Exploit Research: SSRF-to-IMDS Credential Theft Chains in AWS, Azure, and GCP
SSRF vulnerabilities that reach cloud metadata services give attackers temporary cloud credentials with the power of the instance's IAM role. Here's the full exploitation chain across AWS, Azure, and GCP — and what actually stops it.
Server-Side Request Forgery (SSRF) vulnerabilities that can reach cloud Instance Metadata Services (IMDS) are among the highest-impact web application vulnerabilities in cloud-hosted environments. The attacker needs only an SSRF that can hit 169.254.169.254 (AWS/GCP) or 169.254.169.254/fd00:ec2::254 (AWS IPv6) or 169.254.169.254 (Azure) — and they receive temporary cloud credentials tied to the instance's IAM role.
AWS: IMDSv1 vs IMDSv2
The AWS IMDS vulnerability is well-documented since the Capital One breach (2019), but IMDSv1 is still widely deployed. IMDSv1 allows any unauthenticated HTTP GET to http://169.254.169.254/latest/meta-data/iam/security-credentials/ to return temporary credentials. An SSRF vulnerability that can make outbound HTTP requests is sufficient.
IMDSv2 requires a PUT request with a TTL header to obtain a session token, and that token must be included in subsequent GET requests. This breaks naive SSRF exploitation because most SSRF payloads only support GET requests. However, SSRF vulnerabilities that support method control — such as those exploited via XML XXE, PDF generators, or redirect-following HTTP clients — can still reach IMDSv2.
| IMDS version | Required attacker capability | Mitigated by standard SSRF? | Still exploitable via? |
|---|---|---|---|
| IMDSv1 | HTTP GET to 169.254.169.254 | No — any SSRF works | Any SSRF vulnerability |
| IMDSv2 | HTTP PUT + TTL header, then GET with session token | Yes — GET-only SSRF blocked | XXE, PDF renderers, redirect chains, HTTP libraries with PUT support |
Azure: IMDS Without IMDSv2 Equivalent
Azure IMDS (169.254.169.254/metadata/instance) requires a Metadata: true header, which is not sent by default browser-initiated requests (CSRF protection). However, SSRF vulnerabilities executing server-side — via curl, urllib, Axios, or any HTTP library — can trivially set arbitrary headers. Azure does not have an IMDSv2 equivalent with session token requirements.
The Azure IMDS returns the managed identity OAuth token via GET http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/ with the Metadata: true header — valid as a Bearer token for Azure Resource Manager API calls.
GCP: Service Account Token via Metadata Server
GCP's metadata server (metadata.google.internal or 169.254.169.254) returns service account OAuth tokens via GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token with the X-Google-Metadata-Request: True header. Like Azure, no session token pre-authentication step is required — a single SSRF with header control is sufficient.
Detection Logic
Detection for SSRF-to-IMDS exploitation operates at two layers: WAF detection of SSRF payloads targeting IMDS ranges, and cloud-layer detection of anomalous credential use.
- WAF rule: block outbound requests containing 169.254.169.254, metadata.google.internal, or fd00:ec2::254 in URL or redirect targets
- ModSecurity rule: detect SSRF payloads in request parameters targeting RFC 3927 link-local addresses
- AWS CloudTrail: alert on AssumeRole or GetCallingIdentity from IPs outside the organisation's known IP ranges
- AWS GuardDuty: InstanceCredentialExfiltration.OutsideAWS finding — detects IMDS credentials used from non-AWS IPs
- GCP Security Command Center: alert on service account token use from unexpected source IPs
- Azure Monitor: alert on managed identity token use from non-Azure infrastructure IPs
Remediation Priority
- AWS: enforce IMDSv2 on all EC2 instances — set http-tokens=required at the account level via SCP
- Apply instance metadata hop limit of 1 (http-put-response-hop-limit=1) to prevent SSRF via intermediate hops
- Audit IAM role permissions attached to EC2/VM instances — apply least-privilege to limit blast radius
- WAF: deploy SSRF-specific rules blocking link-local address ranges (169.254.0.0/16, 10.0.0.0/8 internal ranges)
- Validate all URL-accepting application inputs against an allowlist of permitted schemes and host ranges