From 1e4ac36de9737717fdcb9ac500a1f10cc0b72b57 Mon Sep 17 00:00:00 2001 From: Prowler Bot Date: Fri, 4 Jul 2025 13:05:33 +0200 Subject: [PATCH] fix(ec2): allow empty values for `http_endpoint` in templates (#8187) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Pedro Martín --- prowler/CHANGELOG.md | 7 ++ .../ec2_launch_template_imdsv2_required.py | 5 +- ...c2_launch_template_imdsv2_required_test.py | 78 +++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 944d7747f9..bec44526ad 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -8,8 +8,15 @@ All notable changes to the **Prowler SDK** are documented in this file. ### Changed +### Fixed + +--- + +## [v5.8.1] (Prowler 5.8.1) + ### Fixed - fix(iam): detect wildcarded ARNs in sts:AssumeRole policy resources [(#8164)](https://github.com/prowler-cloud/prowler/pull/8164) +- fix(ec2): allow empty values for http_endpoint in templates [(#8184)](https://github.com/prowler-cloud/prowler/pull/8184) --- diff --git a/prowler/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required.py b/prowler/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required.py index a974128061..b89c7a821a 100644 --- a/prowler/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required.py +++ b/prowler/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required.py @@ -18,7 +18,10 @@ class ec2_launch_template_imdsv2_required(Check): and version.template_data.http_tokens == "required" ): versions_with_imdsv2_required.append(str(version.version_number)) - elif version.template_data.http_endpoint == "disabled": + elif ( + version.template_data.http_endpoint == "disabled" + or not version.template_data.http_endpoint + ): versions_with_metadata_disabled.append(str(version.version_number)) else: versions_with_no_imdsv2.append(str(version.version_number)) diff --git a/tests/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required_test.py b/tests/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required_test.py index 22ff04f349..fd1a5924ec 100644 --- a/tests/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required_test.py +++ b/tests/providers/aws/services/ec2/ec2_launch_template_imdsv2_required/ec2_launch_template_imdsv2_required_test.py @@ -27,6 +27,24 @@ def mock_make_api_call(self, operation_name, kwarg): return make_api_call(self, operation_name, kwarg) +def mock_make_api_call_empty(self, operation_name, kwarg): + if operation_name == "DescribeLaunchTemplateVersions": + return { + "LaunchTemplateVersions": [ + { + "VersionNumber": 1, + "LaunchTemplateData": { + "MetadataOptions": { + "HttpEndpoint": "", + "HttpTokens": "required", + } + }, + } + ] + } + return make_api_call(self, operation_name, kwarg) + + def mock_make_api_call_not_required(self, operation_name, kwarg): if operation_name == "DescribeLaunchTemplateVersions": return { @@ -134,6 +152,66 @@ class Test_ec2_launch_template_imdsv2_required: ) assert result[0].resource_tags == [] + @mock_aws + def test_launch_template_imdsv2_required_empty(self): + with mock.patch( + "botocore.client.BaseClient._make_api_call", + new=mock_make_api_call_empty, + ): + ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) + launch_template_name = "test-imdsv2-required-empty" + ec2_client.create_launch_template( + LaunchTemplateName=launch_template_name, + VersionDescription="Launch Template with IMDSv2 required", + LaunchTemplateData={ + "InstanceType": "t1.micro", + "MetadataOptions": { + "HttpEndpoint": "", + "HttpTokens": "required", + }, + }, + ) + + launch_template_id = ec2_client.describe_launch_templates( + LaunchTemplateNames=[launch_template_name] + )["LaunchTemplates"][0]["LaunchTemplateId"] + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), + mock.patch( + "prowler.providers.aws.services.ec2.ec2_launch_template_imdsv2_required.ec2_launch_template_imdsv2_required.ec2_client", + new=EC2(aws_provider), + ), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_launch_template_imdsv2_required.ec2_launch_template_imdsv2_required import ( + ec2_launch_template_imdsv2_required, + ) + + check = ec2_launch_template_imdsv2_required() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"EC2 Launch Template {launch_template_name} has metadata service disabled in the following versions: 1." + ) + assert result[0].resource_id == launch_template_id + assert result[0].region == AWS_REGION_US_EAST_1 + assert ( + result[0].resource_arn + == f"arn:aws:ec2:{AWS_REGION_US_EAST_1}:123456789012:launch-template/{launch_template_id}" + ) + assert result[0].resource_tags == [] + @mock_aws def test_launch_template_imdsv2_not_required(self): with mock.patch(