<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Davi</title>
    <description>The latest articles on DEV Community by Davi (@roxdavirox).</description>
    <link>https://dev.to/roxdavirox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F325163%2Faf9b2461-c7f3-439c-9da9-0e94d38035bd.jpg</url>
      <title>DEV Community: Davi</title>
      <link>https://dev.to/roxdavirox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roxdavirox"/>
    <language>en</language>
    <item>
      <title>Your S3 Bucket Might Be Public Right Now. We'll Tell You First.</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:59:53 +0000</pubDate>
      <link>https://dev.to/roxdavirox/your-s3-bucket-might-be-public-right-now-well-tell-you-first-2lk1</link>
      <guid>https://dev.to/roxdavirox/your-s3-bucket-might-be-public-right-now-well-tell-you-first-2lk1</guid>
      <description>&lt;h1&gt;
  
  
  Your S3 Bucket Might Be Public Right Now. We'll Tell You First.
&lt;/h1&gt;

&lt;p&gt;GrayhatWarfare's public index holds 470,600 open buckets today. An attacker searches your company name, filters by &lt;code&gt;.env&lt;/code&gt; or &lt;code&gt;backup.sql&lt;/code&gt;, and has a working target list in under a minute — no cost, no advanced technical skill, no trace in your logs.&lt;/p&gt;

&lt;p&gt;Cloud storage misconfiguration is the number one cause of cloud data exposure. Not zero-days, not provider failures — wrong configuration. Public S3 buckets, Firebase databases left in test mode, Azure containers with anonymous read enabled: all discoverable by anyone with an internet connection. The gap between "configured" and "audited" is where breaches happen — and GrayhatWarfare fills that gap within two weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Is Visibility, Not Technology
&lt;/h2&gt;

&lt;p&gt;AWS, Google, and Microsoft ship robust controls to block public access. The issue isn't the provider. It's what happens between the moment a developer spins up a bucket in test mode to speed up development and the moment someone notices that configuration went to production.&lt;/p&gt;

&lt;p&gt;In most organizations, nobody notices. Not because the team is incompetent — but because proactive cloud storage audits aren't part of the standard operational flow. When the alert arrives, if it arrives, it's an external incident report, a researcher notification, or a headline.&lt;/p&gt;

&lt;p&gt;This isn't a hypothetical. In 2019, Chtrbox — an influencer marketing firm — left their Firebase database in test mode in production. Result: data on 49 million Instagram users exposed publicly, including emails, phone numbers, and location data. The disclosure reached TechCrunch before it reached the company's own security team.&lt;/p&gt;

&lt;p&gt;In another incident, a single S3 misconfiguration exposed 273,000 bank transfer PDFs — routing numbers, account numbers, full transaction records. Discovered through passive reconnaissance. No active exploitation. No warning.&lt;/p&gt;

&lt;p&gt;Gartner projects that 99% of cloud security failures through 2026 will be customer-side configuration failures. The question isn't whether you have a misconfiguration. It's whether you find it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  What intel.mago.team Does for Your Team
&lt;/h2&gt;

&lt;p&gt;intel.mago.team scans your cloud infrastructure across the same vectors attackers look for — S3, Firebase, Azure Blob, GCS — and delivers an exposure report before the problem appears in a public index like GrayhatWarfare.&lt;/p&gt;

&lt;p&gt;Every exposure found comes with full context: which resource is exposed, what type of data is accessible, severity level, and the specific remediation step. No manual analysis on your end. You open the report, prioritize by severity, act.&lt;/p&gt;

&lt;p&gt;The vectors covered are exactly those behind the largest cloud data breaches in the last five years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 buckets with public read or write permissions&lt;/li&gt;
&lt;li&gt;Firebase rules in test mode that survived past their 30-day window&lt;/li&gt;
&lt;li&gt;Azure Blob containers with anonymous read enabled&lt;/li&gt;
&lt;li&gt;GCS buckets with IAM bindings open to all users&lt;/li&gt;
&lt;li&gt;Configuration files, API keys, and &lt;code&gt;.env&lt;/code&gt; files in public storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Difference Between Finding and Being Found
&lt;/h2&gt;

&lt;p&gt;Teams that scan proactively find the exposure on their own schedule, with time to act before data is copied. Teams that don't scan receive notification from the outside — from a researcher who already accessed the files, or worse.&lt;/p&gt;

&lt;p&gt;The difference between the two scenarios isn't technical sophistication. It's knowing the problem exists while it's still yours to resolve.&lt;/p&gt;

&lt;p&gt;Run a scan at &lt;a href="https://intel.mago.team" rel="noopener noreferrer"&gt;intel.mago.team&lt;/a&gt; against your infrastructure today. If there's an exposure, you'll know before any attacker does. If there isn't, you have auditable evidence that the check was done — not just the hope that everything is fine.&lt;/p&gt;

&lt;p&gt;Your S3 bucket might be public right now. Find out first.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>API Security Testing: OWASP Top 10 for APIs</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:58:41 +0000</pubDate>
      <link>https://dev.to/roxdavirox/api-security-testing-owasp-top-10-for-apis-19ff</link>
      <guid>https://dev.to/roxdavirox/api-security-testing-owasp-top-10-for-apis-19ff</guid>
      <description>&lt;p&gt;T-Mobile, Peloton, and Optus all had active security programs. All three were breached through API vulnerabilities that existing tests never caught, because the exploited endpoints were not in anyone's inventory.&lt;/p&gt;

&lt;p&gt;Security teams that rely on pre-deploy testing pass audits and still get breached. API attack surface drifts after deploy. No static scanner can test what it doesn't know exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your OpenAPI Spec Is Not Your Attack Surface
&lt;/h2&gt;

&lt;p&gt;Production APIs diverge from documentation within weeks. Shadow endpoints accumulate through feature flags, deprecated versions that were never deactivated, and side-channel leaks in microservices. None of these endpoints are visible to scanners that operate on code.&lt;/p&gt;

&lt;p&gt;Security teams running comprehensive discovery for the first time consistently find more endpoints than documented — the gap between the specification and what runs in production is substantial. Shadow APIs account for a significant share of API traffic at mid-to-large enterprises, with security teams unaware they exist.&lt;/p&gt;

&lt;p&gt;The 2022 Cequence report recorded 5 billion malicious requests out of 16.7 billion total, all targeting unknown and unmanaged APIs. OWASP API9:2023 names this Improper Inventory Management: beta endpoints frequently lack the rate limiting and authentication equivalent to production, and the absence of documentation lets them be exploited without the security team knowing they exist.&lt;/p&gt;

&lt;p&gt;The 2022 Optus breach made the cost concrete. An undocumented, unauthenticated endpoint exposed data on 9.7 million customers. The endpoint appeared in no OpenAPI spec. SAST and DAST inherit the developer's endpoint list and never test what they don't know exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  BOLA Has Led the List for Five Years Because Auth Only Breaks at Runtime
&lt;/h2&gt;

&lt;p&gt;Object-level authorization failures are not detectable through static analysis. They require real user IDs, real objects in the database, and runtime context. Every static scanner misses this category by design.&lt;/p&gt;

&lt;p&gt;The 2021 Peloton breach exposed more than 4 million user records, including accounts configured as private. Authenticated users could access any other user's data by swapping the ID in the request path. Peloton had authentication working. It had no per-object authorization check on each endpoint.&lt;/p&gt;

&lt;p&gt;T-Mobile in 2023 saw 37 million customers affected by an API without adequate authorization checks. The class action settlement reached 350 million dollars. OWASP has ranked BOLA as API1:2023 for five consecutive years, and the category appears in roughly 40 percent of all documented API attacks.&lt;/p&gt;

&lt;p&gt;The technical reason is straightforward: BOLA requires active runtime context. A valid user session, real objects in the database, and a sequence of requests that crosses ownership boundaries between users. No code scanner can simulate that context. The vulnerability is not in the source code -- it lives in business logic executing with production data. That structural gap is why BOLA has led the list since 2019.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Misconfigs Survive Code Review Because They Are Config Bugs, Not Code Bugs
&lt;/h2&gt;

&lt;p&gt;The most critical JWT vulnerabilities exist in the deployed configuration, independent of source code. Updating the library version does not fix a misconfigured token validation endpoint in the API gateway.&lt;/p&gt;

&lt;p&gt;CVE-2024-31033 affects JJWT: incorrectly configured signing keys allow token forgery with weaker authentication than expected. CVE-2026-29000 affects pac4j-jwt in versions before 4.5.9, 5.7.9, and 6.3.3. An attacker with access only to the RSA public key can forge JWTs with arbitrary claims and authenticate as any user, including administrators.&lt;/p&gt;

&lt;p&gt;The alg:none attack works as follows: the attacker removes the token signature and sets the algorithm field to none. The server accepts the token if it does not explicitly reject that value in configuration. The RS256-to-HS256 confusion attack uses the RSA public key as an HMAC secret. An attacker who knows the public key signs tokens that the server accepts as valid.&lt;/p&gt;

&lt;p&gt;SAST sees the JWT library import in the code. It does not see the token validation configuration deployed in the API gateway or server environment variables. The code can be correct while the configuration is wrong. That distinction is what makes this vulnerability class survive complete code reviews. Tools that test active endpoints, like the jwt_scanner at intel.mago.team, detect these misconfigurations at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OWASP API Top 10 Is a Taxonomy, Not a Detection Workflow
&lt;/h2&gt;

&lt;p&gt;Most practitioners use the OWASP Top 10 as a code review checklist. The actual detection workflow requires active endpoint discovery, runtime probing, and drift comparison against inventory. No static tool executes these steps.&lt;/p&gt;

&lt;p&gt;The major API security vendor blogs follow the same pattern: they explain the categories with generic examples and provide no end-to-end detection methodology. SAST identifies code patterns but does not detect authorization gaps, configuration drift, or undocumented endpoints. DAST tests running applications but needs a known endpoint list, so shadow APIs are never tested.&lt;/p&gt;

&lt;p&gt;Authorization failures, business logic abuse, and multi-step flow exploitation depend on runtime context and sequencing that static analysis cannot see. The fundamental gap is this: knowing which vulnerability categories exist is not the same as knowing whether your deployed API is vulnerable to them. The taxonomy describes what can happen. The detection workflow determines what is happening now, with your active endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Detection Workflow Starts with Discovery, Not Scanning
&lt;/h2&gt;

&lt;p&gt;Effective API security testing follows a fixed sequence: passive discovery to find what exists, fingerprinting to understand the stack, targeted probing for each category. Skipping the first step means scanning a fraction of the real surface.&lt;/p&gt;

&lt;p&gt;Step 1: discovery via subdomain enumeration, JavaScript bundle extraction, path traversal on API gateways, and fingerprinting with Shodan and Censys. Step 2: inventory baseline, mapping discovered endpoints against the documented spec and flagging shadow endpoints and deprecated versions still active. Step 3: authentication probing on each endpoint, testing auth bypass, alg:none acceptance in JWT, and missing required authentication headers.&lt;/p&gt;

&lt;p&gt;Step 4: BOLA and BFLA testing. For each endpoint that handles objects, probe with valid authentication but a different user context and verify whether the response is 403 or 200 with another user's data. Step 5: continuous comparison, re-running discovery weekly and generating a diff against the last known inventory to detect drift. Each step depends on the previous one. Without full discovery, scanning tests only the endpoints you already documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Runtime and Development Posture Diverge at Deploy Time
&lt;/h2&gt;

&lt;p&gt;Protecting production APIs requires continuous external testing against active endpoints, from the same perspective an attacker has. Internal testing from the development side does not detect the configuration, routing, and endpoint drift that emerges in production.&lt;/p&gt;

&lt;p&gt;The scenario documented in OWASP API9:2023 is direct: a beta API without rate limiting was used to brute-force password reset tokens. The production API had rate limiting. The beta version did not. The security team tested the production version and passed the audit.&lt;/p&gt;

&lt;p&gt;The scale of the problem is growing faster than review cycles can track. Organizations with more than 100 API endpoints went from 4 percent in 2024 to 38 percent in 2025. 84 percent of security professionals reported API-related incidents in the past 12 months, most involving endpoints unknown to the internal team.&lt;/p&gt;

&lt;p&gt;External API testing, conducted from outside the network perimeter, detects routing misconfigurations, exposed internal endpoints, and authentication gaps that internal tools cannot reach. Each new API version creates shadow endpoints until the documentation is updated. The intel.mago.team approach combines continuous external discovery with jwt_scanner and technology fingerprinting on active endpoints, not on code.&lt;/p&gt;

&lt;p&gt;The scanner testing your pipeline doesn't know what the deploy delivered.&lt;/p&gt;

</description>
      <category>osint</category>
      <category>security</category>
    </item>
    <item>
      <title>Threat Intelligence 101: From Raw Data to Actionable Insights</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:58:01 +0000</pubDate>
      <link>https://dev.to/roxdavirox/threat-intelligence-101-from-raw-data-to-actionable-insights-185d</link>
      <guid>https://dev.to/roxdavirox/threat-intelligence-101-from-raw-data-to-actionable-insights-185d</guid>
      <description>&lt;p&gt;The SOC got the alert at 2 a.m. By the time the analyst correlated the IOC with the logs and confirmed relevance, the attacker had already moved laterally into three internal servers. The intelligence was right. The pipeline was the problem.&lt;/p&gt;

&lt;p&gt;Most organizations already pay for threat intelligence feeds. The gap is not data: it is operationalization. IOCs arrive in dashboards and PDFs that never automatically translate into detection rules, blocklists, or playbooks. The speed advantage that intelligence should deliver gets destroyed by manual correlation that no team can sustain at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Operationalization Gap
&lt;/h2&gt;

&lt;p&gt;Organizations that suffered breaches in 2024 and 2025 were not operating without intelligence. They had feed subscriptions. The pattern documented in security research is consistent: intelligence arrives, operations cannot absorb it within the relevant time window, the moment passes, and the lesson disappears without a record.&lt;/p&gt;

&lt;p&gt;An IOC that fires without an associated playbook is a documented detection gap. CISA demonstrated with the AIS (Automated Indicator Sharing) program that machine-speed sharing is a solved problem: STIX 2.1 for structure, TAXII 2.1 for transport. What AIS does not solve is the last mile: mapping indicators to SIEM rules and EDR actions, a step that most teams still handle manually.&lt;/p&gt;

&lt;p&gt;Automating the conversion of CTI reports into detection rules exists as an active research field, but adoption in SOC teams has not kept pace with the volume of intelligence produced. Organizations continue paying for intelligence that never reaches the detector.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Threat Intelligence Actually Is
&lt;/h2&gt;

&lt;p&gt;Intelligence is not the same as data. STIX 2.1, ratified by OASIS in June 2021, defines structured objects with 18 domain objects and 18 cyber-observable objects to represent context, relationships, and relevance. A CSV list of IPs has none of that.&lt;/p&gt;

