From SSRF to stolen cloud credentials: the EC2 metadata attack
An SSRF flaw can read EC2 instance-role credentials from the metadata service and replay them from anywhere. Here is the attack, the detection, and why IMDSv2 stops it.
A server-side request forgery bug in a web app is not just a web bug in the cloud. It can become full cloud-credential theft, because the app can be tricked into reading the instance metadata service.
The attack
The attacker abuses an SSRF flaw to make the application fetch http://169.254.169.254/latest/meta-data/iam/security-credentials/. The metadata service returns the EC2 instance role’s temporary credentials. The attacker then replays those credentials, which start with the ASIA prefix, from outside AWS to read S3 and reach whatever the role can touch. This is the Capital-One-class attack. In ATT&CK terms it is T1552.005, Unsecured Credentials: Cloud Instance Metadata API.
Why it works
IMDSv1 requires no session token, so any GET-based SSRF reaches it. Instance roles are also frequently over-privileged, so a stolen role token unlocks far more than the workload needs.
How to detect it
GuardDuty raises InstanceCredentialExfiltration.OutsideAWS when instance-role credentials are used from a non-AWS IP. In CloudTrail, the tell is an ASIA session key used from a source address outside your VPC.
How to contain and fix it
You cannot delete a single temporary session. Instead, attach a deny policy conditioned on aws:TokenIssueTime to invalidate every credential issued before now, and enforce IMDSv2 with HttpTokens required and a hop limit of one. IMDSv2 requires a token obtained by a PUT request that a typical SSRF cannot send. Across the org, require IMDSv2 at launch with an SCP, scope instance roles to least privilege, turn on S3 Block Public Access, and enable CloudTrail data events for sensitive buckets.
Practice it
We built this scenario in GraphLattice Range, including the session-revocation call that catches teams who try to reset a key that does not exist.