From d5abe16180176cd82f7c0f3b072a30f48ecce876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20De=20la=20Torre=20Vico?= Date: Mon, 30 Sep 2024 15:37:16 +0200 Subject: [PATCH] feat(wafv2): add tags to `wafv2_webacl_logging_enabled` (#5243) --- .../aws/services/wafv2/wafv2_service.py | 19 +++++++++++++- .../wafv2_webacl_logging_enabled.py | 1 + .../aws/services/wafv2/wafv2_service_test.py | 26 ++++++++++++++++++- .../wafv2_webacl_logging_enabled_test.py | 4 +++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/prowler/providers/aws/services/wafv2/wafv2_service.py b/prowler/providers/aws/services/wafv2/wafv2_service.py index efb53e668d..1f1ad3793e 100644 --- a/prowler/providers/aws/services/wafv2/wafv2_service.py +++ b/prowler/providers/aws/services/wafv2/wafv2_service.py @@ -1,3 +1,5 @@ +from typing import Optional + from botocore.exceptions import ClientError from pydantic import BaseModel @@ -6,7 +8,6 @@ from prowler.lib.scan_filters.scan_filters import is_resource_filtered from prowler.providers.aws.lib.service.service import AWSService -################### WAFv2 class WAFv2(AWSService): def __init__(self, provider): # Call AWSService's __init__ @@ -15,6 +16,7 @@ class WAFv2(AWSService): self.__threading_call__(self._list_web_acls) self.__threading_call__(self._list_resources_for_web_acl) self.__threading_call__(self._get_logging_configuration) + self.__threading_call__(self._list_tags, self.web_acls) def _list_web_acls(self, regional_client): logger.info("WAFv2 - Listing Regional Web ACLs...") @@ -84,6 +86,20 @@ class WAFv2(AWSService): f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) + def _list_tags(self, resource: any): + logger.info("WAFv2 - Listing tags...") + try: + resource.tags = ( + self.regional_clients[resource.region] + .list_tags_for_resource(ResourceARN=resource.arn) + .get("TagInfoForResource", {}) + .get("TagList", []) + ) + except Exception as error: + logger.error( + f"{resource.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + class WebAclv2(BaseModel): arn: str @@ -93,3 +109,4 @@ class WebAclv2(BaseModel): user_pools: list[str] region: str logging_enabled: bool = False + tags: Optional[list] diff --git a/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.py b/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.py index df4220b871..5307e68752 100644 --- a/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.py +++ b/prowler/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled.py @@ -10,6 +10,7 @@ class wafv2_webacl_logging_enabled(Check): report.region = web_acl.region report.resource_id = web_acl.id report.resource_arn = web_acl.arn + report.resource_tags = web_acl.tags if web_acl.logging_enabled: report.status = "PASS" diff --git a/tests/providers/aws/services/wafv2/wafv2_service_test.py b/tests/providers/aws/services/wafv2/wafv2_service_test.py index 2cfb12e955..c649ac3ec9 100644 --- a/tests/providers/aws/services/wafv2/wafv2_service_test.py +++ b/tests/providers/aws/services/wafv2/wafv2_service_test.py @@ -104,7 +104,7 @@ class Test_WAFv2_Service: # Test WAFv2 describe Web user pools @mock_aws - def test__list_resources_for_web_user_pools__(self): + def test_list_resources_for_web_user_pools(self): wafv2 = client("wafv2", region_name=AWS_REGION_EU_WEST_1) cognito = client("cognito-idp", region_name=AWS_REGION_EU_WEST_1) waf = wafv2.create_web_acl( @@ -126,3 +126,27 @@ class Test_WAFv2_Service: assert len(wafv2.web_acls) == 1 assert len(wafv2.web_acls[0].user_pools) == 1 assert user_pool["Arn"] in wafv2.web_acls[0].user_pools + + @mock_aws + def test_list_tags(self): + wafv2 = client("wafv2", region_name=AWS_REGION_EU_WEST_1) + waf = wafv2.create_web_acl( + Scope="REGIONAL", + Name="my-web-acl", + DefaultAction={"Allow": {}}, + VisibilityConfig={ + "SampledRequestsEnabled": False, + "CloudWatchMetricsEnabled": False, + "MetricName": "idk", + }, + )["Summary"] + wafv2.tag_resource( + ResourceARN=waf["ARN"], Tags=[{"Key": "Name", "Value": "my-web-acl"}] + ) + # WAFv2 client for this test class + aws = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + wafv2 = WAFv2(aws) + assert len(wafv2.web_acls) == 1 + assert len(wafv2.web_acls[0].tags) == 1 + assert wafv2.web_acls[0].tags[0]["Key"] == "Name" + assert wafv2.web_acls[0].tags[0]["Value"] == "my-web-acl" diff --git a/tests/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled_test.py b/tests/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled_test.py index eaf0bb086c..8e0f02b7fa 100644 --- a/tests/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled_test.py +++ b/tests/providers/aws/services/wafv2/wafv2_webacl_logging_enabled/wafv2_webacl_logging_enabled_test.py @@ -41,6 +41,7 @@ class Test_wafv2_webacl_logging_enabled: user_pools=[], region=AWS_REGION_EU_WEST_1, logging_enabled=True, + tags=[{"Key": "Name", "Value": waf_name}], ) ) with mock.patch( @@ -65,6 +66,7 @@ class Test_wafv2_webacl_logging_enabled: assert result[0].resource_id == waf_id assert result[0].resource_arn == waf_arn assert result[0].region == AWS_REGION_EU_WEST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": waf_name}] def test_wafv2_wb_acl_without_logging(self): wafv2_client = mock.MagicMock @@ -79,6 +81,7 @@ class Test_wafv2_webacl_logging_enabled: user_pools=[], region=AWS_REGION_EU_WEST_1, logging_enabled=False, + tags=[{"Key": "Name", "Value": waf_name}], ) ) with mock.patch( @@ -103,3 +106,4 @@ class Test_wafv2_webacl_logging_enabled: assert result[0].resource_id == waf_id assert result[0].resource_arn == waf_arn assert result[0].region == AWS_REGION_EU_WEST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": waf_name}]