&lt;p&gt;The practical distinction splits intelligence into three layers: strategic informs long-term decisions, operational supports campaign planning, and tactical provides IOCs for immediate detection. Most commercial feeds deliver exclusively the tactical layer, which also has the shortest shelf life.&lt;/p&gt;

&lt;p&gt;MITRE ATT&amp;amp;CK v18 (October 2025) catalogs 14 tactics, 216 techniques, and 475 sub-techniques for the Enterprise environment. Adversary techniques change on a quarterly timescale. IOCs change on an hourly timescale. Building detections based on ATT&amp;amp;CK TTPs produces rules that survive attacker infrastructure rotation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commercial Feeds Solve the Wrong Problem
&lt;/h2&gt;

&lt;p&gt;Commercial feeds deliver what is easy to deliver: IP addresses, file hashes, and domains. The problem is that attackers rotate IPs within hours, and half of fresh feed indicators generate false positives from legitimate business traffic, requiring manual triage before any application. With each new batch of indicators, analysts must filter before applying, destroying the automation gain.&lt;/p&gt;

&lt;p&gt;The result is context loss at delivery: the SOC receives values, not intelligence. An IP address without information about which campaign, which actor, and which technique it represents is noise dressed as signal.&lt;/p&gt;

&lt;p&gt;IP blocklists have a shelf life of 24 to 72 hours under normal conditions, and shorter when the attacker notices they are being blocked. Relying exclusively on tactical feeds anchors detection in infrastructure-centric thinking, while the approach that survives is behavior-centric. ATT&amp;amp;CK was built precisely for that paradigm shift.&lt;/p&gt;

&lt;h2&gt;
  
  
  Underused Passive Sources: What You Already Have
&lt;/h2&gt;

&lt;p&gt;Operationalizing threat intelligence does not require depending exclusively on external feeds: the organization's own attack surface already generates primary intelligence that no vendor can see. Certificate Transparency logs are public and free. When an attacker registers a typosquat domain for a phishing campaign, they need an SSL certificate before launching the infrastructure. That certificate gets logged in CT logs and is available for query before the attack starts. IOC feeds only capture the domain after the campaign is active and observed by third parties.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://secybers.com/blog-details/advanced-certificate-transparency-hunting-uncovering-hidden-infrastructure-through-ct-log-analysis" rel="noopener noreferrer"&gt;SecYbers&lt;/a&gt; documents that CT logs combined with DNS and WHOIS data enable full adversary infrastructure mapping before the active phase of the campaign. Subdomain drift, the creation of unmanaged subdomains on the organization's own domains, exposes attack surface that no external feed can see because it is internal. Technology fingerprinting reveals exposed services before attackers discover them through their own scans.&lt;/p&gt;

&lt;p&gt;These sources are continuous intelligence generated by the organization's own attack surface. Tools like &lt;a href="https://intel.mago.team/spells" rel="noopener noreferrer"&gt;intel.mago.team/spells&lt;/a&gt; monitor CT logs and infrastructure detection automatically as intelligence sources; for point-in-time queries, &lt;a href="https://crt.sh" rel="noopener noreferrer"&gt;crt.sh&lt;/a&gt; offers free search and SSLMate's &lt;a href="https://sslmate.com/certspotter/" rel="noopener noreferrer"&gt;Cert Spotter&lt;/a&gt; provides continuous monitoring with a free tier. Most teams outsource intelligence generation to external feeds while already operating high-quality primary sources without processing them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Automation Closes the Gap
&lt;/h2&gt;

&lt;p&gt;The minimum functional pipeline has four stages: ingestion of structured sources, enrichment with context, mapping to ATT&amp;amp;CK TTPs, and automatic delivery to SIEM or EDR. The gap lives between mapping and delivery, which is exactly where manual work intervenes and destroys the speed that automation should provide.&lt;/p&gt;

&lt;p&gt;TAXII 2.1 solves the transport layer: feeds that publish via TAXII allow automated ingestion without manual CSV parsing. STIX 2.1 solves structure: typed objects with explicit relationships let downstream systems process indicators without human intervention. CISA provides AIS access via TAXII to any organization that wants to start with government-sourced intelligence.&lt;/p&gt;

&lt;p&gt;Research published on arXiv in 2026 (From IOCs to Regex, &lt;a href="https://arxiv.org/abs/2604.12228" rel="noopener noreferrer"&gt;arXiv:2604.12228&lt;/a&gt;) demonstrates that LLMs can convert CTI reports into regex expressions for detection with a significant degree of automation. The problem is not technological: teams that do not define what they need to detect before buying feeds have no way to evaluate what to automate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Minimum Pipeline
&lt;/h2&gt;

&lt;p&gt;The most common mistake is starting with the feed and working back to requirements. The functional pipeline reverses that order.&lt;/p&gt;

&lt;p&gt;Step one is defining intelligence requirements based on realistic threats for the organization's sector, size, and technology stack. Without that, any feed generates noise. Step two is an attack surface inventory, because you cannot prioritize intelligence without knowing what to protect. Step three is structured ingestion: feeds in STIX format via TAXII enable automation; raw CSVs do not. Step four is TTP mapping, building detections based on adversary behavior rather than point-in-time indicators that expire. Step five is the feedback loop: measure how many alerts generated by last quarter's intelligence produced an actual security decision change.&lt;/p&gt;

&lt;p&gt;The 2025 arXiv research on MITRE ATT&amp;amp;CK applications (&lt;a href="https://arxiv.org/abs/2502.10825" rel="noopener noreferrer"&gt;arXiv:2502.10825&lt;/a&gt;) identifies automated TTP extraction from reports as a critical gap. Most organizations perform that mapping manually, making the most time-consuming pipeline stage also the most error-prone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Operationalize First
&lt;/h2&gt;

&lt;p&gt;Operationalization priority follows immediate impact with minimal configuration friction.&lt;/p&gt;

&lt;p&gt;Credential exposure monitoring detects when organizational accounts appear in public dumps before attackers use them. Certificate issuance monitoring via CT logs detects phishing infrastructure before campaign launch. Subdomain drift detection exposes attack surface that was never inventoried.&lt;/p&gt;

&lt;p&gt;All three share one property: they produce actionable alerts, not reports. The output is a suspect domain to block, a credential to rotate, a subdomain to disable. Define your requirements before buying the next feed. Set up CT log monitoring for your domains. Map your detections to ATT&amp;amp;CK TTPs, not IP lists. Intelligence that never reaches the detector is indistinguishable from having no intelligence.&lt;/p&gt;

</description>
      <category>osint</category>
      <category>security</category>
    </item>
    <item>
      <title>Web Application Reconnaissance: Mapping the Attack Surface</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:57:25 +0000</pubDate>
      <link>https://dev.to/roxdavirox/web-application-reconnaissance-mapping-the-attack-surface-573a</link>
      <guid>https://dev.to/roxdavirox/web-application-reconnaissance-mapping-the-attack-surface-573a</guid>
      <description>&lt;p&gt;Subfinder returns 1,247 subdomains in 19 minutes. Amass adds 340 more from passive sources. The pentest report covers 12 of them.&lt;/p&gt;

&lt;p&gt;That gap is where most critical bugs survive. Not because the team missed the assets, but because there was no layer to decide which ones to test first.&lt;/p&gt;

&lt;p&gt;Recon produces lists. Practitioners who find critical vulnerabilities first treat those lists as input to a risk scoring layer, not as a final deliverable. The difference between an attack surface report and an actual attack map lives in that intermediate step: internet exposure, known CVE surface, and business criticality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recon Data Is Not Intelligence: The Volume Problem
&lt;/h2&gt;

&lt;p&gt;Modern subdomain enumeration tools deliver impressive scale in minutes. Subfinder queries 103 passive sources simultaneously; Amass adds active brute-force enumeration over wordlists of one million entries. The problem that volume creates is a filtering problem.&lt;/p&gt;

&lt;p&gt;The OWASP Attack Surface Management Top 10 places "unknown and unmanaged external assets" at the top of the risk list. Organizations frequently don't know the full extent of their own exposed surface. An annual pentest scoped to the main domain leaves the rest untouched.&lt;/p&gt;

&lt;p&gt;The distinction that matters is between attack surface and exploitable surface. A list of 1,247 subdomains is an attack surface. Exploitable surface is the subset with active DNS, a stack with a public CVE and CVSS above 7.0, and a path that touches authentication or sensitive data. The gap between those two numbers is where tools stop and judgment begins.&lt;/p&gt;

&lt;p&gt;Technical reports without business context are not actionable. A subdomain running Apache 2.4.49 with public exposure is priority zero: CVE-2021-41773 carries CVSS 9.8 and widely documented public exploits. A subdomain running Apache 2.4.53 on staging with no active DNS is a candidate for deprioritization. Risk scoring makes that distinction; the raw list does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passive Discovery: Mapping Without Touching
&lt;/h2&gt;

&lt;p&gt;Certificate Transparency logs are the most underrated resource for passive discovery. Every TLS certificate issued by a trusted CA appears in a public, immutable log within minutes of issuance. Before a new subdomain even has full DNS propagation, it is already visible in the CT history.&lt;/p&gt;

&lt;p&gt;crt.sh exposes that history through a direct SQL API. A query for &lt;code&gt;%.empresa.com&lt;/code&gt; returns every subdomain that has ever received a certificate, including admin panels provisioned once and never formally decommissioned. A certificate issued in 2019 for &lt;code&gt;dev-api.empresa.com&lt;/code&gt; stays in the log even if the subdomain was later disabled.&lt;/p&gt;

&lt;p&gt;Google and Bing surface accidentally indexed content through search operators. &lt;code&gt;site:empresa.com filetype:env&lt;/code&gt; finds published &lt;code&gt;.env&lt;/code&gt; files. &lt;code&gt;inurl:empresa.com admin login&lt;/code&gt; finds panels exposed to crawlers. The OWASP WSTG operator collection covers 40 distinct search patterns for sensitive data indexed without intent.&lt;/p&gt;

&lt;p&gt;Passive DNS databases like SecurityTrails and VirusTotal store resolution history for years. SecurityTrails &lt;code&gt;/v1/domain/{domain}/subdomains&lt;/code&gt; returns up to 10,000 historical subdomains via API; VirusTotal &lt;code&gt;/domains/{domain}/subdomains&lt;/code&gt; supplements that with resolution data from threat intelligence feeds. A corporate acquisition that brought in domains from a purchased company shows up in that history before any public announcement. WHOIS and RDAP expose ownership records that link seemingly independent domains to the same registrant.&lt;/p&gt;

&lt;p&gt;Public repositories on GitHub and GitLab routinely expose internal hostnames, API tokens, and environment keys in commit history — the dork &lt;code&gt;site:github.com 'company.com' 'password'&lt;/code&gt; is standard practice in passive reconnaissance.&lt;/p&gt;

&lt;p&gt;The operational advantage of all these methods is zero interaction with the target infrastructure. No packets sent means no IDS alerts, no access logs, no anomalous monitoring window. The passive phase is where information asymmetry exists before any contact is made.&lt;/p&gt;

&lt;p&gt;All of that data arrives as raw lists — the resulting volume is precisely what makes the scoring layer non-optional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack Fingerprinting: Disclosed Versions as a CVE Shortlist
&lt;/h2&gt;

&lt;p&gt;Every version string a server leaks is a direct lookup against CVE databases. Fingerprinting does not find vulnerabilities; it narrows the search space to confirmed candidates with documented exploits.&lt;/p&gt;

&lt;p&gt;HTTP headers are the first signal layer. &lt;code&gt;Server: Apache/2.4.49&lt;/code&gt; identifies the exact version. &lt;code&gt;X-Powered-By: PHP/8.0.1&lt;/code&gt; does the same for the runtime. &lt;code&gt;X-AspNet-Version: 4.0.30319&lt;/code&gt; and &lt;code&gt;X-AspNetMvc-Version: 5.2&lt;/code&gt; reveal the full stack in two response lines. These headers are enabled by default in standard configurations and rarely disabled in production.&lt;/p&gt;

&lt;p&gt;Session cookie names identify frameworks without any response body analysis. &lt;code&gt;PHPSESSID&lt;/code&gt; indicates PHP; &lt;code&gt;JSESSIONID&lt;/code&gt; indicates Java EE or Spring; &lt;code&gt;ASP.NET_SessionId&lt;/code&gt; indicates .NET. Combined with the &lt;code&gt;Set-Cookie&lt;/code&gt; header value, these names build a partial stack map without any vulnerability scanner.&lt;/p&gt;

&lt;p&gt;Error pages are immediate visual signatures. Apache Tomcat's default 404 has specific HTML with the Jakarta logo. Spring Boot's 500 exposes "Whitelabel Error Page" by default through version 2.x. IIS 7.5 has an error page with a proprietary HTML structure. Any of these patterns connects the asset to a specific CVE history.&lt;/p&gt;

&lt;p&gt;Default framework files frequently remain accessible. &lt;code&gt;changelog.txt&lt;/code&gt; in WordPress exposes the exact version without authentication. &lt;code&gt;composer.json&lt;/code&gt; in PHP applications lists dependencies with versions. &lt;code&gt;package.json&lt;/code&gt; in Node.js applications does the same. These files are found through direct path guessing, no scanner required.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://intel.mago.team" rel="noopener noreferrer"&gt;intel.mago.team&lt;/a&gt; tech_detector automates the collection of these signals from a URL, without a browser extension, making the process scalable for mass enumeration pipelines. The output maps each detected signal to a stack profile that feeds the NVD query by version.&lt;/p&gt;

&lt;p&gt;The operational chain is straightforward: disclosed version, NVD lookup by exact CPE, filter by CVSS greater than or equal to 7.0, filter by available public exploit. The asset that passes that filter is a priority test candidate before any manual analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subdomain Enumeration: The Perimeter Extends Beyond the Main Domain
&lt;/h2&gt;

&lt;p&gt;Staging and development subdomains represent the most common class of forgotten assets. OWASP ASM Top 10 #7 catalogs "exposed debug and test environments" as a distinct risk because these instances exist on subdomains that never go through security review. &lt;code&gt;dev-api.empresa.com&lt;/code&gt;, &lt;code&gt;staging-admin.empresa.com&lt;/code&gt;, &lt;code&gt;test.empresa.com&lt;/code&gt;: each tends to have weaker authentication, real data for environment validation, and no WAF in front.&lt;/p&gt;

&lt;p&gt;CT logs cover historical subdomains that passive DNS databases may not have. The combination of crt.sh, SecurityTrails, and Subfinder maximizes coverage before any active contact with the target. OWASP Amass adds integration with threat intelligence APIs and pastebins to capture accidental references to internal subdomains.&lt;/p&gt;

