Back to Checks
aws

IMDSv2 is required by default for EC2 instances at the account level

ec2_instance_account_imdsv2_enabled
Service: ec2Severity: high
OfficialBuilt-inVerified
Categories:secretsec2-imdsv1
Resource Type:AwsEc2Instance

EC2 account IMDS defaults with http_tokens=required ensure new instances in the Region use IMDSv2 by default and disable IMDSv1. Existing instances keep their current setting.

Risk

Without a default of IMDSv2, new instances may enable IMDSv1, exposing metadata via simple HTTP. SSRF or proxy misconfigs can steal temporary IAM credentials, enabling data exfiltration (confidentiality), unauthorized API changes (integrity), and lateral movement that can disrupt services (availability).

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_instance_account_imdsv2_enabled

Recommendation

Enforce IMDSv2 at the account level in every Region by setting http_tokens to required. Add guardrails with SCP/IAM conditions. Standardize AMIs and launch templates to require tokens, validate workload compatibility, and apply least privilege to instance roles for defense in depth. For containers, prefer hop limit 2.

Remediation

CLI

aws ec2 modify-instance-metadata-defaults --region <region> --http-tokens required

Other

1In the AWS Console, open EC2 and select the target Region
2Go to EC2 Dashboard > Account attributes > Data protection and security
3Next to IMDS defaults, click Manage
4Set Metadata version to V2 only (token required)
5Click Update

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_account_imdsv2_enabled(Check):
    def execute(self):
        findings = []
        for instance_metadata_default in ec2_client.instance_metadata_defaults:
            if (
                instance_metadata_default.instances
                or ec2_client.provider.scan_unused_services
            ):
                report = Check_Report_AWS(
                    metadata=self.metadata(),
                    resource=instance_metadata_default,
                )
                report.resource_arn = (
                    f"arn:{ec2_client.audited_partition}:ec2:"
                    f"{instance_metadata_default.region}:"
                    f"{ec2_client.audited_account}:account"
                )
                report.resource_id = ec2_client.audited_account
                if instance_metadata_default.http_tokens == "required":
                    report.status = "PASS"
                    report.status_extended = (
                        "IMDSv2 is enabled by default for EC2 instances."
                    )
                else:
                    report.status = "FAIL"
                    report.status_extended = (
                        "IMDSv2 is not enabled by default for EC2 instances."
                    )
                findings.append(report)

        return findings