Chaining SSRF to AWS IMDSv1 Credential Theft

Attackers chain SSRF into AWS metadata endpoints to steal credentials in just three HTTP requests.

Staff Writer · · 9 min read
Cover illustration for “Chaining SSRF to AWS IMDSv1 Credential Theft”
Exploitation Techniques · September 16, 2026 · 9 min read · 2,125 words

Server-side request forgery to AWS IMDSv1 is three or four HTTP requests chained together, each one following mechanically from the last, ending with a full set of working AWS credentials sitting in an attacker's terminal. It is three or four HTTP requests chained together, each one following mechanically from the last, ending with a full set of working AWS credentials sitting in an attacker's terminal. This piece walks through the whole chain: where SSRF hides in ordinary application code, how the metadata endpoint hands over IAM credentials with zero authentication, what an attacker does with those credentials once stolen, and where each link can be broken before it ever gets that far.

SSRF (CWE-918) is what happens when an attacker gets a server to make an HTTP request on their behalf, to a destination they pick. Before cloud computing, that was bad but bounded: an attacker could poke around at internal ports or stumble onto an unauthenticated admin panel. On EC2, though, every instance carries a fixed, always-on HTTP endpoint at 169.254.169.254, the Instance Metadata Service. It answers without a password. It hands back IAM role credentials to whoever asks. That single fact turns a plain bug that lets an attacker steer a server-side request into a direct path into someone's AWS account, and it's why this class of flaw sits on the OWASP Top 10 and keeps getting used against cloud metadata services year after year. Research recorded a 452% jump in SSRF attacks between 2023 and 2024, and in March 2025 the same researchers caught a four-day campaign hitting EC2-hosted sites, systematically trying six parameter names (dest, file, redirect, target, uri, url) against four different IMDS subpaths. The pattern was consistent enough across source IPs that it looked like one operator running a script.

Where SSRF surfaces in common application patterns

Any feature that takes a URL from a user and fetches it on the server is a candidate. That's the plain rule, and it covers more ground than most teams expect.

Image proxies and thumbnail generators. Webhook validators that ping whatever endpoint a caller supplies. Link preview tools that scrape Open Graph tags. PDF renderers that pull in remote assets show how researchers at one security firm got a document-conversion tool to leak credentials: submit HTML with an iframe pointed at 169.254.169.254, and the renderer dutifully fetches it. Basically any API that takes a parameter named url, uri, dest, redirect, target, or file, the same names the March 2025 campaign probed one by one.

Less obvious spots exist too. Internal service calls that forward a header value along without checking it. XML or HTML parsers that resolve external entities. Document conversion pipelines running in the cloud, which inherit whatever network access their host has. A recent SSRF in the Chainlit AI framework let attackers fetch straight from the IMDS endpoint on EC2, a good reminder that third-party libraries inherit the trust boundary of wherever they're deployed. Grafana had a similar issue: CVE-2025-4123, which when chained with the Image Renderer plugin escalates into a full-read SSRF. Fortinet found around 14% of monitored environments were running affected Grafana versions, which says something important: the exposure isn't limited to sloppy in-house code. Mature, widely-used software ships this bug too.

None of these features are broken in any obvious sense. They work exactly as designed. The gap is that nobody checked where the request was actually allowed to go.

How IMDSv1 hands over credentials without any authentication

Diagram: Three Requests From SSRF to Full AWS Credentials. Visualizes: Show the chained HTTP request sequence an attacker uses to extract AWS credentials via SSRF into IMDSv1.

169.254.169.254 is a link-local address, so it's only reachable from inside the instance itself. But "inside the instance" includes every process running on that box, including a web app with an unpatched feature that fetches a remote resource on request. That's the whole trick.

IMDSv1 doesn't ask for anything. No token, no auth header, no challenge-response. A plain GET request is all it takes, and the credential path is three requests deep, each one leading straight into the next:

  • GET /latest/meta-data/iam/security-credentials/ returns the name of the IAM role attached to the instance
  • GET /latest/meta-data/iam/security-credentials/<role-name> returns the credential JSON for that role
  • The JSON contains AccessKeyId, SecretAccessKey, Token, and an Expiration timestamp, which is everything needed to sign authenticated AWS API calls