&lt;p&gt;Subdomain takeover is the direct risk from dangling CNAME records. A subdomain &lt;code&gt;cdn.empresa.com&lt;/code&gt; with a CNAME pointing to a decommissioned cloud service can be claimed by an attacker who provisions the same URL on the target platform. The result is a legitimate company subdomain serving attacker-controlled content, with valid cookie scope on the parent domain. OWASP ASM Top 10 #8 documents this scenario as insecure DNS configuration.&lt;/p&gt;

&lt;p&gt;Active brute-force enumeration over wordlists captures subdomains that never received a TLS certificate and do not appear in passive databases. Wordlists like those from SecLists cover common patterns: &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;admin&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;staging&lt;/code&gt;, &lt;code&gt;beta&lt;/code&gt;, &lt;code&gt;internal&lt;/code&gt;. The critical distinction is authorization: active enumeration sends DNS packets to the target's authoritative server and is only legal with an explicit pentest scope.&lt;/p&gt;

&lt;p&gt;Each subdomain added to the list through this process strengthens the case for scoring before testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Synthesis Layer: Scoring Findings Before Testing Them
&lt;/h2&gt;

&lt;p&gt;Raw recon without scoring is output, not intelligence. The risk matrix operates on three factors: internet exposure, known CVE surface, and business criticality. Applying that matrix converts a subdomain list into an attack map with a defined test sequence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factor 1: Internet exposure.&lt;/strong&gt; An asset counts as exposed when three conditions hold: it appears in CT logs or passive DNS, it resolves DNS at the time of assessment, and it has port 443 or 80 open. A historical subdomain in crt.sh with no active DNS resolution has low exposure; monitoring is worthwhile, but immediate test priority is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factor 2: CVE surface.&lt;/strong&gt; Stack fingerprinting produces a version tuple. That tuple goes to the NVD as a CPE query. The relevant filter is CVSS greater than or equal to 7.0 with a documented public exploit. EPSS (Exploit Prediction Scoring System) complements CVSS by estimating the actual probability of active exploitation within 30 days. A CVE with CVSS 9.8 and EPSS 0.02 is less urgent than one with CVSS 7.5 and EPSS 0.87.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factor 3: Business criticality.&lt;/strong&gt; Path analysis and form inspection identify what the asset processes. A login form indicates authentication. Credit card fields indicate a payment flow. &lt;code&gt;user_id&lt;/code&gt; or &lt;code&gt;account_id&lt;/code&gt; parameters in responses indicate personal data. An admin panel with HTTP Basic Auth on public exposure is maximum priority regardless of how uninteresting it appears.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete example.&lt;/strong&gt; Assess &lt;code&gt;status.empresa.com&lt;/code&gt; discovered in CT logs. The subdomain resolves DNS; port 443 responds. The &lt;code&gt;Server: nginx/1.14.0&lt;/code&gt; header appears in the response. The NVD lists CVE-2019-9511 (HTTP/2 DoS, CVSS 7.5) and CVE-2019-9516 (CVSS 7.5) for that version. The &lt;code&gt;/admin&lt;/code&gt; path returns HTTP 200 without authentication, with a visible login form. EPSS for CVE-2019-9511 is 0.94 in 30 days. Composite score: high exposure, CVE with elevated EPSS, exposed admin path. Result: immediate testing, ahead of any host in the main scope.&lt;/p&gt;

