Skip to main content

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

  1. Open the EC2 console at https://console.aws.amazon.com/ec2/
  2. Make sure you are in the us-east-1 region (or repeat these steps for each region you use)
  3. In the left navigation, scroll down and click Account attributes under Account attributes
  4. Click Data protection and security
  5. Find the IMDS defaults section and click Manage
  6. Set Metadata version to V2 only (token required)
  7. 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:

  1. In the EC2 console, go to Account attributes > Data protection and security
  2. 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

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.