Cloud Security Wire
AWS Azure GCP RSS
AWSAzureGCPMulti-Cloud CVE Analysis critical

SSRF to Cloud Metadata: IMDSv1 vs IMDSv2 and Real-World Exploitation

A technical deep-dive into Server-Side Request Forgery attacks targeting cloud metadata services — how IMDSv1 enables credential theft with a single HTTP request, what IMDSv2 actually protects against, and documented real-world exploitation chains.

By Cloud Security Wire · ·
#ssrf#imds#metadata-service#credential-theft#capital-one
Critical Severity

This issue has been assessed as critical severity. Review affected configurations immediately.

Server-Side Request Forgery (SSRF) vulnerabilities have become one of the most consequential attack classes in cloud environments. What would be a moderate SSRF in a traditional network — access to internal services on RFC 1918 ranges — becomes a critical credential theft in cloud environments because every hyperscaler exposes a metadata service at a well-known link-local address that returns short-lived credentials for the instance’s attached identity.

The Metadata Service Addresses

Each major cloud provider exposes IMDS at a fixed link-local address:

ProviderIMDS AddressCredential Path
AWS169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
Azure169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01
GCPmetadata.google.internal / 169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
Alibaba Cloud100.100.100.200/latest/meta-data/ram/security-credentials/<role>

These addresses are non-routable from the internet and not reachable from other instances within a VPC — they’re only accessible from the instance itself. An SSRF vulnerability in an application running on the instance is a bridge from the internet to these endpoints.

IMDSv1: Single-Request Credential Theft

AWS’s first-generation IMDS (IMDSv1) is a simple HTTP service: no authentication, no headers required. A single GET request returns credentials:

GET http://169.254.169.254/latest/meta-data/iam/security-credentials/

This returns the role name(s) attached to the instance. A second request retrieves temporary credentials:

GET http://169.254.169.254/latest/meta-data/iam/security-credentials/MyEC2Role

Response:

{
  "Code": "Success",
  "Type": "AWS-HMAC",
  "AccessKeyId": "ASIA...",
  "SecretAccessKey": "wJalrXUtnFEMI...",
  "Token": "IQoJb3JpZ2luX2Vj...",
  "Expiration": "2026-05-06T18:00:00Z"
}

These are fully functional AWS API credentials valid for the expiration time (typically 1–6 hours). An attacker who can trigger an SSRF to these two endpoints has the equivalent of a ~/.aws/credentials file for the instance’s IAM role — from anywhere on the internet.

The Capital One Breach (2019)

The most documented cloud SSRF breach. A misconfigured Web Application Firewall (AWS WAF deployed on EC2) allowed SSRF due to an overly permissive rule. The attacker:

  1. Exploited an SSRF via the WAF’s proxy functionality
  2. Queried IMDSv1 to retrieve credentials for the EC2 instance role
  3. Used those credentials to list and download 106 million customer records from S3

The instance role had s3:GetObject on sensitive buckets — a broad permission that wouldn’t flag monitoring. The SSRF was the entry point; the excessive IAM permissions were the blast radius amplifier.

IMDSv2: Token-Based Mitigation

AWS introduced IMDSv2 in 2019 as a defense-in-depth measure. IMDSv2 requires a PUT request to obtain a session token before making GET requests:

# Step 1: Get a session token (requires PUT method, sets TTL)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# Step 2: Use token in subsequent requests
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  "http://169.254.169.254/latest/meta-data/iam/security-credentials/MyEC2Role"

Why this matters for SSRF: Many SSRF vulnerabilities exploit URL-fetching functionality that only supports GET requests — a fetch() call, an image proxy, an XML parser following xinclude or external entity references. These cannot issue the required PUT request with a custom header to obtain the token. IMDSv2 breaks the one-request exploitation chain.

IMDSv2 Bypasses

IMDSv2 is not a panacea:

  1. SSRF with full HTTP control — If the SSRF allows arbitrary HTTP methods and custom headers (e.g., a server-side proxy, a misconfigured reverse proxy), IMDSv2 provides no protection.

  2. Open redirects on the instance — If an application on the instance has an open redirect that allows redirecting to http://169.254.169.254/, and the SSRF vulnerability follows redirects, the two-step exchange can be replayed through the redirect chain.

  3. Cloud function SSRF — Lambda functions, Azure Functions, and Cloud Run don’t have the same IMDS structure as VMs, but Lambda’s internal runtime API (AWS_CONTAINER_CREDENTIALS_FULL_URI) is a similar vector.

GCP Metadata Service

GCP’s IMDS at metadata.google.internal requires a specific header to prevent browser-based attacks:

curl -s -H "Metadata-Flavor: Google" \
  "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"

The Metadata-Flavor: Google header requirement is analogous to Azure’s Metadata: true — it’s a single custom header that’s easy to set in most SSRF contexts but prevents casual browser navigation or basic redirect-following attacks.

GCP also exposes sensitive data beyond tokens:

# SSH public keys
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/project/attributes/ssh-keys

# Startup scripts (often contain secrets)
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/attributes/startup-script

Startup scripts frequently contain environment variables, API keys, and database URLs, making the GCP metadata endpoint even higher value than just the service account token.

Detection

AWS: CloudTrail + GuardDuty

GuardDuty has a dedicated finding type: UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS. This fires when instance credentials are used from an IP address outside AWS infrastructure — the most reliable signal of SSRF-driven credential theft.

aws guardduty list-findings \
  --detector-id <detector-id> \
  --finding-criteria '{"Criterion":{"type":{"Eq":["UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS"]}}}'

Honeytokens

Deploy canary credentials using Canarytokens or thinkst canaries embedded in the metadata service (via UserData or instance tags). Any usage of these credentials immediately alerts — with source IP and full API call details.

Remediation Checklist

  1. Enforce IMDSv2 on all EC2 instances:
aws ec2 modify-instance-metadata-options \
  --instance-id i-1234567890abcdef0 \
  --http-tokens required \
  --http-put-response-hop-limit 1

The --http-put-response-hop-limit 1 ensures the token cannot be obtained from a container inside the instance — essential for preventing container escape chains.

  1. Enforce via launch template:
{
  "MetadataOptions": {
    "HttpTokens": "required",
    "HttpEndpoint": "enabled",
    "HttpPutResponseHopLimit": 1
  }
}
  1. Apply IMDSv2 enforcement as an SCP:
{
  "Effect": "Deny",
  "Action": "ec2:RunInstances",
  "Resource": "arn:aws:ec2:*:*:instance/*",
  "Condition": {
    "StringNotEquals": {
      "ec2:MetadataHttpTokens": "required"
    }
  }
}
  1. Use IMDSv2 enforcement in Terraform:
resource "aws_instance" "secure" {
  ...
  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = "required"
    http_put_response_hop_limit = 1
  }
}
  1. Apply least-privilege instance roles — the SSRF blast radius is proportional to the instance role’s permissions. An instance role with read-only access to a specific S3 prefix is dramatically less impactful than one with broad access.

SSRF to IMDS is a class of vulnerability that will continue to exist as long as web applications proxy external URLs. IMDSv2 significantly raises the bar for exploitation, but defense in depth — minimal instance permissions, network-level IMDS restriction where possible, and real-time credential use monitoring — is the complete control set.

← All Analysis Subscribe via RSS