Enforce IMDSv2 at the Account Level for EC2 Instances
Overview
This check verifies that your AWS account is configured to require Instance Metadata Service Version 2 (IMDSv2) by default for all new EC2 instances. IMDSv2 adds an extra layer of security by requiring a session token to access instance metadata, protecting against common web application vulnerabilities.
Risk
Without IMDSv2 enforcement, new EC2 instances may use the older IMDSv1, which allows any process on the instance to access metadata with a simple HTTP request. This creates a serious security risk:
- Server-Side Request Forgery (SSRF) attacks can steal IAM credentials from the metadata service
- Compromised web applications can be exploited to access sensitive instance credentials
- Lateral movement becomes easier if attackers obtain temporary IAM credentials
This is a high severity issue because credential theft through SSRF is a well-documented attack vector used in real-world breaches.
Remediation Steps
Prerequisites
You need permission to modify EC2 account settings. Specifically, you need the ec2:ModifyInstanceMetadataDefaults permission.
AWS Console Method
- Open the EC2 console at https://console.aws.amazon.com/ec2/
- Make sure you are in the us-east-1 region (or repeat these steps for each region you use)
- In the left navigation, scroll down and click Account attributes under Account attributes
- Click Data protection and security
- Find the IMDS defaults section and click Manage
- Set Metadata version to V2 only (token required)
- Click Update
Repeat these steps for each AWS Region where you run EC2 instances.
AWS CLI (optional)
Enforce IMDSv2 for a single region
aws ec2 modify-instance-metadata-defaults \
--region us-east-1 \
--http-tokens required
Enforce IMDSv2 across all regions
Run this command to enable IMDSv2 in all AWS regions:
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
echo "Enabling IMDSv2 in $region..."
aws ec2 modify-instance-metadata-defaults \
--region "$region" \
--http-tokens required
done
Optional: Set a hop limit for containerized workloads
If you run containers on EC2, you may need to increase the hop limit to 2 so containers can reach the metadata service:
aws ec2 modify-instance-metadata-defaults \
--region us-east-1 \
--http-tokens required \
--http-put-response-hop-limit 2
CloudFormation (optional)
There is no native CloudFormation resource for account-level IMDS defaults. You can use a Custom Resource backed by a Lambda function:
AWSTemplateFormatVersion: '2010-09-09'
Description: Enforce IMDSv2 at the account level for EC2 instances
Resources:
IMDSv2AccountDefault:
Type: Custom::IMDSv2AccountDefault
Properties:
ServiceToken: !GetAtt IMDSv2EnforcementFunction.Arn
IMDSv2EnforcementFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: imdsv2-account-default-enforcement
Runtime: python3.11
Handler: index.handler
Timeout: 60
Role: !GetAtt IMDSv2EnforcementRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
ec2 = boto3.client('ec2')
try:
if event['RequestType'] in ['Create', 'Update']:
ec2.modify_instance_metadata_defaults(HttpTokens='required')
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})
IMDSv2EnforcementRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: IMDSv2EnforcementPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ec2:ModifyInstanceMetadataDefaults
Resource: '*'
Outputs:
Status:
Description: IMDSv2 enforcement status
Value: Enabled
Important: Deploy this stack in each region where you want to enforce IMDSv2.
Terraform (optional)
As of early 2025, there is no native Terraform resource for aws ec2 modify-instance-metadata-defaults. Use a null_resource with a local-exec provisioner:
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
null = {
source = "hashicorp/null"
version = ">= 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
# Enforce IMDSv2 at the account level using AWS CLI
resource "null_resource" "enforce_imdsv2_account_default" {
provisioner "local-exec" {
command = "aws ec2 modify-instance-metadata-defaults --region us-east-1 --http-tokens required"
}
# Re-run if this trigger value changes
triggers = {
always_run = timestamp()
}
}
output "imdsv2_enforcement_status" {
value = "IMDSv2 enforcement command executed"
description = "Confirmation that IMDSv2 account default has been set"
}
Note: The null_resource approach requires the AWS CLI to be installed where Terraform runs. For multi-region enforcement, create multiple provider aliases and resources.
Verification
After making changes, verify that IMDSv2 is now required:
- In the EC2 console, go to Account attributes > Data protection and security
- Confirm that IMDS defaults shows V2 only (token required)
CLI verification
aws ec2 get-instance-metadata-defaults --region us-east-1
Expected output when IMDSv2 is enforced:
{
"AccountLevel": {
"HttpTokens": "required"
}
}
To verify across all regions:
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
echo "Region: $region"
aws ec2 get-instance-metadata-defaults --region "$region" --query 'AccountLevel.HttpTokens' --output text
done
Additional Resources
- Configure the instance metadata service - AWS Documentation
- Use IMDSv2 - How IMDSv2 works
- Order of precedence for instance metadata options - Understanding how settings are applied
- Prowler Check Documentation
Notes
- Scope: This setting only affects new instances launched after the change. Existing instances retain their current IMDS configuration.
- Regional setting: You must configure this in each AWS Region separately.
- Launch templates: For consistent enforcement, also update your launch templates to require IMDSv2.
- Container workloads: If you run containers on EC2 (ECS, EKS, or Docker), consider setting the hop limit to 2 so containers can access the metadata service through the container network layer.
- Compliance: This control helps meet requirements in C5, ISO27001, KISA-ISMS-P, and NIS2 frameworks.