Cloud providers expose a special HTTP endpoint at 169.254.169.254 — a link-local address that is only accessible from within the cloud instance itself. Applications running on the instance use it to retrieve instance configuration, tags, and — critically — IAM credentials for the role assigned to the instance.
Step 1: Fetch http://169.254.169.254/latest/meta-data/iam/security-credentials/
Response: MyEC2Role — the name of the IAM role attached to this instance.
Step 2: Fetch http://169.254.169.254/latest/meta-data/iam/security-credentials/MyEC2Role
Response (JSON): AccessKeyId, SecretAccessKey, Token, Expiration
s3:GetObject on any bucket, the attacker can download all objects from those buckets. If it has broader permissions — EC2 management, RDS access, Lambda invocation — the attacker has those too. This is exactly what happened in Capital One.AWS introduced Instance Metadata Service v2 (IMDSv2) in 2019, which requires a PUT request to get a session token before making metadata requests. This stops simple SSRF (which can only make GET requests). However, IMDSv2 is optional, and many older instances still run IMDSv1. Capital One used IMDSv1.