Back to Checks
aws

EC2 instance requires IMDSv2 or has the instance metadata service disabled

ec2_instance_imdsv2_enabled
Service: ec2Severity: high
OfficialBuilt-inVerified
Categories:identity-accesssecretsec2-imdsv1
Resource Type:AwsEc2Instance

EC2 instances are evaluated for IMDSv2 enforcement: metadata endpoint enabled with http_tokens: required, or metadata service fully disabled (http_endpoint: disabled).

Risk

Permitting IMDSv1 or optional tokens lets SSRF or compromised workloads retrieve temporary IAM credentials, impacting confidentiality and integrity. Stolen role creds can drive privilege escalation, unauthorized data access, and lateral movement across AWS resources.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_instance_imdsv2_enabled

Recommendation

Apply defense in depth:

  • Require IMDSv2 tokens on all instances (http_tokens: required)
  • Disable metadata where not needed (http_endpoint: disabled)
  • Minimize hop limit to 1 when feasible
  • Update SDKs/apps for IMDSv2
  • Restrict instance profile permissions (least privilege)
  • Block metadata access from untrusted workloads

Remediation

CLI

aws ec2 modify-instance-metadata-options --instance-id <instance-id> --http-tokens required --http-endpoint enabled

Terraform

# Enforce IMDSv2 on an EC2 instance
resource "aws_instance" "<example_resource_name>" {
  ami           = "<example_resource_id>"
  instance_type = "<example_resource_name>"

  metadata_options {
    http_tokens = "required"  # Critical: Require IMDSv2 tokens (blocks IMDSv1)
  }
}

NativeIaC

# CloudFormation: enforce IMDSv2 on an EC2 instance
Resources:
  <example_resource_name>:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: "<example_resource_id>"
      InstanceType: "<example_resource_name>"
      MetadataOptions:
        HttpTokens: required  # Critical: Require IMDSv2 tokens (blocks IMDSv1)

Other

1In AWS Console, go to EC2 > Instances
2Select the instance > Actions > Instance settings > Modify instance metadata options
3Set Metadata version to IMDSv2 only (HTTP tokens: Required)
4Ensure Instance metadata service is Enabled (or set to Disabled to turn off IMDS entirely)
5Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client


class ec2_instance_imdsv2_enabled(Check):
    def execute(self):
        findings = []
        for instance in ec2_client.instances:
            if instance.state != "terminated":
                report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
                report.status = "FAIL"
                report.status_extended = (
                    f"EC2 Instance {instance.id} has IMDSv2 disabled or not required."
                )
                if (
                    instance.http_endpoint == "enabled"
                    and instance.http_tokens == "required"
                ):
                    report.status = "PASS"
                    report.status_extended = (
                        f"EC2 Instance {instance.id} has IMDSv2 enabled and required."
                    )
                elif instance.http_endpoint == "disabled":
                    report.status = "PASS"
                    report.status_extended = (
                        f"EC2 Instance {instance.id} has metadata service disabled."
                    )

                findings.append(report)

        return findings