From 470e218bb8b2fc19507b625d31948fa4f87bc421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Pe=C3=B1a?= Date: Mon, 13 Jul 2026 17:32:08 +0200 Subject: [PATCH] fix(sdk): preserve regional IMDSv2 account findings (#11959) --- ...imdsv2-regional-resource-identity.fixed.md | 1 + .../ec2_instance_account_imdsv2_enabled.py | 6 +- ...c2_instance_account_imdsv2_enabled_test.py | 58 ++++++++++++++++--- 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 prowler/changelog.d/ec2-imdsv2-regional-resource-identity.fixed.md diff --git a/prowler/changelog.d/ec2-imdsv2-regional-resource-identity.fixed.md b/prowler/changelog.d/ec2-imdsv2-regional-resource-identity.fixed.md new file mode 100644 index 0000000000..97e854ce61 --- /dev/null +++ b/prowler/changelog.d/ec2-imdsv2-regional-resource-identity.fixed.md @@ -0,0 +1 @@ +`ec2_instance_account_imdsv2_enabled` findings now use regional resource ARNs, preventing findings from different AWS Regions from collapsing into one resource diff --git a/prowler/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled.py b/prowler/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled.py index 9abd6239cc..f6b0fce95f 100644 --- a/prowler/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled.py +++ b/prowler/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled.py @@ -14,7 +14,11 @@ class ec2_instance_account_imdsv2_enabled(Check): metadata=self.metadata(), resource=instance_metadata_default, ) - report.resource_arn = ec2_client.account_arn_template + 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" diff --git a/tests/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled_test.py b/tests/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled_test.py index 8a1f323409..9d19211ca8 100644 --- a/tests/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled_test.py +++ b/tests/providers/aws/services/ec2/ec2_instance_account_imdsv2_enabled/ec2_instance_account_imdsv2_enabled_test.py @@ -1,15 +1,64 @@ +from types import SimpleNamespace from unittest import mock from moto import mock_aws from tests.providers.aws.utils import ( AWS_ACCOUNT_NUMBER, + AWS_COMMERCIAL_PARTITION, + AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1, set_mocked_aws_provider, ) class Test_ec2_instance_account_imdsv2_enabled: + @mock_aws + def test_ec2_imdsv2_uses_region_in_resource_arn(self): + from prowler.providers.aws.services.ec2.ec2_service import ( + InstanceMetadataDefaults, + ) + + ec2_client = SimpleNamespace( + instance_metadata_defaults=[ + InstanceMetadataDefaults( + http_tokens=None, + instances=True, + region=AWS_REGION_US_EAST_1, + ), + InstanceMetadataDefaults( + http_tokens=None, + instances=True, + region=AWS_REGION_EU_WEST_1, + ), + ], + audited_account=AWS_ACCOUNT_NUMBER, + audited_partition=AWS_COMMERCIAL_PARTITION, + provider=SimpleNamespace(scan_unused_services=False), + ) + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_aws_provider(), + ), + mock.patch( + "prowler.providers.aws.services.ec2.ec2_instance_account_imdsv2_enabled.ec2_instance_account_imdsv2_enabled.ec2_client", + new=ec2_client, + ), + ): + from prowler.providers.aws.services.ec2.ec2_instance_account_imdsv2_enabled.ec2_instance_account_imdsv2_enabled import ( + ec2_instance_account_imdsv2_enabled, + ) + + result = ec2_instance_account_imdsv2_enabled().execute() + + assert len(result) == 2 + assert {report.resource_arn for report in result} == { + f"arn:aws:ec2:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account", + f"arn:aws:ec2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:account", + } + @mock_aws def test_ec2_imdsv2_required(self): from prowler.providers.aws.services.ec2.ec2_service import ( @@ -23,10 +72,8 @@ class Test_ec2_instance_account_imdsv2_enabled: ) ] ec2_client.audited_account = AWS_ACCOUNT_NUMBER + ec2_client.audited_partition = AWS_COMMERCIAL_PARTITION ec2_client.region = AWS_REGION_US_EAST_1 - ec2_client.account_arn_template = ( - f"arn:aws:ec2:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account" - ) with ( mock.patch( @@ -71,12 +118,9 @@ class Test_ec2_instance_account_imdsv2_enabled: ) ] ec2_client.audited_account = AWS_ACCOUNT_NUMBER + ec2_client.audited_partition = AWS_COMMERCIAL_PARTITION ec2_client.region = AWS_REGION_US_EAST_1 - ec2_client.account_arn_template = ( - f"arn:aws:ec2:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account" - ) - with ( mock.patch( "prowler.providers.common.provider.Provider.get_global_provider",