The metadata service leaks other things too, without a token: user-data scripts (which often have secrets baked into them), the instance identity document, MAC addresses and network config. And the credentials it hands over, while temporary, remain valid for a window of hours. That's plenty of time to enumerate an account, pull data out, or move laterally to something more valuable.

There's also a bypass: if the vulnerable app follows HTTP redirects automatically, an attacker can point it at a domain they control, which then redirects to 169.254.169.254. The request still fires from the app server, on the same network hop, so any domain-based filtering gets skipped entirely. The March 2025 campaign F5 Labs tracked used requests as simple as /?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/. No cleverness required. The endpoint was built to be simple, and that simplicity is the whole problem. A quick way to check exposure from the outside: a token-less curl to the metadata root returns HTTP 200 on IMDSv1 instances, and 401 once IMDSv2 is enforced.

What stolen temporary credentials enable

Once an attacker has the AccessKeyId, SecretAccessKey, and Token, those work from anywhere on the internet. They carry exactly whatever permissions the attached IAM role has, no more and no less. Whatever that role's policy allows is the entire blast radius of the theft.

The usual sequence after theft goes something like this. First, permission probing: try a bunch of IAM operations to map out what the role can actually do. Even the ones that fail get logged in CloudTrail, which matters a lot for detection later. Then service enumeration: list S3 buckets, DynamoDB tables, EC2 resources, maybe Bedrock models, whatever's reachable. From there it's exfiltration or abuse, depending on what the role permits, sometimes with operations shifted to a region that gets less monitoring attention.

AWS's own incident response documentation lays out a case that follows this exact shape. An attacker pulled credentials for a role called webdev via SSRF into IMDSv1, then moved through five stages: tried CreateUser (denied, but logged), got console access without MFA, pivoted over to Bedrock in us-east-2, and invoked the Nova Pro model. Every one of those steps carried the same field in CloudTrail: ec2RoleDelivery: "1.0". That field is the forensic fingerprint of credentials obtained through the older metadata service version, since it confirms no session token was ever involved, and it's the thread that ties a scattered set of log entries into a single incident.

Capital One in 2019 is the reference case for how bad this gets. An attacker used credentials tied to the ISRM-WAF-Role to list and pull data from more than 700 S3 buckets, exfiltrating tens of gigabytes of data and exposing over 100 million customer records. The breach went undetected for an extended period. The fallout included an $80 million fine from the OCC and a $190 million class-action settlement. More recently, in 2025, a ransomware operation dubbed Codefinger used compromised keys to re-encrypt S3 buckets with SSE-C, customer-supplied encryption keys outside AWS's control, which is a stark illustration that the outcome of a credential theft is bounded only by what the attacker decides to do with the access, not by any built-in safety net.

Long-lived keys widen this exposure further. Research has found that a large share of AWS IAM users carry access keys older than a year, That's a separate, parallel exposure path, and it's one that stolen temporary credentials can intersect with or escalate into.

How to detect that the chain was attempted or completed

Start at the application layer. Outbound requests to 169.254.169.254 showing up in app logs or WAF logs are a clear signal, and so is any request from a URL-fetching feature aimed at internal link-local ranges generally.

At the infrastructure layer, the first thing worth checking is which instances still accept IMDSv1 at all:

aws ec2 describe-instances --query "Reservations[*].Instances[*].MetadataOptions"

HttpTokens set to "optional" means IMDSv1 is still accepted, leaving the instance exposed. HttpTokens set to "required" means the basic path from a server-side-request flaw to stolen credentials is closed. Run this across every region, not just the default profile's region, since cross-region blind spots are how the us-east-2 pivot in the AWS incident write-up slipped past. HttpPutResponseHopLimit set above 1 lets containers a hop away from the host reach IMDS, widening the blast radius even with IMDSv2 turned on.