&lt;p&gt;What gets deprioritized: historical subdomains in CT with no active DNS resolution; updated stacks with no public CVE with relevant EPSS; services with no confirmed internet exposure. The OWASP Relative Attack Surface Quotient weights attack points by access level, damage potential, and reproducibility — the result is a numerical metric comparable across assets (&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Attack_Surface_Analysis_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP ASM&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Operationalizing: The Attack Surface Changes Every Day
&lt;/h2&gt;

&lt;p&gt;A recon audit done today is a snapshot of yesterday's risk. TLS certificates are issued continuously. A new subdomain provisioned at 2:00 PM has its certificate in the CT log by 2:05 PM, before any human security review. Annual or monthly audit cadences cannot keep pace with that speed.&lt;/p&gt;

&lt;p&gt;CT log streaming is the operational solution. Tools like certstream subscribe to logs from multiple CAs and deliver real-time events for monitored domains. A new certificate for &lt;code&gt;*.empresa.com&lt;/code&gt; triggers an event; the pipeline runs fingerprinting, DNS check, and port scan automatically; the alert arrives with context before the subdomain is in full production.&lt;/p&gt;

&lt;p&gt;Delta checking formalizes the process: for each newly discovered asset, the pipeline compares against the existing inventory, runs the full fingerprinting and CVE lookup chain, and ranks by risk score. Alerts with a configurable threshold ensure the team receives actionable context, not another raw log to interpret manually.&lt;/p&gt;

&lt;p&gt;intel.mago.team provides continuous stack and subdomain monitoring, closing the gap between audit cycles. New assets enter the pipeline with automated fingerprinting and scoring, without requiring manual re-execution of every tool each week.&lt;/p&gt;

&lt;p&gt;The attack surface is not a list to generate and file away. It is a living map that requires a scoring layer between raw discovery and actual testing. Built once, that layer makes any tool output immediately actionable.&lt;/p&gt;

</description>
      <category>osint</category>
      <category>security</category>
    </item>
    <item>
      <title>JWT Security: How Misconfigured Tokens Expose Your APIs</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:56:49 +0000</pubDate>
      <link>https://dev.to/roxdavirox/jwt-security-how-misconfigured-tokens-expose-your-apis-he5</link>
      <guid>https://dev.to/roxdavirox/jwt-security-how-misconfigured-tokens-expose-your-apis-he5</guid>
      <description>&lt;h1&gt;
  
  
  JWT Security: How Misconfigured Tokens Expose Your APIs
&lt;/h1&gt;

&lt;p&gt;A JWT with a forged signature. No password needed, no exploit chain, just a change to the base64-encoded header and a stolen session. Auth0 shipped this bug to production. Attackers exploited it at scale. The token looked valid. The API accepted it.&lt;/p&gt;

&lt;p&gt;The problem is not the JWT format itself. The only real protection the token has, signature verification, can be disabled by misconfiguration. And popular libraries have made it trivially easy to get wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWTs Are Trusted by Design. That Is the Problem
&lt;/h2&gt;

&lt;p&gt;A JWT has three parts: header, payload, and signature. The signature is the only security control. Without it, anyone who decodes the token sees the claims in plaintext and can modify them freely.&lt;/p&gt;

&lt;p&gt;The design is stateless by nature. The server holds no session state and cannot revoke individual tokens without additional infrastructure. Who signed the token and when are the only verifiable facts.&lt;/p&gt;

&lt;p&gt;Decoding a JWT is trivial. Verifying the signature requires an explicit library call. The distinction between those two operations is where most bugs live.&lt;/p&gt;

&lt;p&gt;Historically, &lt;code&gt;jsonwebtoken&lt;/code&gt; and &lt;code&gt;jose&lt;/code&gt; accepted &lt;code&gt;alg:none&lt;/code&gt; by default. An unsigned token was valid. The library decoded the payload and returned it as authenticated without verifying anything. That was not an obscure bug. It was the default behavior of libraries used in millions of applications.&lt;/p&gt;

&lt;p&gt;The second structural problem: many languages separate &lt;code&gt;decode&lt;/code&gt; from &lt;code&gt;verify&lt;/code&gt; into distinct functions. Python has &lt;code&gt;jwt.decode()&lt;/code&gt; and &lt;code&gt;jwt.decode(options={"verify_signature": False})&lt;/code&gt;. PHP has &lt;code&gt;Firebase\JWT\JWT::decode()&lt;/code&gt;, which accepts an array of allowed algorithms. When documentation shows incomplete examples or a developer is rushing, the verification step disappears silently. The application works. Tests pass. The vulnerability persists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Misconfigurations That Break Authentication Completely
&lt;/h2&gt;

&lt;h3&gt;
  
  
  alg:none
&lt;/h3&gt;

&lt;p&gt;Change the &lt;code&gt;alg&lt;/code&gt; field in the header to &lt;code&gt;none&lt;/code&gt;, remove the signature, and send the token. In vulnerable implementations, the server accepts it. No key required. No access to the private key. Just base64 editing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Decode the original header&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="c"&gt;# {"alg":"RS256","typ":"JWT"}&lt;/span&gt;

&lt;span class="c"&gt;# Build a new header with alg:none&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'{"alg":"none","typ":"JWT"}'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'='&lt;/span&gt;
&lt;span class="c"&gt;# eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0&lt;/span&gt;

&lt;span class="c"&gt;# Assemble the token without a signature (trailing empty dot)&lt;/span&gt;
&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0IiwicGF5bG9hZCI6ImFkbWluIn0."&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; https://api.alvo.com/admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auth0 had this problem in production. The variant &lt;code&gt;alg:nonE&lt;/code&gt; (uppercase E) bypassed the simple string check that would normally block &lt;code&gt;none&lt;/code&gt;. A case-sensitive comparison broke the entire protection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithm Confusion: RS256 to HS256
&lt;/h3&gt;

&lt;p&gt;RS256 uses a private key to sign and a public key to verify. The public key is, by definition, public and frequently exposed at the application's JWKS endpoint.&lt;/p&gt;

&lt;p&gt;HS256 uses a symmetric key. The same secret signs and verifies.&lt;/p&gt;

&lt;p&gt;When an API configured for RS256 accepts HS256 tokens, the attacker uses the server's public key as the HMAC secret. The signature is valid because the server uses that same public key to verify. CVE-2024-54150 documents exactly this pattern in Comcast's xmidt platform, published in 2024. Not in 2010. In 2024. The vector has existed for over a decade and keeps getting introduced into production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weak Secrets in HS256
&lt;/h3&gt;

&lt;p&gt;Hashcat in mode 16500 attacks HS256 tokens directly. A captured token with a 12-character dictionary-based secret falls in minutes on modern hardware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hashcat &lt;span class="nt"&gt;-a&lt;/span&gt; 0 &lt;span class="nt"&gt;-m&lt;/span&gt; 16500 captured.jwt /usr/share/wordlists/rockyou.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Red Sentry documented that 16-character secrets are crackable in under 24 hours with current hardware. That includes secrets that look strong but follow predictable patterns like &lt;code&gt;MyAppSecret2024&lt;/code&gt; or &lt;code&gt;jwt-secret-prod&lt;/code&gt;. Secrets derived from product names, dates, or any human-readable string fall into that category.&lt;/p&gt;

&lt;h3&gt;
  
  
  Missing Claims
&lt;/h3&gt;

&lt;p&gt;A missing &lt;code&gt;exp&lt;/code&gt; claim means the token never expires. Compromised credentials cannot be rotated. An account compromised six months ago still holds a valid token today.&lt;/p&gt;

&lt;p&gt;A missing &lt;code&gt;aud&lt;/code&gt; claim means a token issued for service A is accepted by service B. Lateral movement with no additional exploit. Just token reuse across microservices in the same organization.&lt;/p&gt;

&lt;p&gt;Each of these four vectors alone enables complete authentication bypass. Production APIs frequently present more than one at the same time. The team that got &lt;code&gt;alg:none&lt;/code&gt; wrong probably also skipped &lt;code&gt;aud&lt;/code&gt; validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Theoretical: CVEs With Real Production Impact
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CVE-2022-21449&lt;/strong&gt; affected Java 15, 16, 17, and 18 before the April 2022 patch. The bug was in the JVM's ECDSA implementation. A signature with &lt;code&gt;r=0, s=0&lt;/code&gt; passed mathematical validation. Any JWT signed with ES256, ES384, or ES512 on a vulnerable JVM was forgeable with those two values. CVSS 7.5, remotely exploitable, no authentication required. &lt;code&gt;com.nimbusds.jose&lt;/code&gt; fixed it in version 9.22. &lt;code&gt;com.auth0:java-jwt&lt;/code&gt; fixed it in 3.19.2. Applications running earlier versions stayed vulnerable for months after the public patch because security dependency updates are not automatic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2018-6873&lt;/strong&gt; in Auth0. The &lt;code&gt;aud&lt;/code&gt; parameter was not validated. An attacker with any Auth0 account used their own token to access any account on the platform. All they needed was the target's email address. (CVE-2018-6874, from the same API, is a distinct CSRF vulnerability — not to be confused with the audience bypass.) Complete admin takeover without knowing any victim credentials. It affected every application protected by Auth0 during that period. The impact was not limited to a bug in one specific application. It was systemic across the platform's entire customer base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2024-54150&lt;/strong&gt; in Comcast's &lt;code&gt;xmidt-org/cjwt&lt;/code&gt;. Classic algorithm confusion, the same RS256/HS256 pattern. Published in 2024, confirming that this vector keeps getting introduced into production. Comcast's code likely went through review. It likely has tests. The vulnerability existed anyway because functional tests do not detect algorithm confusion.&lt;/p&gt;

&lt;p&gt;Red Sentry counted multiple new critical JWT-related CVEs in 2025 alone (Red Sentry, 2025), affecting cloud platforms and enterprise systems. This vulnerability class is not going away. It keeps reproducing because every new JWT implementation reinvents the same mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Detect Before Attackers Do
&lt;/h2&gt;

&lt;p&gt;Manual testing requires base64 and curl. Nothing else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test alg:none:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Capture a valid JWT from any authenticated response&lt;/li&gt;
&lt;li&gt;Decode the header: &lt;code&gt;echo "&amp;lt;header_part&amp;gt;" | base64 -d&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Build a new header with &lt;code&gt;"alg":"none"&lt;/code&gt; and encode it back&lt;/li&gt;
&lt;li&gt;Assemble the token with the original payload but without a signature (end with an empty dot)&lt;/li&gt;
&lt;li&gt;Send it to the protected endpoint. If it accepts, the endpoint is vulnerable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Test algorithm confusion:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Obtain the server's public key (JWKS endpoint, &lt;code&gt;.well-known/jwks.json&lt;/code&gt;, or documentation)&lt;/li&gt;
&lt;li&gt;Re-sign the token with HS256 using the public key as the HMAC secret&lt;/li&gt;
&lt;li&gt;Send it to the endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For automation, &lt;code&gt;jwt_tool&lt;/code&gt; covers these vectors and more in batch mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 jwt_tool.py &amp;lt;token&amp;gt; &lt;span class="nt"&gt;-X&lt;/span&gt; a               &lt;span class="c"&gt;# algorithm confusion&lt;/span&gt;
python3 jwt_tool.py &amp;lt;token&amp;gt; &lt;span class="nt"&gt;-X&lt;/span&gt; n               &lt;span class="c"&gt;# none attack&lt;/span&gt;
python3 jwt_tool.py &amp;lt;token&amp;gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; wordlist.txt  &lt;span class="c"&gt;# crack HS256 secret&lt;/span&gt;
python3 jwt_tool.py &amp;lt;token&amp;gt; &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="nt"&gt;-hc&lt;/span&gt; alg &lt;span class="nt"&gt;-hv&lt;/span&gt; none &lt;span class="c"&gt;# manual header injection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Burp JWT Scanner detects CVE-2022-21449 passively. It intercepts tokens in responses and tests attack variants in active mode. In an API assessment, running the active scanner against every endpoint that returns a JWT takes minutes and covers known classes without manual configuration.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;kid&lt;/code&gt; (Key ID) field deserves separate attention. It is frequently used as a parameter in database queries without sanitization. SQLi via the &lt;code&gt;kid&lt;/code&gt; header is a documented vector with public PoCs. Variants include JKU and X5U header injection for key substitution, where the attacker points the token at an external JWKS under their control. TrustedSec has a complete methodology covering these advanced attacks.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;jwt_scanner&lt;/code&gt; (intel.mago.team/spells) automates detection of those three vectors in a single scan: it crawls exposed endpoints, detects JWTs in the Authorization header and Set-Cookie, applies algorithm confusion and &lt;code&gt;alg:none&lt;/code&gt; tests, and correlates with the CVE database to identify affected libraries by version.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Is Not the Problem. Implementation Is.
&lt;/h2&gt;

&lt;p&gt;JWT is not inherently insecure. The strongest argument against this analysis is that the same blind-trust vector exists in session tokens: a compromised Redis instance exposes sessions the same way a weak secret exposes tokens. Misconfiguration, not the format, is the attack surface in both cases. The difference is that JWT externalizes state. Any service that accepts the token without verifying the algorithm becomes a failure point independent of the issuer. Centralized sessions fail at one point. Poorly verified tokens fail at every service that consumes them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remediation: The Checklist That Closes the Surface
&lt;/h2&gt;

&lt;p&gt;Four controls. All mandatory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Algorithm pinning on the server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Never read the &lt;code&gt;alg&lt;/code&gt; field from the token to decide which algorithm to use for verification. The server hardcodes the algorithm. The token has no say in that decision.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WRONG: client dictates the algorithm&lt;/span&gt;
&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// CORRECT: server decides&lt;/span&gt;
&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;algorithms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RS256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# PyJWT
&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RS256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c1"&gt;# Never:
# jwt.decode(token, public_key, algorithms=jwt.get_unverified_header(token)["alg"])
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Real entropy for HS256 secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Minimum 256 bits generated cryptographically. No passwords, phrases, or human-readable strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store it in a secrets manager (AWS Secrets Manager, HashiCorp Vault, or equivalent). Rotate every 90 days. Never commit it to a repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Explicit validation of all claims&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;algorithms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RS256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://auth.sua-api.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.sua-api.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clockTolerance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reject tokens without &lt;code&gt;exp&lt;/code&gt;. Reject tokens with &lt;code&gt;exp&lt;/code&gt; in the past. Reject tokens with an &lt;code&gt;aud&lt;/code&gt; that does not match your service. Reject tokens with an unknown &lt;code&gt;iss&lt;/code&gt;. The library does not do this automatically. You configure it explicitly or you skip it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Short lifetime and revocation for critical cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Access token: maximum 15 minutes. Refresh token: maximum 24 hours. Both require a mandatory &lt;code&gt;exp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For security events (logout, password change, privilege de-escalation), maintain a &lt;code&gt;jti&lt;/code&gt; (JWT ID) blocklist with TTL equal to the token lifetime. Stateless is convenient, not dogma. Redis with TTL handles selective revocation without complex architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asymmetric over symmetric in multi-service architectures&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If more than one service consumes your tokens, use RS256 or ES256. The private key stays only in the issuer service. Consumer services verify with the public key. RS256/HS256 algorithm confusion is not possible in this architecture when each service hardcodes the expected algorithm.&lt;/p&gt;




&lt;p&gt;JWT security is not a library decision. It is operational discipline. The attack surface closes when algorithm pinning, secret hygiene, and claims validation are verified continuously. The same vulnerabilities reappear in 2024 because teams do not scan what they have implemented. Scanning is the missing step between implementing and trusting.&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>apisecurity</category>
      <category>authentication</category>
      <category>securitytech</category>
    </item>
    <item>
      <title>GitHub OSINT: What Developers Expose Without Realizing It</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:56:13 +0000</pubDate>
      <link>https://dev.to/roxdavirox/github-osint-what-developers-expose-without-realizing-it-39pc</link>
      <guid>https://dev.to/roxdavirox/github-osint-what-developers-expose-without-realizing-it-39pc</guid>
      <description>&lt;h1&gt;
  
  
  GitHub OSINT: What Developers Expose Without Realizing It
&lt;/h1&gt;

&lt;p&gt;In September 2022, Toyota discovered that an access key to the database of 296,019 customers had been public on GitHub since December 2017. Five years. Anyone could have used it at any point during its public existence.&lt;/p&gt;

&lt;p&gt;Attackers collect exposed credentials on GitHub in under 5 minutes. The median remediation time for teams is 94 days. The 89-day gap between those two numbers is the window where any attacker already has what they need. Any security policy that ignores this gap is theater.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5-Minute Window That Invalidates Your Security Policy
&lt;/h2&gt;

&lt;p&gt;Reactive controls are ineffective by design. The gap between a credential exposure and automated collection by attackers is under 5 minutes; the median remediation time for teams is 94 days.&lt;/p&gt;

&lt;p&gt;Unit 42 (Palo Alto Networks) documented automated collection of IAM credentials in under 5 minutes after exposure on GitHub. The Verizon DBIR 2025 reported that the median time to remediate a leaked secret is 94 days. The real exposure window before any internal action is 89 days.&lt;/p&gt;

&lt;p&gt;GitHub found 39 million leaked secrets in 2024. GitGuardian reported 28.65 million new leaks in 2025, up 34% from the previous year. These numbers describe a system where the rate of production of new attack vectors consistently outpaces detection and response capacity.&lt;/p&gt;

&lt;p&gt;A security policy that doesn't address the gap between exposure and detection isn't a security policy. It's compliance documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You're Exposing Right Now (and Probably Don't Know)
&lt;/h2&gt;

&lt;p&gt;The exposure isn't limited to carelessly committed &lt;code&gt;.env&lt;/code&gt; files. The real surface includes complete database connection strings (DATABASE_URL, MONGO_URI), API keys for critical services (AWS, GCP, OpenAI, Stripe, Twilio) committed in configuration files, SSH private keys and TLS certificates in infrastructure repositories, and JWT secrets hardcoded to make local development easier.&lt;/p&gt;

&lt;p&gt;The 2025 data records one rapidly growing vector: AI service credentials increased 81% from the prior year. GitGuardian detected 113,000 DeepSeek API keys exposed in a single year. Each new AI service a team adopts adds a potential credential vector with no monitoring history configured.&lt;/p&gt;

&lt;p&gt;The most underrated vector is git history. A secret deleted in the current commit exists in every prior revision of the repository. The GitHub API exposes this history for public repositories without authentication.&lt;/p&gt;

&lt;p&gt;Reverting a commit doesn't remove the credential from history. The exposure window starts at the moment of the first commit, not at the moment of the attempted fix. Attackers monitoring the event stream collect the credential at the time of the original push; the subsequent revert is irrelevant to them.&lt;/p&gt;

&lt;p&gt;Internal URLs and staging endpoints in configuration files complete the surface. They reveal the internal infrastructure architecture to anyone indexing the repository, including internal services that were never designed to be publicly accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Attackers Find Your Keys in Minutes Using the GitHub API
&lt;/h2&gt;

&lt;p&gt;The GitHub Search API turns the platform into a credential surveillance system accessible to anyone. Queries like &lt;code&gt;filename:.env DB_PASSWORD&lt;/code&gt;, &lt;code&gt;extension:sql mysql dump&lt;/code&gt;, and &lt;code&gt;api_key language:python&lt;/code&gt; return results in seconds, without authentication.&lt;/p&gt;

&lt;p&gt;The GitHub Events API (&lt;code&gt;api.github.com/events&lt;/code&gt;) broadcasts a public stream of every commit made on the platform. Automated tools consume this stream and scan each diff for known credential patterns. The time between a push and detection by an external monitoring system is less than the average code review.&lt;/p&gt;

&lt;p&gt;In October 2025, the OffSeq Threat Radar documented an active mass reconnaissance campaign. Ghost accounts abuse the GitHub API to map entire organizations using user agents that mimic legitimate tools. The requests return HTTP 200 without triggering alerts in conventional monitoring systems.&lt;/p&gt;

&lt;p&gt;Tools like gitrob automate complete surface mapping of an organization: repositories, members, configuration files, and commit history. The combination of GitHub Search with event stream monitoring and history scanning covers the entire public surface of an organization without any credentials on the attacker's side. Exposed credentials are consumed within a window shorter than a status meeting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Incidents That Cost More Than Any Monitoring Tool
&lt;/h2&gt;

&lt;p&gt;Toyota, Uber, and Twitch demonstrate that exposure via public repositories isn't an anomaly: it's the default mode of operation for teams without continuous monitoring. In none of these cases was detection internal.&lt;/p&gt;

&lt;p&gt;Toyota is the most documented case. In December 2017, a subcontractor committed a symmetric key to a customer database in a public repository. The key remained exposed for five years. In September 2022, GitGuardian detected the exposure and notified the company; Toyota had not identified the issue internally.&lt;/p&gt;

&lt;p&gt;The Uber breach in 2022 followed the same pattern. Credentials found in a public repository were part of the attack chain that exposed data from 57 million riders and drivers. The settlement reached USD 148 million. The original commit wasn't malicious: it was a developer who considered the repository secure.&lt;/p&gt;

&lt;p&gt;Twitch and Samsung suffered similar exposures of source code and internal credentials via public repositories. The pattern is consistent: unintentional commit, detection always external. The root cause isn't isolated human error. It's the absence of continuous monitoring that would have made the error immediately visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detection Tools Exist, But Arrive Too Late When Used Only in CI/CD
&lt;/h2&gt;

&lt;p&gt;Gitleaks and TruffleHog are effective, but when run only in the CI/CD pipeline, they detect exposures that are already indexed, collected, and potentially exploited.&lt;/p&gt;

&lt;p&gt;Gitleaks uses regex patterns with TOML configuration, operates without a network connection, and runs as a pre-commit hook in milliseconds. It blocks the commit before the secret reaches the repository. TruffleHog adds entropy analysis and makes real API calls to verify whether the detected credential is still active.&lt;/p&gt;

&lt;p&gt;The configuration that provides layered coverage combines Gitleaks at pre-commit (prevention) with TruffleHog in CI/CD (detection of secrets that passed the first layer). AWS Labs' git-secrets configures local hooks to block specific AWS service patterns before the commit. The three tools combined have over 51,000 stars on GitHub and cover the most common credential patterns in production.&lt;/p&gt;

&lt;p&gt;The critical gap in all three: none monitors what's already public in forks, gists, or third-party code that copied the repository. GitHub Secret Scanning (Advanced Security), even when enabled for the organization, covers only the repository where it's configured. When a developer creates a public fork of a repository that contains credentials in its history, those credentials fall outside the scope of any CI/CD scanner configured on the original repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous Monitoring Is the Only Response That Closes the 89-Day Gap
&lt;/h2&gt;

&lt;p&gt;The difference between proactive and reactive detection determines whether a leaked secret becomes a contained incident or a breach requiring regulatory notification. Continuous monitoring means active scanning of GitHub search, event streams, and paste sites in real time, not a weekly scan of the main repository.&lt;/p&gt;

&lt;p&gt;The surface to monitor includes the organization name, corporate domains, proprietary API key patterns, and corporate email addresses. Any of these identifiers can appear in third-party repositories, gists, Pastebin, or leak forums. An operationally useful alert arrives in minutes, not days.&lt;/p&gt;

&lt;p&gt;intel.mago.team automatically monitors the exposure surface: GitHub, GitLab, paste sites, and leak forums, with alerts that allow credential rotation before the exploitation window closes. Knowing about an exposure the same day is the difference between a contained incident and a breach report that goes to the regulator.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Checklist That Closes the Immediate Gaps
&lt;/h2&gt;

&lt;p&gt;Durable remediation doesn't depend on consistent human discipline. It depends on automation that blocks the vector before the commit and on visibility into what's already outside your control.&lt;/p&gt;

&lt;p&gt;The audit starts with the existing history: &lt;code&gt;git log --all -p | grep -iE 'api_key|password|secret|token'&lt;/code&gt; on the current repository identifies past exposures. Every credential with suspected exposure needs to be rotated before any other action, even if the commit has already been reverted.&lt;/p&gt;

&lt;p&gt;For history rewriting, &lt;code&gt;git-filter-repo&lt;/code&gt; removes committed secrets permanently and replaces the deprecated &lt;code&gt;git filter-branch&lt;/code&gt;. Installing Gitleaks as a pre-commit hook via the pre-commit framework takes two commands and blocks commits matching the configured patterns.&lt;/p&gt;

&lt;p&gt;Environment variables in a local &lt;code&gt;.env&lt;/code&gt; with a global &lt;code&gt;.gitignore&lt;/code&gt; configured eliminate the most common vector for accidental exposure. GitHub Secret Scanning enabled at the organization level is free for public repositories. External continuous monitoring covers the gap that none of these internal measures can reach: what has already been copied, forked, or indexed before any remediation action.&lt;/p&gt;

&lt;p&gt;The commit has been made. The question is: who found it before you did?&lt;/p&gt;

</description>
      <category>osint</category>
      <category>github</category>
      <category>credenciais</category>
      <category>recon</category>
    </item>
    <item>
      <title>Capital One 2019: SSRF, AWS IMDS, and 106 Million Exposed Records</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:55:37 +0000</pubDate>
      <link>https://dev.to/roxdavirox/capital-one-2019-ssrf-aws-imds-and-106-million-exposed-records-4ha6</link>
      <guid>https://dev.to/roxdavirox/capital-one-2019-ssrf-aws-imds-and-106-million-exposed-records-4ha6</guid>
      <description>&lt;h1&gt;
  
  
  Capital One 2019: SSRF, AWS IMDS, and 106 Million Exposed Records
&lt;/h1&gt;

&lt;p&gt;On March 22, 2019, a single HTTP request to an IP address present on every AWS EC2 instance returned temporary IAM credentials with access to over 700 S3 buckets. No zero-day. No nation-state tooling. One SSRF and an overprivileged role.&lt;/p&gt;

&lt;p&gt;The Capital One breach was determined by IAM design, not WAF configuration. The SSRF opened the door in one HTTP request, but the IAM role attached to the WAF instance, &lt;code&gt;ISRM-WAF-Role&lt;/code&gt;, decided 700 buckets were in scope. A properly scoped WAF needs no S3 data access at all. The blast radius could have been zero bytes.&lt;/p&gt;

&lt;h2&gt;
  
  
  One HTTP Request, 700 S3 Buckets
&lt;/h2&gt;

&lt;p&gt;The full attack chain ran in three steps, each one amplifying the blast radius of the previous. The SSRF delivered credentials. The credentials opened the AWS API. The overprivileged IAM role turned API access into catastrophic exposure.&lt;/p&gt;

&lt;p&gt;IMDS exposes the active role name with no authentication. The first GET to &lt;code&gt;http://169.254.169.254/latest/meta-data/iam/security-credentials/&lt;/code&gt; returned &lt;code&gt;ISRM-WAF-Role&lt;/code&gt;. The second GET to &lt;code&gt;http://169.254.169.254/latest/meta-data/iam/security-credentials/ISRM-WAF-Role&lt;/code&gt; returned a JSON body with &lt;code&gt;AccessKeyId&lt;/code&gt;, &lt;code&gt;SecretAccessKey&lt;/code&gt;, &lt;code&gt;Token&lt;/code&gt;, and &lt;code&gt;Expiration&lt;/code&gt;. With those STS credentials, Paige Thompson ran &lt;code&gt;aws s3 ls&lt;/code&gt; from outside AWS and listed over 700 buckets.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;s3:GetObject&lt;/code&gt; calls that followed pulled approximately 30 GB over two days, March 22-23, 2019. The data covered 106 million credit application records: 100 million US customers and 6 million in Canada, spanning 2005 to 2019. That included 140,000 Social Security numbers, 80,000 bank account numbers, plus payment histories, credit scores, and credit limits.&lt;/p&gt;

&lt;p&gt;The breach went undetected for four months. On July 17, 2019, a GitHub user alerted Capital One about stolen data posted by Thompson under the alias Erratic. Capital One notified the FBI on July 19. No internal alert fired during the two days 30 GB was exfiltrated from the infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  169.254.169.254: The Credential Dispenser With No Authentication
&lt;/h2&gt;

&lt;p&gt;IMDSv1 was designed for operational convenience, not adversarial environments. Any process running on the EC2 instance, including processes manipulated via SSRF, could retrieve full IAM credentials without any token, signature, or identity check.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;169.254.169.254&lt;/code&gt; is a link-local address: it exists only within the instance's own network stack. Link-local routing means the WAF instance appears as the requester to the metadata service. An SSRF in the application turns the WAF instance into an involuntary relay: the request arrives at the application, the application directs the WAF to issue the GET to IMDS, and IMDS responds with valid STS credentials in plain text.&lt;/p&gt;

&lt;p&gt;The returned credentials are real AWS credentials, with &lt;code&gt;AccessKeyId&lt;/code&gt;, &lt;code&gt;SecretAccessKey&lt;/code&gt;, &lt;code&gt;Token&lt;/code&gt;, and &lt;code&gt;Expiration&lt;/code&gt; fields. They work from any configured AWS client on any network, not just from inside the VPC. STS credential validity varies by role, but typically lasts hours, long enough to complete an exfiltration at scale.&lt;/p&gt;

&lt;p&gt;AWS released IMDSv2 on November 19, 2019, seven months after the breach. IMDSv2 requires a PUT handshake with the &lt;code&gt;X-aws-ec2-metadata-token-ttl-seconds&lt;/code&gt; header to obtain a session token before any metadata GET. A hop-limit of 1 on the PUT packet's IP TTL ensures the response token is dropped after one network hop, breaking SSRF chains that pass through proxies or intermediate WAFs.&lt;/p&gt;

&lt;p&gt;IMDSv2 addresses the specific SSRF-to-IMDS vector used against Capital One. It does not protect against arbitrary code execution on the instance, where the attacker sits on the same network hop and can complete the PUT handshake normally. And it does nothing to reduce the blast radius of an overprivileged IAM role: the permissions policy remains the deciding factor.&lt;/p&gt;

&lt;h2&gt;
  
  
  The IAM Role That Controlled Every Bucket
&lt;/h2&gt;

&lt;p&gt;The blast radius of the Capital One breach was entirely determined by what &lt;code&gt;ISRM-WAF-Role&lt;/code&gt; had permission to do. That is an IAM design decision, not an inevitable attack outcome. A WAF has no operational reason to read customer financial PII stored in S3.&lt;/p&gt;

&lt;p&gt;Based on reconstructed court records, &lt;code&gt;ISRM-WAF-Role&lt;/code&gt; held permissions consistent with &lt;code&gt;s3:*&lt;/code&gt; on &lt;code&gt;Resource: *&lt;/code&gt;, putting over 700 buckets in scope. A properly scoped WAF role would need at most &lt;code&gt;s3:GetObject&lt;/code&gt; on a specific WAF configuration bucket. The difference between &lt;code&gt;Resource: *&lt;/code&gt; and &lt;code&gt;arn:aws:s3:::waf-config-prod/*&lt;/code&gt; is the difference between 30 GB exfiltrated and zero bytes.&lt;/p&gt;

&lt;p&gt;The OCC imposed an $80 million civil money penalty on Capital One on August 6, 2020, the first significant regulatory penalty against a bank for a cloud security failure. The OCC cited failure to establish adequate risk management controls for the cloud environment, absence of effective data loss prevention controls, and lack of effective alert systems. The Cleary Gottlieb analysis of the OCC enforcement order confirms that regulatory action focused on governance deficiencies, not the specific WAF misconfiguration.&lt;/p&gt;

&lt;p&gt;Paige Thompson, a former AWS engineer with direct knowledge of the IMDS endpoint, was sentenced to time served plus five years of probation. Prior knowledge of the endpoint accelerated identifying the attack vector. The overprivileged IAM policy is what determined the scale of the consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why ModSecurity Let It Through
&lt;/h2&gt;

&lt;p&gt;ModSecurity's failure was necessary for Thompson's specific attack, but insufficient to explain the scale of the impact. ModSecurity, with its default ruleset, does not block outbound application requests to the &lt;code&gt;169.254.0.0/16&lt;/code&gt; range. That is a documented configuration gap, not a software bug.&lt;/p&gt;

&lt;p&gt;SSRF filter bypass techniques are numerous and well documented in offensive security literature. Decimal IP notation converts &lt;code&gt;169.254.169.254&lt;/code&gt; to &lt;code&gt;2852039166&lt;/code&gt;, bypassing WAF rules based on string matching. Equivalent IPv6 notation and URL encoding offer alternative paths to the same address. Thompson built a custom scanner to identify misconfigured AWS accounts, drawing on her AWS engineering background to locate instances vulnerable to the IMDS vector.&lt;/p&gt;

&lt;p&gt;The structural problem runs deeper than the ModSecurity ruleset. A WAF defends against inbound attacks, but an SSRF converts the WAF into an outbound attacker against its own internal environment. Perimeter controls cannot set an upper bound on blast radius because they do not control what happens after credentials are obtained. The OCC explicitly cited the absence of effective alert systems as a determining cause of the impact: CloudTrail data events for S3 existed as an available AWS capability, but volume-based alerts were not configured in Capital One's environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  IMDSv2: What It Fixes and What It Does Not
&lt;/h2&gt;

&lt;p&gt;IMDSv2 closes the specific SSRF-to-IMDS vector used against Capital One. The mechanism requires a PUT to &lt;code&gt;http://169.254.169.254/latest/api/token&lt;/code&gt; with the &lt;code&gt;X-aws-ec2-metadata-token-ttl-seconds&lt;/code&gt; header, which returns a session token with a configured TTL. Subsequent GET requests to IMDS must include that token in the &lt;code&gt;X-aws-ec2-metadata-token&lt;/code&gt; header. SSRF attacks that can only issue GET requests do not complete the handshake and do not obtain credentials.&lt;/p&gt;

&lt;p&gt;The hop-limit of 1 on the PUT token's IP packet is the critical control against SSRF chains that pass through intermediaries. When the PUT request traverses an additional network hop, such as a WAF or reverse proxy, the IP packet's TTL is decremented to zero and the response token is dropped by the operating system. The external attacker does not receive the token and cannot issue the subsequent IMDS GETs.&lt;/p&gt;

&lt;p&gt;AWS made IMDSv2 the default for new instances in 2021. Existing instances require an opt-in migration by setting &lt;code&gt;HttpTokens=required&lt;/code&gt; via console or CLI. An environment with older instances created before 2021 that have not been migrated still runs IMDSv1 by default.&lt;/p&gt;

&lt;p&gt;IMDSv2 does not protect against arbitrary code execution on the instance, where the attacker is on the same hop and completes the PUT normally. It does not protect against SSRF variants in frameworks that allow issuing PUT requests with custom headers. And it does nothing to reduce the blast radius of an overprivileged IAM role: if the attacker reaches IMDS through any working vector, the role's permissions determine exactly what can be exfiltrated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detecting SSRF-to-IMDS Chains Before Exfiltration
&lt;/h2&gt;

&lt;p&gt;Three detection layers would have identified the Capital One breach in real time. None were operational during the two days of 30 GB exfiltration.&lt;/p&gt;

&lt;p&gt;GuardDuty generates the &lt;code&gt;UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS&lt;/code&gt; finding when EC2 instance credentials are used from an IP address outside AWS. Thompson exfiltrated from her home network. That finding would have fired on the first &lt;code&gt;aws s3 ls&lt;/code&gt; call executed outside AWS infrastructure, before a single byte of data left the VPC.&lt;/p&gt;

&lt;p&gt;S3 data events in CloudTrail plus rate-based volume alerts would have detected 700 buckets being listed and read by a WAF instance within 24 hours. The operational baseline for a WAF issuing &lt;code&gt;s3:GetObject&lt;/code&gt; calls against credit application data is zero. Any deviation from that baseline is detectable with a CloudWatch threshold rule, no implementation complexity required.&lt;/p&gt;

&lt;p&gt;Security Groups at the application layer denying outbound TCP to &lt;code&gt;169.254.0.0/16&lt;/code&gt; contain the SSRF before credentials are reached. This control operates at the network layer, independent of WAF configuration or application code. intel.mago.team (MAGO team tool) identifies this class of misconfiguration through passive API surface analysis: EC2 roles with broad-scope &lt;code&gt;s3:*&lt;/code&gt; and instances with IMDSv1 enabled are flagged before any active exploitation.&lt;/p&gt;

&lt;p&gt;The OCC's $80 million fine did not change Thompson's sentence. It changed the IAM governance budget of every CISO at banks with cloud workloads. The blast radius of any future SSRF in your environment is set right now by your IAM role policies, not your perimeter controls.&lt;/p&gt;

</description>
      <category>securityincidents</category>
      <category>cloudsecurity</category>
      <category>ssrf</category>
      <category>aws</category>
    </item>
    <item>
      <title>TLS Certificate Analysis: What Your SSL Config Reveals</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:55:01 +0000</pubDate>
      <link>https://dev.to/roxdavirox/tls-certificate-analysis-what-your-ssl-config-reveals-53a6</link>
      <guid>https://dev.to/roxdavirox/tls-certificate-analysis-what-your-ssl-config-reveals-53a6</guid>
      <description>&lt;p&gt;In March 2019, an expired authentication certificate took tens of thousands of Cisco network devices offline — not because an attacker interfered, but because nobody was monitoring the expiration field.&lt;/p&gt;

&lt;p&gt;TLS certificates are public surveillance records. The CA publishes them in append-only logs before the service goes live, with the operator having no control over the timing or destination of the publication. An attacker querying crt.sh against your infrastructure finds your new subdomains before DNS propagates, your staging environments before any legitimate user accesses them, and your infrastructure's expiration dates before your team is alerted. These logs are not an optional security feature. They are a condition of existence for any certificate from a public CA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your CA Published This. You Did Not Authorize It
&lt;/h2&gt;

&lt;p&gt;CT log submission happens within milliseconds of issuance. The operator is still configuring the server when the certificate is already indexed and searchable by anyone with access to crt.sh. RFC 9162 (2021) defines the technical mechanism, and Google Chrome has enforced it since May 2018: a certificate without a log entry is rejected by the browser with no warning to the user. More than 10 billion certificates have been recorded in the logs since 2013, all accessible via JSON API without authentication and without any record of who queried them.&lt;/p&gt;

&lt;p&gt;0ktapus demonstrated the practical effect of this during the 2022 campaign. Group-IB identified 169 phishing domains before most were active, pivoting on certificate issuance patterns. The certificates appeared in CT logs before the phishing sites became accessible, exposing targets including Twilio, Cloudflare, LastPass, and 130 other organizations. The certificate is not an artifact of a deployed service; it is the deployment announcement, published by the CA as a mandatory step before any request is served.&lt;/p&gt;

&lt;h2&gt;
  
  
  SAN Fields Are Org Charts for Attackers
&lt;/h2&gt;

&lt;p&gt;The Subject Alternative Name field lists every hostname covered by the certificate. A single certificate for &lt;code&gt;api-staging.empresa.com&lt;/code&gt;, &lt;code&gt;internal-proxy.empresa.com&lt;/code&gt;, &lt;code&gt;mailrelay.empresa.com&lt;/code&gt;, and &lt;code&gt;dev.empresa.com&lt;/code&gt; reveals in one query: the scope of the development environment, the existence of an internal proxy, the email relay configuration, and the staging-to-production separation. This happens before any HTTP request reaches the server, and regardless of whether those hosts have public DNS records.&lt;/p&gt;

&lt;p&gt;Organizations operating multiple domains through a holding company expose acquisition structure in the SANs of multi-domain certificates. A corporate certificate with &lt;code&gt;*.empresa-adquirida.com&lt;/code&gt; in the SAN field appears in the CT log before the acquisition press release. The X.509 certificate OSINT analysis published by Gigamon found that large corporations expose organizational boundaries in multi-SAN certificates, including hosting platform fingerprints that identify the provider without interacting with the server.&lt;/p&gt;

&lt;p&gt;The UCSB research published at EuroS&amp;amp;P 2023 showed that systematic CT log analysis allows discovering hostnames that never appear in public DNS, and correlating software versions exposed on those hostnames with known vulnerabilities at scale without sending a single active packet against the target. Domains hosted on cPanel include &lt;code&gt;cpanel.&lt;/code&gt; subdomains in the SANs as default platform behavior. This is not a misconfiguration. It is the expected behavior of those platforms, recorded by mandate in a global log accessible without authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issuance Timestamps Are a Deployment Intelligence Feed
&lt;/h2&gt;

&lt;p&gt;A new certificate in the CT logs means a new service is arriving. The window between issuance and the service becoming accessible is typically 1 to 48 hours. Attackers monitoring CT logs reach the target before the WAF has rules written for the new endpoint, before the security team knows the service exists, and before the first legitimate user makes a request.&lt;/p&gt;

&lt;p&gt;Group-IB used precisely this timing in the 0ktapus investigation (2022). Phishing infrastructure certificates appeared in CT logs 2 to 8 hours before the sites went live. By tracking the issuance pattern, investigators mapped 169 domains attacking Twilio, Cloudflare, LastPass, DoorDash, Signal, and over 130 organizations. The investigation led to the arrest of leader Tyler Buchanan at Palma de Mallorca airport in June 2024. The same feed that coordinated the attack served as the forensic evidence chain to reconstruct it.&lt;/p&gt;

&lt;p&gt;River Security pentesters documented the operational pattern that follows from this: they monitor CT logs for mentions of the target brand, run a DNS delta against newly discovered hosts, and reach new endpoints proactively before any internal alert fires. Renewal timing also carries operational intelligence. Let's Encrypt uses 90-day cycles; a domain that stopped renewing for more than 6 months but still resolves in DNS is a subdomain takeover candidate. The expired certificate in the CT log is the signal. The DNS record still pointing to the host is the attack surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wildcard Certificates Trade Operational Convenience for Permanent CT Log Scope Disclosure
&lt;/h2&gt;

&lt;p&gt;A wildcard &lt;code&gt;*.empresa.com&lt;/code&gt; simplifies management: a single private key covers all subdomains. The cost visible in the CT log is immediate. Anyone querying the log knows that the company's subdomain namespace is unbounded, that any subdomain discovered through brute-force potentially exists in production, and that a private key compromise affects all covered services simultaneously.&lt;/p&gt;

&lt;p&gt;CA/Browser Forum Ballot SC-63 (2024) restricts wildcard scope to a single subdomain level — &lt;code&gt;*.example.com&lt;/code&gt; cannot cover &lt;code&gt;api.dev.example.com&lt;/code&gt;. Revocation is the underlying structural problem. OCSP servers are frequently unavailable at the moment a compromised certificate is being used, and Keyfactor documented that rotating a compromised wildcard across multiple servers amplifies downtime risk and extends the exposure window. A revoked wildcard in theory remains valid in practice for hours while clients do not receive the status update.&lt;/p&gt;

&lt;p&gt;The decisive metric is blast radius per compromise. A certificate with explicit SANs for &lt;code&gt;api.empresa.com&lt;/code&gt; and &lt;code&gt;app.empresa.com&lt;/code&gt; limits exposure to two services in the worst case. A wildcard &lt;code&gt;*.empresa.com&lt;/code&gt; has no such limit. The convenience of managing fewer certificates comes at the cost of turning any key compromise into a full-scope incident, and that scope has been published since day one in the CT log.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Expired Certificate Is a Marker of an Abandoned Asset
&lt;/h2&gt;

&lt;p&gt;In May 2023, Cisco SD-WAN disrupted service for more than 20,000 customers. The root cause was certificates from the 2017 Viptela acquisition, not renewed four years later, mid-way through a 10-year validity cycle (device authentication certificates issued by Cisco's private CA, not subject to the 397-day maximum that the CA/Browser Forum applies to publicly trusted certificates). The expiration date was in the CT logs since original issuance. No team monitored the logs for acquired infrastructure in the intervening four years.&lt;/p&gt;

&lt;p&gt;The pattern repeats across sectors: long-lived authentication certificates in telecommunications, energy, and critical infrastructure have renewal cycles measured in years, not weeks.&lt;/p&gt;

&lt;p&gt;From an attacker's perspective, an expired certificate on an active domain with DNS still resolving signals insufficient operational attention. CVE-2023-40104 (Android ca-certificates, CWE-295, published November 2023) allowed TLS data disclosure without user interaction on Android 12 through 14, a reminder that certificate lifecycle failures create a direct attack surface without requiring the attacker to find a new bug. A domain with an expired certificate, active DNS, and no redirect is a top candidate for CNAME takeover verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  CT Logs as an Early Warning System for Defenders
&lt;/h2&gt;

&lt;p&gt;The same public feed that attackers query is available to defenders at no cost and without authentication. crt.sh offers manual querying through a web interface and a JSON API with wildcard query support. CertSpotter (SSLMate) delivers real-time alerts for new certificates issued against monitored domains, regardless of which CA issued them, covering the scenario of a compromised CA issuing unauthorized certificates.&lt;/p&gt;

&lt;p&gt;The highest-signal alert triggers are specific: a new certificate for &lt;code&gt;*.yourdomain.com&lt;/code&gt; issued by an unexpected CA can indicate phishing or CA compromise. A new subdomain not yet deployed signals untracked surface expansion. A certificate for &lt;code&gt;paypal-yourdomain.com&lt;/code&gt; indicates phishing using your brand as a prefix or suffix. The UK CHAPS/RTGS incident (July 2024) illustrated the failure mode from the defender side: the certificate expired without internal alert — any external CT log monitor would have flagged the expiry date months in advance.&lt;/p&gt;

&lt;p&gt;intel.mago.team (MAGO team tool) automates CT log monitoring, correlating new certificate issuance with DNS resolution for continuous attack surface tracking of monitored targets without firing active scans. Receiving the alert before the certificate is in production puts you at the same vantage point the attacker would use to plan access.&lt;/p&gt;

&lt;p&gt;CT logs are not going away. Browser security depends on them as the mandatory audit mechanism for the CA ecosystem. The question is not whether your certificates are public: they are, from the millisecond of issuance, with no exceptions for any publicly trusted CA. The question is who queries crt.sh for your domain first. Every SAN in the results is a surface you are responsible for, regardless of whether you remember issuing that certificate.&lt;/p&gt;

</description>
      <category>osint</category>
      <category>security</category>
    </item>
    <item>
      <title>Kubernetes Attack Surface: What Exposed APIs and Misconfigured RBAC Reveal</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:53:14 +0000</pubDate>
      <link>https://dev.to/roxdavirox/kubernetes-attack-surface-what-exposed-apis-and-misconfigured-rbac-reveal-14d2</link>
      <guid>https://dev.to/roxdavirox/kubernetes-attack-surface-what-exposed-apis-and-misconfigured-rbac-reveal-14d2</guid>
      <description>&lt;p&gt;An attacker compromised 60+ Kubernetes clusters in a single campaign without exploits, zero-days, or CVEs. Entry came through an API server running anonymous authentication. The attacker read existing RBAC bindings and let the cluster's own configuration deliver cluster-admin access.&lt;/p&gt;

&lt;p&gt;The blast radius of a Kubernetes cluster is determined in the first 5 minutes after any foothold. The API server, RBAC bindings, and service account token automounting define the escape path before a single exploit is needed. In real incidents, the exploit comes last. Configuration already decided the outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Exploit Comes Last — Configuration Decides the Outcome First
&lt;/h2&gt;

&lt;p&gt;The RBAC Buster incident (Aqua Security, April 2023) compromised 60+ Kubernetes clusters without a single exploit. The attacker found API servers with &lt;code&gt;--anonymous-auth=true&lt;/code&gt;, read existing RBAC bindings, and reached full control in an average of 3.2 minutes after initial access. The campaign generated 14,399 malicious image pulls over 5 months, all through configuration, none through vulnerability.&lt;/p&gt;

&lt;p&gt;Tesla learned this directly in 2018. The Kubernetes dashboard was exposed without any authentication. The attacker read AWS S3 credentials directly from pod environment variables, deployed a cryptominer behind Cloudflare to mask traffic, and exited without any exploit trace. No CVE was filed because no CVE was needed.&lt;/p&gt;

&lt;p&gt;The 2025 data confirms these were not isolated cases. Unit 42 recorded a 282% increase in Kubernetes token theft during the period. Azure Kubernetes Service clusters receive the first attack attempt 18 minutes after creation. The blast radius is not determined at the moment of the incident. It is determined at &lt;code&gt;helm install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Kubernetes versions from 1.25 improved defaults: PSS replaced PodSecurityPolicy, &lt;code&gt;--anonymous-auth=false&lt;/code&gt; became the recommendation, and EKS and GKE Autopilot tightened factory settings. The blast-radius problem persists in clusters created before those changes, in self-managed deployments where operators overrode defaults for application compatibility — which Unit 42 found in 22% of audited cloud environments — and in any cluster where the attack vector is not a CVE but a ClusterRoleBinding created in 2019 that no one reviewed.&lt;/p&gt;

&lt;h2&gt;
  
  
  381,645 Entry Points: How the Exposed API Server Became Mass Exploitation Surface
&lt;/h2&gt;

&lt;p&gt;The Shadowserver Foundation identified 381,645 unique IPs responding with HTTP 200 OK on Kubernetes ports 443 and 6443. That number represents 84% of all identifiable Kubernetes clusters on the internet. Automated scanning of that volume is operationally trivial for any threat actor with a basic infrastructure budget.&lt;/p&gt;

&lt;p&gt;Censys documented 1,626,249 cluster hosts with visible version numbers in February 2024, more than double the 842,350 identified in August 2022. The &lt;code&gt;/version&lt;/code&gt; endpoint returns version information without authentication in most configurations. With version in hand, attackers can select exploits targeting specific Kubernetes, runtime, or CNI versions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--anonymous-auth=true&lt;/code&gt; flag is the Kubernetes default. It automatically grants membership in the &lt;code&gt;system:anonymous&lt;/code&gt; and &lt;code&gt;system:unauthenticated&lt;/code&gt; groups, groups that downstream RBAC rules can amplify into concrete read or write permissions. A &lt;code&gt;curl -k https://[IP]:6443/api/v1/pods&lt;/code&gt; returns a pod list in misconfigured clusters without any credentials presented.&lt;/p&gt;

&lt;h2&gt;
  
  
  etcd Port 2379: Bypassing the API Server and All Its Controls at Once
&lt;/h2&gt;

&lt;p&gt;etcd stores the entire Kubernetes cluster state: pod environment variables, ConfigMap contents, Secret values in base64, TLS certificates, and service account tokens. Direct access via port 2379 delivers everything simultaneously, bypassing the API server and any RBAC controls applied there.&lt;/p&gt;

&lt;p&gt;From etcd's perspective, the API server is just another client. The entire Kubernetes access control model, including RBAC, admission controllers, and audit logging, disappears when the attacker accesses etcd directly. The official Kubernetes documentation is explicit: read access to etcd via client certificate is equivalent to cluster-admin.&lt;/p&gt;

&lt;p&gt;CVE-2026-33413 (CVSS 8.8) quantifies the risk in unpatched clusters: unauthenticated users can invoke critical etcd backend methods via the gRPC endpoint on port 2379 without administrative tokens. Self-managed clusters with etcd exposed without mutual TLS are targeted for complete secrets exfiltration or extortion over stored data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service Account Token Automounting: Any App Vulnerability Becomes a K8s Credential
&lt;/h2&gt;

&lt;p&gt;Kubernetes automatically mounts service account tokens at &lt;code&gt;/var/run/secrets/kubernetes.io/serviceaccount/token&lt;/code&gt; in all pods with automounting active, which is the default. Any process in the pod, from the main binary to a compromised third-party dependency, can read and use that token to authenticate against the Kubernetes API as the service account identity.&lt;/p&gt;

&lt;p&gt;The cryptocurrency exchange incident documented by Unit 42 in mid-2025 followed this path exactly. A developer workstation compromise led to a malicious pod that read the token at the default path, gained cross-namespace access to cluster secrets, and reached financial backend systems without any container escape exploit at any point in the chain.&lt;/p&gt;

&lt;p&gt;The scale of the problem is documented: 22% of cloud environments in 2025 showed suspicious SA token theft activity (Unit 42). The Azure Airflow RBAC misconfiguration in 2023 affected 350+ organizations, including Fortune 500 companies, via two common configuration errors that left clusters publicly accessible. MITRE ATT&amp;amp;CK tracks the vector as T1528, with a Kubernetes-specific technique. Any authorized file read in memory or filesystem converts application compromise into control plane compromise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Over-Permission Chains in RBAC Complete the Escape Without Privilege Escalation Exploits
&lt;/h2&gt;

&lt;p&gt;Stolen service account tokens frequently do not need additional exploits. The attacker follows the permission graph the operator built. In RBAC Buster, the strategy was to create a ClusterRole with near-administrative privileges bound to a ServiceAccount named &lt;code&gt;kube-controller&lt;/code&gt; in the &lt;code&gt;kube-system&lt;/code&gt; namespace, mimicking legitimate component naming to evade manual inspection of audit logs.&lt;/p&gt;

&lt;p&gt;Binding &lt;code&gt;cluster-admin&lt;/code&gt; to the &lt;code&gt;default&lt;/code&gt; ServiceAccount in the &lt;code&gt;default&lt;/code&gt; namespace distributes full cluster control to every pod in that namespace. Wildcard permissions with &lt;code&gt;verbs: ["*"]&lt;/code&gt; and &lt;code&gt;resources: ["*"]&lt;/code&gt; grant admin-equivalent access and appear consistently in self-managed clusters. No automatic alert fires on the creation of an overly permissive ClusterRoleBinding by default.&lt;/p&gt;

&lt;p&gt;Red Hat research (2026) documented where tooling fails: RBAC linters analyze bindings individually and produce a false sense of security. Attackers reason over the full permission graph and identify escalation paths that per-binding analysis never detects. RBAC Buster added a dimension to this: the malicious ClusterRoleBinding survived intact after the anonymous access that enabled entry was disabled. The backdoor outlasted the original misconfiguration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detection at the API Layer: What Attackers Leave and What We Monitor
&lt;/h2&gt;

&lt;p&gt;Shodan and Censys fingerprint Kubernetes API servers via ports 443 and 6443 continuously. The &lt;code&gt;/version&lt;/code&gt; endpoint returns version without authentication in most configurations, delivering the exact patch level and enabling version-targeted exploit selection. Any 200 OK status on port 6443 without credentials is classified as an immediate high-severity finding.&lt;/p&gt;

&lt;p&gt;For continuous passive monitoring of exposed Kubernetes API servers, etcd on port 2379, and dashboards on ports 8001/8443, &lt;a href="https://intel.mago.team" rel="noopener noreferrer"&gt;intel.mago.team&lt;/a&gt; (MAGO team tool) maintains visibility without active scanning.&lt;/p&gt;

&lt;p&gt;Kubernetes audit logs carry the most relevant signals: anonymous requests to &lt;code&gt;/api/v1&lt;/code&gt;, ClusterRoleBinding creation, and SA token access originating from IPs outside the expected range. CVE-2024-21626 (runC, critical) extends the blast radius to the node level when privileged containers or &lt;code&gt;hostPath&lt;/code&gt; mounts to &lt;code&gt;/etc&lt;/code&gt; or &lt;code&gt;/var/run/docker.sock&lt;/code&gt; are present, converting pod compromise into physical host compromise.&lt;/p&gt;

&lt;p&gt;Most Kubernetes security programs invest in CVE patching and runtime monitoring. Both are necessary. Clusters that deliver &lt;code&gt;cluster-admin&lt;/code&gt; in 3.2 minutes do so via a ClusterRoleBinding created during a pressured deploy, a token automounted since the first &lt;code&gt;helm install&lt;/code&gt;, and an API server listening on port 6443 with defaults no one reviewed. Audit RBAC bindings with tools that analyze the full graph, disable automounting in pods that do not need API access, block port 2379 at the network layer, and confirm that &lt;code&gt;/version&lt;/code&gt; returns 401 and not 200 from outside your VPC.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>cybersecurity</category>
      <category>kubernetes</category>
      <category>security</category>
    </item>
    <item>
      <title>Email Header Analysis: What SMTP Metadata Reveals About Infrastructure and Identity</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:52:38 +0000</pubDate>
      <link>https://dev.to/roxdavirox/email-header-analysis-what-smtp-metadata-reveals-about-infrastructure-and-identity-g7k</link>
      <guid>https://dev.to/roxdavirox/email-header-analysis-what-smtp-metadata-reveals-about-infrastructure-and-identity-g7k</guid>
      <description>&lt;p&gt;The email your team flagged as probable phishing contains the attacker's entire infrastructure in 30 lines of plain text. Most analysts check 2 things: SPF pass/fail and the From address. The rest goes unread.&lt;/p&gt;

&lt;p&gt;Email headers are a complete infrastructure map. Every relay hop, server version, authentication result, and sending IP are preserved in plain text, and most senders, including attackers, do not know what they are broadcasting. Anyone who reads the full header has access to reconnaissance data that no endpoint tool captures.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Received Chain Is a Hop-by-Hop Confession
&lt;/h2&gt;

&lt;p&gt;Every &lt;code&gt;Received&lt;/code&gt; header added by a relay includes a timestamp checkpoint and server identification that attackers cannot remove without breaking delivery, making the routing path forensically irrefutable.&lt;/p&gt;

&lt;p&gt;Not every header carries the same forensic weight. Received headers are relay-inserted — removing one breaks delivery chain validation, so MTAs cannot forge them without leaving a gap. X-Mailer, X-Originating-IP, and Message-ID format strings are all sender-controlled and trivially set to any value. The forensic anchor is the Received chain; the metadata headers provide context, not certainty.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Received&lt;/code&gt; headers are inserted bottom-up: the oldest hop is last, the recipient's server is first. That parsing detail is the most common analyst error: reading in the wrong order reverses traffic direction and attributes IPs to the receiver instead of the sender.&lt;/p&gt;

&lt;p&gt;Each hop records server hostname, IP, software identifier (e.g., Postfix 3.5.6), protocol (ESMTPS), and timestamp with timezone offset. A clock deviation greater than 120 seconds between 2 hops indicates header forgery or a misconfigured relay. The boundary between RFC1918 private IPs and public IPs marks the exact entry point of corporate email.&lt;/p&gt;

&lt;p&gt;The SLOW#TEMPEST campaign (Securonix, August 2024) delivered Cobalt Strike payloads via phishing emails routed through infrastructure entirely hosted on Shenzhen Tencent Cloud (AS45090). The operator's geography was visible in the ASN signatures of the &lt;code&gt;Received&lt;/code&gt; headers, with no active probing required. The full path was printed on every delivered email.&lt;/p&gt;

&lt;p&gt;The relevant sending IP is the first external IP in the chain: the last &lt;code&gt;Received&lt;/code&gt; header that contains a public address outside the recipient's email provider. That is the attacker's entry point into the internet postal system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication-Results Exposes What the Sender Authorized
&lt;/h2&gt;

&lt;p&gt;SPF, DKIM, and DMARC in the &lt;code&gt;Authentication-Results&lt;/code&gt; header do more than confirm pass/fail. They expose which IP ranges the domain owner authorized, which signing selector was used, and whether the sender intentionally left enforcement disabled.&lt;/p&gt;

&lt;p&gt;An SPF failure reveals the exact sending IP and confirms it is not on the authorized sender list. That IP can be pivoted against threat intelligence databases immediately. The DKIM selector (e.g., &lt;code&gt;s=google&lt;/code&gt;, &lt;code&gt;s=protonmail2048&lt;/code&gt;) identifies which email provider signed the message: a banking domain signed by a consumer ESP is an immediate anomaly, visible before any content analysis.&lt;/p&gt;

&lt;p&gt;The DMARC policy field (&lt;code&gt;p=none&lt;/code&gt;) in the header indicates the domain owner chose not to apply enforcement. 83.9% of all domains analyzed globally have no DMARC record (Red Sift, December 2024). When the field is absent, the header communicates exactly that: the domain does not monitor spoofing.&lt;/p&gt;

&lt;p&gt;In 2024, IronScales documented a malicious domain that passed SPF and DKIM with no DMARC record configured. Microsoft applied the &lt;code&gt;BestGuessPass&lt;/code&gt; verdict and delivered the message to 3 mailboxes. The gap was visible in the &lt;code&gt;Authentication-Results&lt;/code&gt; header before delivery: the absence of an enforcement policy was explicit in plain text. Analysts who checked only the final verdict missed the signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message-ID and X-Mailer Are Server Fingerprints Disguised as Metadata
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Message-ID&lt;/code&gt; format and the &lt;code&gt;X-Mailer&lt;/code&gt; header reveal email server software, version, and frequently the generating host. Attackers treat these fields as irrelevant; they uniquely identify the sending infrastructure.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Message-ID&lt;/code&gt; format is defined by the MTA: Postfix generates &lt;code&gt;&amp;lt;timestamp.pid.hostname@domain&amp;gt;&lt;/code&gt;, Exim uses &lt;code&gt;&amp;lt;UUID@domain&amp;gt;&lt;/code&gt;, Exchange generates &lt;code&gt;&amp;lt;UUID@server.domain.local&amp;gt;&lt;/code&gt;. The local part frequently embeds the server's internal hostname, which can differ from the envelope HELO, exposing hosting provider templates or the attacker organization's internal naming conventions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;X-Mailer&lt;/code&gt; and &lt;code&gt;User-Agent&lt;/code&gt; headers identify email client software and version, such as Microsoft Outlook 16.0.14326 or Mutt/1.14.0. business email compromise (BEC) actors using webmail frequently expose the exact interface used. Botnet fingerprinting research (arXiv:1903.11400, 2019) demonstrated that &lt;code&gt;User-Agent&lt;/code&gt; and &lt;code&gt;X-Mailer&lt;/code&gt; fields combined with SMTP dialect identify spam botnet families with over 90% accuracy.&lt;/p&gt;

&lt;p&gt;Timestamps in &lt;code&gt;Message-ID&lt;/code&gt; with millisecond resolution indicate automated bulk sending tools; second resolution indicates human-operated clients. That distinction separates automated campaigns from targeted BEC before any content analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Single Sending IP Reveals ASN, Provider, and Campaign History
&lt;/h2&gt;

&lt;p&gt;The first external IP in the &lt;code&gt;Received&lt;/code&gt; chain is the entry point into a public intelligence chain: ASN ownership, provider abuse history, co-hosted domains, and prior campaign attributions, all queryable in minutes from a single address.&lt;/p&gt;

&lt;p&gt;IP-to-ASN lookup via Team Cymru, RIPE, or BGP.he.net immediately distinguishes residential ISP from bulletproof hosting from cloud provider. Shodan and Censys index email server banners on ports 25, 465, and 587: a phishing IP running Postfix with a self-signed certificate and open relay is a searchable fingerprint in historical and recent scans.&lt;/p&gt;

&lt;p&gt;Passive DNS via SecurityTrails or DNSDB maps domains that historically pointed to the IP. In documented campaigns, a single phishing IP typically resolves to dozens of lookalike domains registered in the same campaign window. The &lt;code&gt;X-Originating-IP&lt;/code&gt; header exposes the sending client's IP even when the sending domain is legitimate: a message sent via Outlook.com from a Nigerian residential IP while claiming to be an American CFO is visible in the header without any email server access.&lt;/p&gt;

&lt;p&gt;The SLOW#TEMPEST campaign had its entire geographic attribution derived from &lt;code&gt;Received&lt;/code&gt; headers, pointing exclusively to Tencent ASNs in Shenzhen. For passive monitoring of sending infrastructure, tools that aggregate MX records, SPF include graphs, sending IP reputation, and server version disclosure eliminate the manual lookup sequence across dozens of campaign IPs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The DMARC Enforcement Gap Makes Phishing Self-Reporting
&lt;/h2&gt;

&lt;p&gt;Phishing emails that fail DMARC declare their illegitimacy in the &lt;code&gt;Authentication-Results&lt;/code&gt; header. With only 9% of domains with DMARC records operating at &lt;code&gt;p=reject&lt;/code&gt; (DMARC Report, 2026), that declaration goes ignored, and analysts who do not read the header miss the plain-text signal.&lt;/p&gt;

&lt;p&gt;The FBI IC3 2024 report recorded $2.77B in verified BEC losses across 21,442 complaints. EasyDMARC 2025 shows DMARC adoption grew 79% in 3 years, but enforcement lagged: most new adopters configure &lt;code&gt;p=none&lt;/code&gt; for monitoring, leaving spoofing channels open while headers communicate that the problem is known.&lt;/p&gt;

&lt;p&gt;The GuidePoint Security case (Q1 2024) illustrates the full pattern: an attacker accessed corporate email and attempted transfers above $100,000. The attack was reconstructed entirely via header forensics and DKIM selector reuse. The fraudulent infrastructure was registered as MedHealth via Titan Email, with mailbox rules configured for keywords including invoice, transfer, and ACH.&lt;/p&gt;

&lt;p&gt;A DMARC failure combined with a From domain belonging to a financial institution is a high-confidence BEC indicator. No ML model is required: it is a plain-text signal, consistently missed by analysts who do not read raw headers on every suspicious message.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Single-Email Forensics to Campaign Attribution
&lt;/h2&gt;

&lt;p&gt;Reading 1 email header is detection. Reading 50 headers from the same campaign cluster is attribution: the correlation signals are in plain text in every message, including shared IPs, identical &lt;code&gt;Message-ID&lt;/code&gt; formats, synchronized timestamps, and identical DKIM selectors.&lt;/p&gt;

&lt;p&gt;A shared IP in &lt;code&gt;Received-from&lt;/code&gt; across emails with different &lt;code&gt;From&lt;/code&gt; addresses is the highest-confidence campaign correlation signal. Attackers reuse sending infrastructure across multiple target organizations. Identical &lt;code&gt;Message-ID&lt;/code&gt; format strings across reported phishing emails identify a specific sending platform or script, even when domains rotate every campaign.&lt;/p&gt;

&lt;p&gt;DKIM selector reuse links apparently unrelated emails to a single compromised ESP account. A consistent UTC offset across multiple emails correlates with working time zones and narrows geographic attribution without relying on IP geolocation. Ghostwriter APT (BushidoToken, 2025) had 12 months of phishing campaigns correlated via consistent ASN block and email server configuration: APT operators rotate web infrastructure faster than email infrastructure, leaving correlation traces in headers for months.&lt;/p&gt;

&lt;p&gt;Header forensics requires no specialized tooling: only access to the raw header and a passive DNS resolver. The gap is not technical capability; it is habit. Analysts who pivot the first external IP against passive DNS and correlate &lt;code&gt;Message-ID&lt;/code&gt; patterns across a campaign cluster will find attacker infrastructure that endpoint detection never captures, because it was never hidden.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>infrastructure</category>
      <category>networking</category>
      <category>security</category>
    </item>
    <item>
      <title>Passive DNS: The Infrastructure History That Reveals Origin, Movement, and Campaign</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:52:03 +0000</pubDate>
      <link>https://dev.to/roxdavirox/passive-dns-the-infrastructure-history-that-reveals-origin-movement-and-campaign-4gkf</link>
      <guid>https://dev.to/roxdavirox/passive-dns-the-infrastructure-history-that-reveals-origin-movement-and-campaign-4gkf</guid>
      <description>&lt;p&gt;A domain migrates behind Cloudflare and the operator believes the origin IP is protected. It is not. Every resolver that answered queries before that migration logged the response, and those records are queryable today in databases that have been accumulating history since 2010.&lt;/p&gt;

&lt;p&gt;Passive DNS is the permanent historical archive of every IP a domain has ever resolved to. Attackers use these records to find origin servers hidden behind CDNs, track infrastructure movements over months, and expand a single IOC into a complete campaign map.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Passive DNS Records That Active DNS Does Not Show
&lt;/h2&gt;

&lt;p&gt;Passive DNS captures A, AAAA, NS, MX, and CNAME records with first-seen and last-seen timestamps — everything that was ever authoritative for that domain, regardless of what it points to today. Farsight's DNSDB stores over 300 billion records dating back to July 2010, ingesting up to 200,000 DNS observations per second and 2TB of data daily. SecurityTrails has indexed 3.5 billion hostnames with &lt;code&gt;first_seen&lt;/code&gt; and &lt;code&gt;last_seen&lt;/code&gt; timestamps on every entry.&lt;/p&gt;

&lt;p&gt;The practical difference between active and passive DNS is not technical — it is temporal. Active DNS queries the authoritative server now and returns the current state. Passive DNS aggregates responses from distributed sensors over years, without making any connection to the target. This lets you reconstruct an adversary's infrastructure history without triggering any detection system.&lt;/p&gt;

&lt;p&gt;Every DNS change leaves the previous record intact in passive databases. Migrating to a CDN does not erase the prior A record, switching hosting does not eliminate old NS records, and domain expiration does not remove entries that pointed to the origin server. The result is a permanent inventory of infrastructure decisions the operator assumed were temporary.&lt;/p&gt;

&lt;h2&gt;
  
  
  IP Pivot: From One IOC to an Entire Campaign
&lt;/h2&gt;

&lt;p&gt;The Coyote Banking Trojan demonstrated the value of the IP pivot in 2024 with precision documented by Validin. The C2 domain &lt;code&gt;cloridatosys[.]com&lt;/code&gt; resolved to IP &lt;code&gt;20.201.119[.]204&lt;/code&gt;, with a first_seen date in December 2023. A passive DNS query for all domains that resolved to that IP during the same period returned 48 domains: 18 matched exactly the domains from BlackBerry's report, and 30 were previously unknown in any public threat feed.&lt;/p&gt;

&lt;p&gt;The Gamaredon/ACTINIUM case scales the same mechanism to APT level. Microsoft's February 2022 report listed 124 malicious domains belonging to the group, which was targeting Ukrainian organizations. Passive DNS analysis by Embee Research showed that 49 of the 124 domains resolved to IP &lt;code&gt;139.180.174[.]234&lt;/code&gt; around July 27, 2022. Filtering &lt;code&gt;.ru&lt;/code&gt; domains that pointed to that IP at that timestamp, the researcher found 122 previously unreported domains, including &lt;code&gt;coffiti[.]ru&lt;/code&gt;, &lt;code&gt;torfasta[.]ru&lt;/code&gt;, and &lt;code&gt;vilitord[.]ru&lt;/code&gt;, all exhibiting the same subdomain generation pattern with random words. The 124-domain blocklist became 246 in a few hours.&lt;/p&gt;

&lt;p&gt;The mechanism is straightforward: initial IOC, historical IP, all domains that shared that IP, pattern matching. Campaign infrastructure reuses hosting because changing IPs has real operational cost, and that behavior is the signal passive DNS makes persistently visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  CDN Bypass: How Historical Records Expose the Origin Server
&lt;/h2&gt;

&lt;p&gt;Any domain that existed before enabling a CDN was indexed with its origin IP. A 2024 academic analysis of the Tranco Top 1M identified 4,766 CDN-protected domains with DNS vulnerabilities; 727 of them, 15.25% of the total, exposed the origin server IP through residual records or post-CDN-termination resolution.&lt;/p&gt;

&lt;p&gt;The residual vulnerability occurs when a client migrates away from a CDN or cancels the contract: the old A record, pointing directly to the origin server, persists in passive DNS databases regardless of the current configuration. The practical flow: SecurityTrails returns historical A records for the domain, the pre-CDN IP is validated in Shodan or Censys confirming that port 80/443 still responds, and the request goes directly to the origin server, bypassing firewall, WAF, and DDoS protection.&lt;/p&gt;

&lt;p&gt;Staging subdomains amplify the problem. Subdomains like &lt;code&gt;staging.target.com&lt;/code&gt;, &lt;code&gt;dev.target.com&lt;/code&gt;, or &lt;code&gt;origin.target.com&lt;/code&gt; frequently point directly to the server without CDN protection, appear in passive DNS even when the primary domain is protected, and continue responding because administrators rarely include them in the hardening scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazarus and the Email Address That Connected 27 VPN Servers
&lt;/h2&gt;

&lt;p&gt;The $1.4B ByBit theft in February 2025 was prepared in advance, with the timeline documented in passive DNS. The domain &lt;code&gt;bybit-assessment[.]com&lt;/code&gt; was registered on February 20, 2025 at 22:21:57 UTC, hours before the attack executed. The A record pointed to IP &lt;code&gt;91.222.173[.]30&lt;/code&gt;, which from February 21 onward hosted multiple malicious domains identified by Silent Push in its Lazarus Group infrastructure analysis.&lt;/p&gt;

&lt;p&gt;Pivoting on that IP address revealed a cluster of cryptocurrency scam and fake job listing infrastructure: &lt;code&gt;blockchainjobhub[.]com&lt;/code&gt;, &lt;code&gt;jobinterview360[.]com&lt;/code&gt;, &lt;code&gt;nvidia-release[.]org&lt;/code&gt;. The registrant email &lt;code&gt;trevorgreer9312@gmail[.]com&lt;/code&gt; was tied to a Lazarus operational persona documented in prior campaigns. That single correlation point connected apparently unrelated domains spread across months of operation.&lt;/p&gt;

&lt;p&gt;Exposed infrastructure logs revealed 27 unique Astrill VPN IPs, confirming the OPSEC pattern consistent with DPRK operators. Passive DNS provided the full temporal correlation: domain created hours before the attack, sharing hosting with prior campaign infrastructure, linked by registrant email to a known persona from the group's previous operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools: Free, Commercial, and When to Use Each
&lt;/h2&gt;

&lt;p&gt;No passive DNS provider has complete sensor coverage. The choice depends on the historical depth required, the analysis context (malware vs. APT), and the need for API access in automated pipelines.&lt;/p&gt;

&lt;p&gt;DNSDB (Farsight/DomainTools): over 300 billion records since July 2010, API-first, precise first_seen/last_seen timestamps with observation counts. Best for APT infrastructure analysis requiring years of historical reach. SecurityTrails: 3.5 billion hostnames indexed, free tier available, certificate transparency integration. Best for CDN bypass and quick lookups. VirusTotal passive DNS: direct correlation with indexed malware samples. Best when analysis starts from a malware sample rather than a domain. Microsoft Defender TI (formerly PassiveTotal/RiskIQ): 400 million records per day, SSL certificate correlation, integrated into the Microsoft stack. Best for SOC analysts in the Microsoft ecosystem. Validin: free tier with malware infrastructure pivot capability; when a CDN blocks IP pivoting, the HTML title tag pivot technique is an effective alternative even against Cloudflare-protected C2s.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse Monitoring: Getting Alerts When Your IP Appears in a New Domain
&lt;/h2&gt;

&lt;p&gt;Passive DNS works in both directions. The logic an attacker uses to map a target's infrastructure can be inverted to detect when new domains point to your organization's IPs, turning the same technique into a defensive tool.&lt;/p&gt;

&lt;p&gt;Passive DNS APIs have a lag of 5 to 30 minutes, compared to seconds for Certstream on TLS certificates. Certstream does not capture domains without HTTPS, which leaves uncertificated attack infrastructure outside the monitoring window. Passive DNS monitoring covers that gap: it detects domains pointing to the organization's IP block regardless of certificates, with minute-level latency that is acceptable for most defensive use cases. &lt;a href="https://intel.mago.team" rel="noopener noreferrer"&gt;intel.mago.team&lt;/a&gt; (MAGO team tool) monitors new DNS records pointing to organization IPs and alerts when a newly created domain resolves to the registered IP block.&lt;/p&gt;

&lt;p&gt;The abuse pattern is documented: attackers register phishing domains pointing to compromised infrastructure within the victim's IP block before the compromise is detected. Every domain migration, every hosting switch, every CDN contract cancellation leaves a permanent trace in passive DNS. The practitioner who checks historical A records before assuming CDN protection, and who pivots on IPs before treating a domain as isolated, sees the infrastructure the operator believed was hidden.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>infrastructure</category>
      <category>security</category>
    </item>
    <item>
      <title>Subdomain Takeover: When an Abandoned CNAME Becomes an Attack Vector</title>
      <dc:creator>Davi</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:51:27 +0000</pubDate>
      <link>https://dev.to/roxdavirox/subdomain-takeover-when-an-abandoned-cname-becomes-an-attack-vector-29mb</link>
      <guid>https://dev.to/roxdavirox/subdomain-takeover-when-an-abandoned-cname-becomes-an-attack-vector-29mb</guid>
      <description>&lt;p&gt;A researcher registers an abandoned S3 bucket, waits 72 hours, and starts receiving 8M+ requests, including CloudFormation templates, unsigned binaries, and SSLVPN configurations from Fortune 500 CI/CD pipelines. No exploit was used. The attacker simply showed up where the victim had forgotten to close the door.&lt;/p&gt;

&lt;p&gt;Dangling CNAMEs are not a DNS problem. They are a decommissioning failure. The DNS record keeps working exactly as designed; the fault lies in the process that separates the cloud resource lifecycle from the lifecycle of the record pointing to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CNAME Is Still Active. The Service Is Not. That Gap Is the Vulnerability.
&lt;/h2&gt;

&lt;p&gt;Subdomain takeover requires no technical vulnerability to exploit. It only requires that the cloud resource name be globally unique and claimable after deletion.&lt;/p&gt;

&lt;p&gt;When an organization deletes an app on Heroku, a bucket on S3, or a service on Azure App Service, the resource name returns to the global available pool. Any account on the same provider can register that name immediately. The CNAME record, until it is removed from DNS, keeps routing traffic to the new resource owner.&lt;/p&gt;

&lt;p&gt;EdOverflow's &lt;code&gt;can-i-take-over-xyz&lt;/code&gt; GitHub repository catalogs 76+ services with confirmed takeover paths. Nuclei maintains 72+ detection templates based on per-service fingerprints, with specific error messages like "NoSuchBucket" for S3, "There isn't a GitHub Pages site here." for GitHub Pages, and "No such app" for Heroku. DNS TTL may delay cache propagation by minutes to hours, but once the new resource is active, traffic is already routed.&lt;/p&gt;

&lt;p&gt;The critical distinction: DNS did not fail. The team that decommissioned the cloud resource failed to remove the corresponding DNS record. These two lifecycles are managed by different teams, and the gap between them is the attack surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four Documented Cases That Show the Full Severity Spectrum
&lt;/h2&gt;

&lt;p&gt;The attack vector is identical across all cases. The blast radius depends on how much trust the organization placed in that subdomain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uber / saostatic.uber.com (2016) — complete authentication bypass.&lt;/strong&gt; Researcher Arne Swinnen found that &lt;code&gt;saostatic.uber.com&lt;/code&gt; had a CNAME pointing to a disabled CloudFront distribution. He claimed the distribution under his own account. Uber's SSO set cookies scoped to &lt;code&gt;*.uber.com&lt;/code&gt;; controlling any subdomain meant capturing valid sessions on &lt;code&gt;riders.uber.com&lt;/code&gt;, &lt;code&gt;vault.uber.com&lt;/code&gt;, and &lt;code&gt;partners.uber.com&lt;/code&gt;. HackerOne report #219205 resulted in a $5,000 bounty. A static assets subdomain delivered full account access for any user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SentinelOne S3 research (October 2024 to January 2025) — supply chain compromise.&lt;/strong&gt; Researchers identified approximately 150 abandoned S3 buckets still referenced by active CNAMEs from government agencies, Fortune 500 companies, and open-source projects. They claimed the buckets and monitored for 4 months. The result: 8M+ requests received, including CloudFormation templates, unsigned pre-compiled binaries, SSLVPN configurations, and container images. Zero DNS changes were needed; the victims' own CI/CD pipelines did the work, continuing to pull dependencies from buckets that already belonged to third parties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shopify / s3.shopify.com — CSP bypass.&lt;/strong&gt; The &lt;code&gt;s3.shopify.com&lt;/code&gt; record had a CNAME pointing to an unclaimed S3 bucket. Registering the bucket would allow serving arbitrary content under the &lt;code&gt;shopify.com&lt;/code&gt; origin. Shopify's ecosystem CSP policies trusted &lt;code&gt;*.shopify.com&lt;/code&gt;; any script served from the bucket would execute without restriction in contexts relying on that wildcard. $500 bounty on HackerOne, report #207576.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Snapchat / blog.snapchat.com — phishing with a legitimate-looking URL.&lt;/strong&gt; The &lt;code&gt;blog.snapchat.com&lt;/code&gt; subdomain pointed to a deactivated blog platform instance. Claiming the platform account meant controlling the content served under &lt;code&gt;blog.snapchat.com&lt;/code&gt;. The end user would see a completely valid URL with no visual indicator of compromise. Phishing under a verified domain is categorically more effective than phishing with a lookalike domain, and technically indistinguishable to the average user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Sprawl Is Making This Problem Exponentially Worse
&lt;/h2&gt;

&lt;p&gt;Every sprint that provisions a new cloud service without a corresponding decommissioning task in the backlog is generating future attack surface.&lt;/p&gt;

&lt;p&gt;SentinelOne identified 1,250+ subdomain takeover risks for customers in 2024. A single customer had more than 2,000 exploitable DNS records. IONIX estimates that organizations know only 62% of their actual external exposure; 38% of the attack inventory is completely blind to the teams that should be defending it.&lt;/p&gt;

&lt;p&gt;A corporate apex domain routinely accumulates 25,000+ subdomains spread across infra teams, marketing, developers, and SaaS vendors. Azure alone exposes 14 services with globally unique, claimable namespaces after deletion: App Service, Traffic Manager, CDN, Blob Storage, Container Registry, API Management, SQL Server, Redis Cache, Service Bus, Container Instance, AI Search, Data Lake Store, Virtual Machine, and Cloud Services. &lt;code&gt;can-i-take-over-xyz&lt;/code&gt; catalogs 76+ confirmed services and is continuously updated by the community.&lt;/p&gt;

&lt;p&gt;Ownership fragmentation is the multiplying factor. When no team knows who is responsible for a specific DNS record, no one removes it at the right time. Decommissioned SaaS vendors, subdomains from ended marketing campaigns, and forgotten staging environments form the most common inventory of dangling CNAMEs in organizations with more than 200 people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detection Is a Solved Problem: Most Teams Never Run the Pipeline
&lt;/h2&gt;

&lt;p&gt;The tooling to find dangling CNAMEs at scale exists, is free, and runs in under 2 minutes for most domains.&lt;/p&gt;

&lt;p&gt;The most direct pipeline has 3 chained stages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;subfinder &lt;span class="nt"&gt;-d&lt;/span&gt; target.com | httpx &lt;span class="nt"&gt;-silent&lt;/span&gt; | nuclei &lt;span class="nt"&gt;-tags&lt;/span&gt; takeover
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;subfinder&lt;/code&gt; enumerates subdomains through multiple passive sources. &lt;code&gt;httpx&lt;/code&gt; filters hosts that respond over HTTP and discards silent ones. &lt;code&gt;nuclei&lt;/code&gt; applies 72+ fingerprint templates, identifying the specific error message for each service to confirm the vulnerability.&lt;/p&gt;

&lt;p&gt;Subjack offers parallel verification across 30+ services with customizable fingerprints and separate output by status: confirmed, unresolved, and vulnerable. dnsReaper supports automated periodic scanning with SARIF output, integrating natively into CI/CD security gates. &lt;a href="https://intel.mago.team" rel="noopener noreferrer"&gt;intel.mago.team&lt;/a&gt; monitors dangling CNAMEs continuously as part of the attack surface exposure module.&lt;/p&gt;

&lt;p&gt;The gap is not technical. It is operational: most teams run this pipeline once, in response to an incident, and never incorporate it as a recurring monitoring process. A weekly scheduled scanner would find dangling CNAMEs before any external researcher does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix Happens at Decommissioning Time, Not at Discovery
&lt;/h2&gt;

&lt;p&gt;Reactive scanning finds dangling CNAMEs after the compromise window is already open. The only durable mitigation is making DNS record removal a mandatory step in the cloud resource decommissioning workflow.&lt;/p&gt;

&lt;p&gt;The correct sequence inverts what most teams do in practice: remove the DNS record &lt;em&gt;before&lt;/em&gt; decommissioning the resource, not after. Keeping the resource active while DNS is removed eliminates any takeover window. OWASP documents this sequence inversion as the core of the vulnerability.&lt;/p&gt;

&lt;p&gt;Azure implemented domain verification via TXT records for App Service: the platform requires proof of ownership before accepting a custom domain binding, blocking the vector by design. This approach can be replicated internally with a verification TXT record before CNAME removal, ensuring the domain is not claimable during the interval between DNS removal and resource deletion.&lt;/p&gt;

&lt;p&gt;Wildcards in CNAMEs and CSP directives need to be eliminated. Any subdomain takeover under a wildcard like &lt;code&gt;*.example.com&lt;/code&gt; automatically scales to full session hijack or script injection across the entire ecosystem. DNS ownership requires explicit mapping: each record must have an owning team, a cloud resource ID, and a documented decommissioning contact.&lt;/p&gt;

&lt;p&gt;Every sprint that provisions a Heroku dyno, an Azure App Service, or an Elastic Beanstalk environment without a corresponding decommissioning task is accumulating attack debt. The attacker does not need to break in. They only need to register what you left behind.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cybersecurity</category>
      <category>infosec</category>
      <category>security</category>
    </item>
  </channel>
</rss>
