Auto Scaling group enforces IMDSv2 or disables the instance metadata service
Amazon EC2 Auto Scaling launch configurations are evaluated for Instance Metadata Service settings. Instances should have the metadata endpoint enabled with http_tokens=required (enforcing IMDSv2), or have the metadata service disabled.
Allowing http_tokens=optional or omitting the version leaves legacy access enabled.
Risk
Without enforced IMDSv2, SSRF and local escape paths can access IAM role credentials, enabling unauthorized API calls.
Attackers could:
- Exfiltrate data with stolen tokens
- Move laterally and modify resources, degrading confidentiality and integrity
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks autoscaling_group_launch_configuration_requires_imdsv2Recommendation
Require IMDSv2 for Auto Scaling-launched instances by setting http_tokens=required when metadata is enabled. If metadata is not needed, disable it.
Apply least privilege to instance roles, set IMDSv2 as an account default, and use defense in depth (egress filtering, SSRF protections) to limit exposure.
Remediation
CLI
aws autoscaling create-launch-configuration --launch-configuration-name <new-launch-config> --image-id <AMI_ID> --instance-type <INSTANCE_TYPE> --metadata-options 'HttpTokens=required,HttpEndpoint=enabled'Terraform
# ASG launch configuration enforces IMDSv2
resource "aws_launch_configuration" "example" {
image_id = "<example_ami_id>"
instance_type = "<example_instance_type>"
metadata_options {
http_tokens = "required" # critical: require IMDSv2 tokens (blocks IMDSv1)
http_endpoint = "enabled" # critical: IMDS enabled while enforcing v2
}
}
resource "aws_autoscaling_group" "example" {
launch_configuration = aws_launch_configuration.example.name
min_size = 1
max_size = 1
vpc_zone_identifier = ["<example_subnet_id>"]
}NativeIaC
# CloudFormation: ASG launch configuration enforces IMDSv2
Resources:
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: <example_ami_id>
InstanceType: <example_instance_type>
MetadataOptions:
HttpTokens: required # critical: require IMDSv2 tokens (disables IMDSv1)
HttpEndpoint: enabled # critical: keep IMDS enabled while enforcing v2
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
LaunchConfigurationName: !Ref LaunchConfig
MinSize: 1
MaxSize: 1
VPCZoneIdentifier:
- <example_subnet_id>Other
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.autoscaling.autoscaling_client import (
autoscaling_client,
)
class autoscaling_group_launch_configuration_requires_imdsv2(Check):
def execute(self):
findings = []
for group in autoscaling_client.groups:
for (
launch_configuration
) in autoscaling_client.launch_configurations.values():
if launch_configuration.name == group.launch_configuration_name:
report = Check_Report_AWS(metadata=self.metadata(), resource=group)
report.status = "FAIL"
report.status_extended = f"Autoscaling group {group.name} has IMDSv2 disabled or not required."
if (
launch_configuration.http_endpoint == "enabled"
and launch_configuration.http_tokens == "required"
):
report.status = "PASS"
report.status_extended = f"Autoscaling group {group.name} has IMDSv2 enabled and required."
elif launch_configuration.http_endpoint == "disabled":
report.status = "PASS"
report.status_extended = f"Autoscaling group {group.name} has metadata service disabled."
findings.append(report)
return findingsReferences
- https://trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/aws/EC2/require-imds-v2.html
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-IMDS-new-instances.html
- https://docs.aws.amazon.com/securityhub/latest/userguide/autoscaling-controls.html#autoscaling-3
- https://aws.plainenglish.io/dont-let-metadata-leak-why-imdsv2-is-a-must-and-how-to-migrate-a88e1e285394