CloudTrail carries the clearest signals. The ec2RoleDelivery: "1.0" field on any event confirms credentials obtained through the older metadata service version, and it stays attached to every API call made using them. Failed IAM calls, like a denied CreateUser, coming from an EC2 assumed-role session are a common early sign of post-theft probing. Console logins without MFA on an AssumedRole session, API activity in regions the workload has no reason touching, and calls to services like Bedrock or SageMaker from a role with no operational need for them all point to compromise.

CloudWatch's MetadataNoToken metric tracks token-less requests hitting the metadata service. It's useful beyond just spotting attacks, too, since it tells a team which instances are still receiving IMDSv1 traffic before they flip everything over to IMDSv2, so nothing breaks in the switch.

Capital One's breach sat undetected for four months. No internal alert fired during the two days the 30GB of data actually left the building. That's the cost of detection gaps at both the app layer and the CloudTrail layer, and it's the clearest argument for building both.

Breaking the chain: code-level controls in the application

The cleanest fix is never letting the request reach 169.254.169.254 in the first place. Get that right, and the metadata endpoint stops mattering as an SSRF target entirely.

On input validation: use an allowlist of permitted destinations. Blocklists lose eventually, because attackers find new bypasses, redirect chains, DNS rebinding, odd encodings, faster than defenders can list them. Resolve the DNS name to an IP before making the request, and check that resolved IP against the allowlist, which stops DNS rebinding attacks where a domain looks fine at validation time and then resolves to 169.254.169.254 moments later. Block link-local ranges, loopback, private RFC 1918 space, and IPv6 link-local ranges outright.

Redirects need their own handling. Turn off automatic redirect-following in whatever HTTP client the URL-fetching feature uses, or re-check the destination after every redirect hop. Skipping this step means the allowlist accomplishes nothing: an attacker points the app at a domain they control, that domain redirects to the metadata IP, and the request fires from the server on that same hop, allowlist entirely bypassed.

Network isolation backs up whatever the code does. Run URL-fetching workers in segments or containers that have no route to 169.254.169.254 at all. Egress filtering enforced at the network layer is a hard control, one that a bug in application logic can't accidentally sidestep the way it can sidestep a code-level check. For document conversion pipelines specifically, strip out or sandbox external resource loading, and never let user-supplied content pass through a converter that resolves network references on its own.

During code review, treat SSRF sinks in common libraries, SSRF sinks in common HTTP client libraries as things that get flagged every time, not just once. The default of following redirects automatically is where most "fixed" SSRF bugs quietly come back.

Breaking the chain: enforcing IMDSv2 and reducing IAM blast radius

IMDSv2 is the infrastructure-level fix, and it closes the door that plain-GET SSRF walks through. It requires a two-step handshake: a PUT request first, to get a session token, then a GET that includes that token in the X-aws-ec2-metadata-token header. Most SSRF bugs can only force a GET. They can't issue the PUT step needed to get a token in the first place, which is why the newer metadata service version shuts down the standard path from a server-side-request flaw to credential theft.

Enforcing it on a single instance:

aws ec2 modify-instance-metadata-options --instance-id i-1234567890abcdef0 --http-endpoint enabled --http-tokens required

At the organization level, Service Control Policies can block new instances from launching with IMDSv1 enabled at all, and help govern IMDSv2 requirements across an account or OU.

IMDSv2 buys more than credential protection, too. It blocks token requests carrying an X-Forwarded-For header, which closes off a path where a misconfigured reverse proxy could otherwise be tricked into relaying a request it shouldn't.

None of this replaces good IAM hygiene. A tightly scoped role limits what stolen credentials can actually do, even if IMDSv1 somehow stays enabled somewhere. Scoped IAM permissions and IMDSv2 enforcement are two separate links in the same chain, and both need breaking. They're two separate links in the same chain, and both need breaking.

Sources

  1. Campaign Targets Amazon EC2 Instance Metadata via SSRF
  2. Incident response guide for AWS CloudTrail investigations – Part 2 | Amazon Web Services
  3. Cloud Metadata Service Exploitation: How IMDSv1 Exposes AWS
  4. Steal EC2 Metadata Credentials via SSRF - Hacking The Cloud
  5. bleepingcomputer.com
  6. cheatsheetseries.owasp.org
  7. blog.christophetd.fr

More in Exploitation Techniques