SSRF: The Complete Practical Guide to Server-Side Request Forgery
SSRF Cloud Metadata Abuse (AWS, GCP, Azure)
Stealing cloud credentials via SSRF: the instance metadata service, AWS IMDSv1 vs IMDSv2 token handshake, GCP and Azure metadata, and why IMDSv2 raises the bar.
Published
The single highest-impact thing an SSRF can do is reach the cloud instance metadata service and walk away with credentials. Almost every cloud instance can query an internal endpoint to learn its own identity, and that identity usually includes temporary keys for the role the server runs as. An SSRF that reaches the metadata endpoint turns one fetch feature into credential theft, and those credentials often unlock far more than the single box.
What the metadata service is
Cloud instances need to know things about themselves: their region, their name, and critically the credentials for the IAM role or service account they were launched with. The provider exposes this over plain HTTP at a link-local address that is only reachable from the instance itself, commonly 169.254.169.254. No authentication is needed from on-box, because the design assumed only the instance could reach it. SSRF breaks that assumption by making the instance query it for you.
AWS IMDSv1 versus IMDSv2
AWS has two versions, and the difference is the whole game.
IMDSv1 is a plain GET. No headers, no handshake. Walk the path to the role, then read its credentials:
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>The second response is JSON with AccessKeyId, SecretAccessKey, and a session Token. A bare URL-fetch SSRF can do this directly, which is why IMDSv1 is so dangerous.
IMDSv2 requires a token handshake. You first PUT to get a token, sending a TTL header, then send that token back in a header on every read:
PUT http://169.254.169.254/latest/api/token
Header: X-aws-ec2-metadata-token-ttl-seconds: 21600
-> returns a token string
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
Header: X-aws-ec2-metadata-token: <token>This matters enormously for SSRF: a feature that only fetches a URL usually cannot issue a PUT or set custom headers, so it cannot complete the handshake. IMDSv2 does not fix SSRF, but it makes the easy credential grab fail.
GCP and Azure metadata
Other clouds gate the metadata service behind a required header, which has the same SSRF-blunting effect as IMDSv2.
GCP requires the Metadata-Flavor: Google header, and the service-account token lives at a known path:
GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
Header: Metadata-Flavor: GoogleAzure requires the Metadata: true header and a resource parameter:
GET http://169.254.169.254/metadata/identity/oauth2/token?api-version=2021-02-01&resource=https://management.azure.com/
Header: Metadata: trueFor both, a URL-only SSRF that cannot add headers will not get a token. An SSRF that can inject headers, or a flexible fetcher, still can.
Why the required header matters
The recurring theme is headers. IMDSv1 needs none, so a bare fetch wins. IMDSv2, GCP, and Azure all demand a header a simple URL fetch cannot add. So when you assess an SSRF for metadata reach, the key question is not just "can it reach 169.254.169.254" but "can it set a method and headers." A link-preview that only takes a URL is often stuck at IMDSv1-style targets, while an SSRF in a feature that forwards your headers is far more dangerous.
What you do with stolen credentials
Temporary cloud credentials are the keys to the identity the server runs as. With them you can call the provider's APIs as that role: list and read storage buckets, enumerate other resources, sometimes escalate to broader permissions, and pivot into the cloud control plane. A set of credentials scoped to "one web server" frequently turns out to reach shared data or other services, which is how a single SSRF becomes an account-level breach. The next step from here is covered in SSRF to RCE and compromise.
Defensively, the answer is IMDSv2 with a metadata hop limit of 1, workload identity over long-lived keys, and tightly scoped roles so a leaked credential is short-lived and reaches little. Try the metadata chain on a free live target.
← Back to SSRF: The Complete Practical Guide to Server-Side Request Forgery