Exploitation to Exfiltration: Chaining SSRF to Compromise AWS IMDS
Server-Side Request Forgery is dangerous. When combined with legacy cloud metadata services, it’s catastrophic. Here is a technical breakdown of how attackers pivot from a simple SSRF to full cloud account takeover.
Server-Side Request Forgery (SSRF) has historically been viewed as a high-severity, but somewhat limited, vulnerability. In an on-premise environment, an SSRF allows an attacker to map internal networks or perhaps bypass a firewall to hit an internal admin panel.
But in the cloud, SSRF is the ultimate skeleton key.
The reason? The Instance Metadata Service (IMDS).
If an attacker can trick your EC2 instance into making an HTTP request to the magic IP address 169.254.169.254, they aren't just mapping your internal network—they are stealing your cloud IAM credentials. Here is the technical breakdown of how this attack chain works, and exactly how you fix it using Terraform.
The Vulnerability: Blind SSRF
Consider a web application that takes a user-supplied URL to fetch a remote image for a profile avatar:
@app.route('/fetch_avatar')
def fetch_avatar():
url = request.args.get('url')
# Vulnerable: No validation on the URL
response = requests.get(url)
return response.content
If a user supplies http://example.com/image.png, the server fetches the image. But what if the attacker supplies the AWS IMDS IP address?
The Exploit: Hitting IMDSv1
AWS created the Instance Metadata Service (IMDS) so that applications running on an EC2 instance could seamlessly retrieve metadata about themselves, including their dynamically generated IAM role credentials.
In IMDSv1, this service requires zero authentication. It simply relies on a GET request originating from the EC2 instance itself.
The attacker submits the following payload to the vulnerable endpoint:
GET /fetch_avatar?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
The server, obediently executing the SSRF, reaches out to the IMDS. The IMDS sees a request coming from the EC2 instance and responds with the name of the IAM role attached to the machine:
prod-web-server-role
The attacker then issues a second request to steal the actual temporary STS credentials for that role:
GET /fetch_avatar?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/prod-web-server-role
The response is catastrophic:
{
"Code" : "Success",
"LastUpdated" : "2026-09-08T10:00:00Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAX...",
"SecretAccessKey" : "K8s3...",
"Token" : "IQoJb3JpZ2luX2VjE...",
"Expiration" : "2026-09-08T16:00:00Z"
}
The attacker now takes these credentials, configures them in their local AWS CLI, and assumes the identity of the prod-web-server-role. If that role has overly permissive policies (e.g., s3:GetObject on all buckets), the attacker immediately begins exfiltrating sensitive data.
This exact attack chain was responsible for the infamous 2019 Capital One breach, which compromised the data of 106 million customers.
The Remediation: Enforcing IMDSv2
AWS responded to this attack vector by releasing IMDSv2.
IMDSv2 fundamentally breaks this attack chain by introducing session-oriented requests. Before you can request metadata, you must first execute a PUT request with a specific header (X-aws-ec2-metadata-token-ttl-seconds) to generate a temporary token.
Because standard SSRF vulnerabilities (like the requests.get() example above) typically only allow attackers to control the URL and not the HTTP method (PUT) or the specific headers, IMDSv2 completely neutralizes the attack.
Implementing IMDSv2 via Terraform
Enforcing IMDSv2 is not the default on older EC2 instances. You must explicitly require it in your Infrastructure as Code.
Here is the Terraform configuration to enforce IMDSv2 on an aws_instance:
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.web_profile.name
# The critical block to neutralize SSRF attacks
metadata_options {
http_endpoint = "enabled"
# Force IMDSv2
http_tokens = "required"
# Prevent the token from being forwarded in a network proxy
http_put_response_hop_limit = 1
}
tags = {
Name = "SecureWebServer"
}
}
The Takeaway
SSRF vulnerabilities will always exist as long as applications need to interact with external URIs. The goal of cloud security is not to perfectly prevent application vulnerabilities, but to isolate the blast radius when they occur. Enforcing IMDSv2 across your entire AWS fleet is the highest ROI security fix you can deploy today.
Is your cloud infrastructure vulnerable to metadata exfiltration? Contact NadahWeb's Cloud Security Architecture team for a comprehensive architecture review.
Need expert help with Cloud Security?
Engage NadahWeb’s elite security team. Free 30-minute strategic consultation.