EC2 Instances Without IMDSv2 Enforcement Let SSRF Steal IAM Role Credentials
Leaving IMDSv1 permitted on an EC2 instance turns an ordinary SSRF bug into a route to the instance's live IAM role credentials. Here is the exact misconfiguration, the diagnosis, the fix and the rollback boundary.
Operational summary
At a glance
- Symptom
- An EC2-hosted application begins making outbound requests to attacker-controlled or attacker-redirected URLs after a server-side request forgery (SSRF) flaw in a feature that fetches…
- Likely cause
- The instance's MetadataOptions.HttpTokens value is set to "optional", so both IMDSv1 (tokenless) and IMDSv2 (token-bound) requests are accepted.
- Impact
- The observable consequence is that an attacker who can trigger the SSRF path obtains valid temporary AWS credentials scoped to the instance's IAM role without any AWS-side authentication…
- Verification signal
- Validation must confirm both that IMDSv2 is enforced and that the running application still obtains credentials successfully.aws ec2 describe-instances --instance-ids i-0123456789abcdef0 --query "Reservations[].Instances[].MetadataOptions.HttpTokens"Pass condition: the returned value is…
- Safe correction
- Enforce IMDSv2 on the instance, setting a hop limit that survives the extra network hop introduced by a container bridge if the workload runs containers on top of…
- Rollback or recovery
- If the application cannot obtain credentials after enforcement, visible as authentication failures in application logs immediately after the change, revert the specific instance rather than leaving the workload…
Symptom
An EC2-hosted application begins making outbound requests to attacker-controlled or attacker-redirected URLs after a server-side request forgery (SSRF) flaw in a feature that fetches user-supplied URLs is exploited. Shortly afterwards, unfamiliar API calls appear in the account’s activity history, made using the instance’s own IAM role rather than any human or service identity that should have generated them.
False Assumption
The team assumed that scoping the EC2 instance’s IAM role tightly under least privilege was sufficient protection against an application-layer bug, and that the instance metadata service was authenticated in the same way as the rest of the AWS API surface. Neither assumption holds under the instance’s actual configuration: the metadata endpoint at 169.254.169.254 still answers plain, tokenless requests because the legacy Instance Metadata Service version 1 (IMDSv1) protocol remains permitted. Some teams also assume newly launched instances default to enforcing IMDSv2 automatically. That default depends on launch method, account-level settings and the age of the source AMI, and is not something this article can confirm for a specific account without checking the live configuration directly.
Root Cause
The instance’s MetadataOptions.HttpTokens value is set to “optional”, so both IMDSv1 (tokenless) and IMDSv2 (token-bound) requests are accepted. Under IMDSv1, any process capable of issuing an HTTP GET to the link-local metadata address – including a request relayed through a vulnerable application feature – can read /latest/meta-data/iam/security-credentials/<role-name> and receive the instance role’s current temporary access key, secret key and session token. The application-layer SSRF flaw is the entry point, but the exposure is only exploitable because the instance never requires the session-bound IMDSv2 token that a simple tokenless SSRF relay cannot supply.
Impact
The observable consequence is that an attacker who can trigger the SSRF path obtains valid temporary AWS credentials scoped to the instance’s IAM role without any AWS-side authentication weakness. From that point they can call any AWS API action the role permits, for as long as the credentials remain valid, enabling data access, further reconnaissance or lateral movement inside the account. The blast radius is bounded by the IAM role’s permissions rather than by the SSRF bug itself, which is why a “well-scoped” role reduces but does not remove the exposure.
Diagnosis
Confirm the current metadata configuration on the affected instance before changing anything.
aws ec2 describe-instances
--instance-ids i-0123456789abcdef0
--query "Reservations[].Instances[].MetadataOptions"
Expected evidence: HttpTokens returns “optional” rather than “required”. Separately review the attached role to establish the actual blast radius before deciding on urgency.
aws iam list-attached-role-policies --role-name <instance-role-name>
| Property | IMDSv1 | IMDSv2 |
|---|---|---|
| Authentication | None; plain GET | Session token from a prior PUT request required |
| Basic SSRF relay risk | High | Substantially reduced; most relays cannot perform the required PUT plus custom header |
| Enforced by | Fallback default | MetadataOptions.HttpTokens = required |
Correction
Enforce IMDSv2 on the instance, setting a hop limit that survives the extra network hop introduced by a container bridge if the workload runs containers on top of the EC2 host.
aws ec2 modify-instance-metadata-options
--instance-id i-0123456789abcdef0
--http-tokens required
--http-put-response-hop-limit 2
--http-endpoint enabled
This is a state-changing action that takes effect immediately without a reboot. Apply it to a single instance first and confirm the application still authenticates correctly before rolling the change out through the launch template or Auto Scaling Group configuration used for the fleet.
Validation
Validation must confirm both that IMDSv2 is enforced and that the running application still obtains credentials successfully.
aws ec2 describe-instances
--instance-ids i-0123456789abcdef0
--query "Reservations[].Instances[].MetadataOptions.HttpTokens"
Pass condition: the returned value is “required”. From a shell on the instance, confirm a tokenless request is now rejected.
curl -s -o /dev/null -w "%{http_code}n" http://169.254.169.254/latest/meta-data/
Pass condition: the response is 401, not 200. Also confirm the application continues normal operation for at least one full deployment or health-check cycle, since older AWS SDK versions do not support IMDSv2 and need upgrading rather than a permanent rollback.
Rollback
If the application cannot obtain credentials after enforcement, visible as authentication failures in application logs immediately after the change, revert the specific instance rather than leaving the workload without valid credentials.
aws ec2 modify-instance-metadata-options
--instance-id i-0123456789abcdef0
--http-tokens optional
--http-put-response-hop-limit 1
Stop condition: apply this only to instances showing confirmed credential failures caused by the metadata change, not unrelated deployment issues. Treat this rollback as temporary containment, not a resolution, since it restores the original exposure: schedule the SDK or application fix and re-apply enforcement within a defined, tracked window.
Prevention
Set http-tokens to required in every launch template and Auto Scaling Group configuration so new instances never launch with IMDSv1 permitted, and enable the AWS Config managed rule that checks for IMDSv2 enforcement across the account so drift is detected rather than discovered during an incident. Treat the IAM role’s permission scope as a secondary control: least privilege limits what stolen credentials can do, but it does not stop the credentials being read in the first place. Any application feature that fetches a user-supplied or externally influenced URL should also be reviewed for SSRF exposure independently of the metadata service configuration, since the metadata endpoint is only one of the internal destinations such a flaw can reach.
Apply the safer control
Before you change production
Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.
Fix commands and configuration
/latest/meta-data/iam/security-credentials/<role-name>aws ec2 describe-instances
--instance-ids i-0123456789abcdef0
--query "Reservations[].Instances[].MetadataOptions"aws iam list-attached-role-policies --role-name <instance-role-name>Verify, roll back or escalate
Verify
Validation must confirm both that IMDSv2 is enforced and that the running application still obtains credentials successfully.aws ec2 describe-instances --instance-ids i-0123456789abcdef0 --query "Reservations[].Instances[].MetadataOptions.HttpTokens"Pass condition: the returned value is "required".
Rollback
If the application cannot obtain credentials after enforcement, visible as authentication failures in application logs immediately after the change, revert the specific instance rather than leaving the workload without valid credentials.aws ec2 modify-instance-metadata-options --instance-id i-0123456789abcdef0 --http-tokens optional …
Escalate
Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.