Server-Side Request Forgery (SSRF) remains one of the most critical threats to cloud-native applications. In an AWS EC2 environment, a successful SSRF vulnerability allows an attacker to trick your web server into making unauthorized requests to internal resources, most notably the Instance Metadata Service (IMDS). If your instance uses the legacy IMDSv1, an attacker can extract temporary IAM credentials, leading to full account takeover. You must understand how to detect these gaps and transition your infrastructure to the more secure IMDSv2 to protect your sensitive data.
By the end of this guide, you will know how to identify SSRF entry points, enforce IMDSv2 across your fleet, and configure network egress rules that block malicious lateral movement. We will focus on practical AWS CLI commands and security configurations that you can apply to production environments today.
TL;DR — SSRF exploits in AWS typically target the 169.254.169.254 metadata endpoint. To stop this, you must disable IMDSv1, enforce IMDSv2 with a session-oriented token, and set the "Hop Limit" to 1 to prevent container-based bypasses. Use AWS Service Control Policies (SCPs) to ensure no new instances are launched with legacy metadata settings.
Table of Contents
- Understanding SSRF and AWS Instance Metadata
- When SSRF Becomes a Critical Threat
- Step-by-Step Implementation: Enforcing IMDSv2
- Common Pitfalls and IMDSv2 Bypasses
- Advanced Detection and Prevention Tips
- Frequently Asked Questions
Understanding SSRF and AWS Instance Metadata
💡 Analogy: Imagine a high-security office building where the receptionist (your Web Server) is allowed to fetch documents from the back office (Internal Services) for guests. An SSRF attack is like a guest giving the receptionist a request that says, "Go to the CEO's private safe and bring me the master keys." Because the receptionist trusts the request is legitimate and has internal access, they inadvertently hand over the keys to the attacker.
In the context of AWS, the "master keys" are often stored at http://169.254.169.254/latest/meta-data/iam/security-credentials/. This endpoint provides temporary AWS Access Keys, Secret Keys, and Session Tokens associated with the IAM Role assigned to the EC2 instance. In the legacy Instance Metadata Service Version 1 (IMDSv1), access is granted via a simple GET request. This makes it trivial for an attacker who finds a URL-parsing vulnerability in your application to exfiltrate these credentials.
IMDSv2 introduces a session-oriented defense. It requires a PUT request to generate a temporary token, which must then be included in the header of any subsequent GET requests. Because most SSRF vulnerabilities only allow GET or POST requests without custom headers, IMDSv2 effectively neutralizes the primary vector for credential theft in EC2 environments. You are essentially adding a "handshake" that an external attacker cannot easily replicate through a blind request forgery.
When SSRF Becomes a Critical Threat
SSRF vulnerabilities usually appear in application features that require fetching external data. If you have a web application that allows users to upload an image via a URL, preview a website, or integrate with webhooks, you are at risk. Attackers will input http://169.254.169.254/latest/meta-data/ into these fields to see if the server returns internal metadata. This is a common finding during penetration testing and security audits, often resulting in a "High" or "Critical" severity rating.
Consider a PDF generation service that takes a URL and converts it into a document. If the underlying library (like wkhtmltopdf or similar) isn't restricted, it can be commanded to fetch the EC2 metadata and embed it directly into the PDF. Similarly, internal microservices that lack authentication are primary targets. If an attacker can reach your internal VPC endpoints via SSRF, they can bypass firewalls that only protect the perimeter, accessing databases or internal APIs that assume "inside the network" means "safe."
You should also be wary of "Blind SSRF." In this scenario, the server doesn't return the content of the request to the user, but the request still happens. An attacker might use this to scan your internal network (port scanning) or trigger internal administrative actions. In cloud environments, the metadata service is the highest-value target because it facilitates the jump from a web vulnerability to a full cloud infrastructure breach, as seen in the infamous 2019 Capital One data breach.
Step-by-Step Implementation: Enforcing IMDSv2
Step 1: Detect IMDSv1 Usage
Before enforcing IMDSv2, you should identify which instances are still relying on IMDSv1. AWS provides a CloudWatch metric called MetadataNoToken. If this metric is greater than zero, your application or its SDKs are still using the legacy method. You can use the AWS CLI to check the current configuration of an instance:
aws ec2 describe-instances \
--instance-ids i-0123456789abcdef0 \
--query "Reservations[*].Instances[*].MetadataOptions"
Step 2: Transition an Existing Instance to IMDSv2
You can modify a running instance to require tokens (IMDSv2). It is highly recommended to test this in a staging environment first, as older AWS SDKs might fail if they don't support token-based fetching. Run the following command to enforce IMDSv2 and set the hop limit to 1:
aws ec2 modify-instance-metadata-options \
--instance-id i-0123456789abcdef0 \
--http-tokens required \
--http-endpoint enabled \
--http-put-response-hop-limit 1
Step 3: Enforce IMDSv2 Globally via Service Control Policy (SCP)
To prevent developers from accidentally launching insecure instances, you should apply an SCP at the AWS Organizations level. This policy denies the ec2:RunInstances action unless the metadata tokens are set to required. This ensures that every new instance launched in your environment is secure by default.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
}
]
}
Common Pitfalls and IMDSv2 Bypasses
⚠️ Common Mistake: Setting the http-put-response-hop-limit too high in containerized environments. If you run Docker on EC2, a hop limit of 2 or more allows a container to reach the metadata service, potentially exposing the host's IAM role to every container on that instance.
One common pitfall is the "Hop Limit" configuration. In a standard EC2 instance, the IP packet for a metadata request has a Time-to-Live (TTL) or hop limit. If you set this limit to 1, the packet cannot cross a network bridge. Since Docker and Kubernetes use network bridging to connect containers to the host network, a hop limit of 1 prevents containers from accessing the EC2 metadata service directly. This forces you to use IAM Roles for Service Accounts (IRSA) or ECS Task Roles, which follow the principle of least privilege better than sharing the host's role.
Another issue arises when applications use outdated AWS SDKs. Older versions of the Java or Python SDKs might not automatically handle the IMDSv2 token handshake. If you enforce IMDSv2 without updating these libraries, your application will lose access to its IAM credentials, causing "Access Denied" errors or timeout failures. Always verify that your software stack is compatible with IMDSv2 before flipping the switch to "Required" in production.
Finally, don't forget about WAF (Web Application Firewall) bypasses. While a WAF can block requests containing "169.254.169.254", attackers can use DNS rebinding or decimal/hexadecimal IP encodings (e.g., http://2852039166/) to circumvent simple string-matching rules. You must treat IMDSv2 as your primary defense and the WAF as a secondary, "defense-in-depth" layer.
Advanced Detection and Prevention Tips
Beyond IMDSv2, you should implement strict egress filtering using Security Groups or Network ACLs. If your application only needs to talk to specific external APIs, deny all other outbound traffic on ports 80 and 443. This prevents the "Request" part of Server-Side Request Forgery from ever reaching a malicious external callback server (often used for OAST detection like Burp Collaborator).
Use AWS GuardDuty to monitor for suspicious activity. GuardDuty has specific findings like UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration. This alert triggers when credentials generated via IMDS are used from an IP address outside of the AWS infrastructure. This is a definitive signal that an SSRF attack has occurred and credentials have been stolen. When I monitored a fleet of 500+ instances during a migration, this alert was our "safety net" for identifying misconfigured proxy servers.
📌 Key Takeaways
- IMDSv1 is insecure because it allows simple GET requests to fetch IAM credentials.
- IMDSv2 requires a session token (via PUT), stopping most SSRF attacks.
- Set
http-put-response-hop-limitto 1 for container hosts to isolate containers from host metadata. - Use CloudWatch metrics (
MetadataNoToken) to track legacy usage before cutover. - Apply SCPs to ensure all new infrastructure is IMDSv2-compliant by default.
Frequently Asked Questions
Q. What is SSRF in AWS?
A. SSRF in AWS is a vulnerability where an attacker forces an EC2 instance to make requests to the internal Metadata Service (169.254.169.254). This is typically used to steal IAM role credentials or scan internal VPC resources that are not exposed to the public internet.
Q. How to enforce IMDSv2 on existing EC2 instances?
A. You can enforce IMDSv2 using the AWS CLI command aws ec2 modify-instance-metadata-options with the --http-tokens required flag. This change takes effect immediately without requiring a reboot, but you should ensure your application SDKs support tokens first.
Q. How does SSRF exploit instance metadata?
A. Attackers exploit SSRF by providing a URL like http://169.254.169.254/latest/meta-data/iam/security-credentials/[role-name] to a vulnerable application feature. The server fetches the URL and returns the temporary security tokens to the attacker, allowing them to impersonate the EC2 instance's IAM role.
Post a Comment