SSRF to AWS Metadata (IMDSv2): What Still Pays in Bug Bounty
You find a URL fetch. Classic move: hit http://169.254.169.254/. On older fleets that still spoke IMDSv1, a bare GET returned IAM role credentials and the report wrote itself. Most serious AWS shops flipped on IMDSv2. The endpoint did not vanish — the handshake changed.
I still chase metadata through SSRF in 2026. The payouts moved from “open IMDS” to “can you complete the token dance from the vulnerable server?”
Why hunters care
Instance metadata holds temporary credentials for the attached role. If your SSRF runs on an EC2 host (or something that can reach the link-local address), that role becomes your blast radius: S3, Secrets Manager, internal APIs — whatever the role allows.
Authorized testing only. Pull credentials from your lab role or stop at proving the token + metadata path. Do not exfiltrate production secrets into a public writeup.
IMDSv1 vs IMDSv2 in one minute
- IMDSv1:
GET http://169.254.169.254/latest/meta-data/— no session header. - IMDSv2: first
PUTto/latest/api/tokenwithX-aws-ec2-metadata-token-ttl-seconds, then reuseX-aws-ec2-metadata-tokenon later GETs. Many environments also set a hop limit of 1 so containers and SSRF proxies cannot reach IMDS.
If your SSRF only supports GET, IMDSv2 often blocks you cold. If it lets you set method and headers, keep going.
A practical probe order
- Confirm SSRF: hit a collaborator or an in-scope host you control. Note redirects, DNS rebinding filters, and scheme allowlists.
- Try link-local and common aliases:
169.254.169.254,[::ffff:a9fe:a9fe], decimal/hex IP tricks the parser might normalize later. - Attempt the IMDSv2 token
PUT. Watch for hop-limit failures (empty response) versus application blocks (4xx from the app). - If you get a token, request
/latest/meta-data/iam/security-credentials/then the role name — on a disposable lab account.
Partial wins still matter. “SSRF can speak to IMDS but hop limit stops tokens” is useful for defenders and sometimes still accepted as medium when paired with internal network reach.
Filters you will meet
Apps rewrite hostnames, block literal 169.254, or only allow https://. Bypass research stays ethical: open redirects chained into SSRF, DNS that resolves external then flips internal, and URL parsers that disagree with the HTTP client. Document which layer failed — app WAF, metadata hop limit, or IMDS itself.
Writing the report
Lead with the fetch sink (parameter, webhook, PDF renderer, import-from-URL). Show the token request succeeding or the precise IMDSv2 failure. Explain blast radius from the role policy if you safely inspected it in a sandbox. Recommend IMDSv2 + hop limit 1, egress controls, and denying link-local from app workers.
Quick defensive asks
- Require IMDSv2; set
http-put-response-hop-limitto 1 on instances. - Block
169.254.169.254and equivalent forms at the egress proxy for app tiers. - Prefer VPC endpoints and least-privilege instance roles over “wide admin on the box.”
SSRF into cloud metadata is less “one GET” than it used to be. Treat IMDSv2 as a puzzle with method, headers, and network hops — that is where the remaining bugs hide.