From a1b9b2171f47fa1dc8f08293674f619da5933bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20De=20la=20Torre=20Vico?= Date: Mon, 30 Sep 2024 16:13:41 +0200 Subject: [PATCH] feat(securityhub): add tags `securityhub_enabled` (#5231) Co-authored-by: Sergio --- .../securityhub_enabled/securityhub_enabled.py | 1 + .../securityhub/securityhub_service.py | 18 +++++++++++++++++- .../securityhub_enabled_test.py | 16 +++++++++++++--- .../securityhub/securityhub_service_test.py | 11 +++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled.py b/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled.py index 20f9ae1f56..0c81f4a9d9 100644 --- a/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled.py +++ b/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled.py @@ -12,6 +12,7 @@ class securityhub_enabled(Check): report.region = securityhub.region report.resource_id = securityhub.id report.resource_arn = securityhub.arn + report.resource_tags = securityhub.tags if securityhub.status == "ACTIVE": report.status = "PASS" if securityhub.standards: diff --git a/prowler/providers/aws/services/securityhub/securityhub_service.py b/prowler/providers/aws/services/securityhub/securityhub_service.py index 1711f63a94..b3050e0afe 100644 --- a/prowler/providers/aws/services/securityhub/securityhub_service.py +++ b/prowler/providers/aws/services/securityhub/securityhub_service.py @@ -1,3 +1,5 @@ +from typing import Optional + from botocore.client import ClientError from pydantic import BaseModel @@ -6,13 +8,13 @@ from prowler.lib.scan_filters.scan_filters import is_resource_filtered from prowler.providers.aws.lib.service.service import AWSService -################## SecurityHub class SecurityHub(AWSService): def __init__(self, provider): # Call AWSService's __init__ super().__init__(__class__.__name__, provider) self.securityhubs = [] self.__threading_call__(self._describe_hub) + self.__threading_call__(self._list_tags, self.securityhubs) def _describe_hub(self, regional_client): logger.info("SecurityHub - Describing Hub...") @@ -85,6 +87,19 @@ class SecurityHub(AWSService): f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) + def _list_tags(self, resource: any): + try: + if resource.status != "NOT_AVAILABLE": + resource.tags = [ + self.regional_clients[resource.region].list_tags_for_resource( + ResourceArn=resource.arn + )["Tags"] + ] + except Exception as error: + logger.error( + f"{resource.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + class SecurityHubHub(BaseModel): arn: str @@ -93,3 +108,4 @@ class SecurityHubHub(BaseModel): standards: str integrations: str region: str + tags: Optional[list] diff --git a/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_test.py b/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_test.py index 1438b048e0..8d601ae7cc 100644 --- a/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_test.py +++ b/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_test.py @@ -18,6 +18,7 @@ class Test_securityhub_enabled: standards="", integrations="", region=AWS_REGION_EU_WEST_1, + tags=[{"test_key": "test_value"}], ) ] with mock.patch( @@ -37,6 +38,7 @@ class Test_securityhub_enabled: assert result[0].resource_id == "Security Hub" assert result[0].resource_arn == AWS_ACCOUNT_ARN assert result[0].region == AWS_REGION_EU_WEST_1 + assert result[0].resource_tags == [{"test_key": "test_value"}] def test_securityhub_hub_active_with_standards(self): securityhub_client = mock.MagicMock @@ -47,7 +49,8 @@ class Test_securityhub_enabled: status="ACTIVE", standards="cis-aws-foundations-benchmark/v/1.2.0", integrations="", - region="eu-west-1", + region=AWS_REGION_EU_WEST_1, + tags=[{"test_key": "test_value"}], ) ] with mock.patch( @@ -73,6 +76,7 @@ class Test_securityhub_enabled: == "arn:aws:securityhub:us-east-1:0123456789012:hub/default" ) assert result[0].region == AWS_REGION_EU_WEST_1 + assert result[0].resource_tags == [{"test_key": "test_value"}] def test_securityhub_hub_active_with_integrations(self): securityhub_client = mock.MagicMock @@ -83,7 +87,8 @@ class Test_securityhub_enabled: status="ACTIVE", standards="", integrations="prowler", - region="eu-west-1", + region=AWS_REGION_EU_WEST_1, + tags=[{"test_key": "test_value"}], ) ] with mock.patch( @@ -109,6 +114,7 @@ class Test_securityhub_enabled: == "arn:aws:securityhub:us-east-1:0123456789012:hub/default" ) assert result[0].region == AWS_REGION_EU_WEST_1 + assert result[0].resource_tags == [{"test_key": "test_value"}] def test_securityhub_hub_active_without_integrations_or_standards(self): securityhub_client = mock.MagicMock @@ -120,7 +126,8 @@ class Test_securityhub_enabled: status="ACTIVE", standards="", integrations="", - region="eu-west-1", + region=AWS_REGION_EU_WEST_1, + tags=[{"test_key": "test_value"}], ) ] with mock.patch( @@ -146,6 +153,7 @@ class Test_securityhub_enabled: == "arn:aws:securityhub:us-east-1:0123456789012:hub/default" ) assert result[0].region == AWS_REGION_EU_WEST_1 + assert result[0].resource_tags == [{"test_key": "test_value"}] def test_securityhub_hub_active_without_integrations_or_standards_muted(self): securityhub_client = mock.MagicMock @@ -159,6 +167,7 @@ class Test_securityhub_enabled: standards="", integrations="", region="eu-south-2", + tags=[], ) ] with mock.patch( @@ -185,3 +194,4 @@ class Test_securityhub_enabled: == "arn:aws:securityhub:us-east-1:0123456789012:hub/default" ) assert result[0].region == "eu-south-2" + assert result[0].resource_tags == [] diff --git a/tests/providers/aws/services/securityhub/securityhub_service_test.py b/tests/providers/aws/services/securityhub/securityhub_service_test.py index 1799262440..bdfabe65ef 100644 --- a/tests/providers/aws/services/securityhub/securityhub_service_test.py +++ b/tests/providers/aws/services/securityhub/securityhub_service_test.py @@ -37,6 +37,11 @@ def mock_make_api_call(self, operation_name, kwarg): return { "HubArn": "arn:aws:securityhub:us-east-1:0123456789012:hub/default", } + if operation_name == "ListTagsForResource": + return { + "Tags": {"test_key": "test_value"}, + } + return make_api_call(self, operation_name, kwarg) @@ -80,3 +85,9 @@ class Test_SecurityHub_Service: assert securityhub.securityhubs[0].id == "default" assert securityhub.securityhubs[0].standards == "cis-aws-foundations-benchmark " assert securityhub.securityhubs[0].integrations == "prowler " + + def test_list_tags(self): + # Set partition for the service + securityhub = SecurityHub(set_mocked_aws_provider([AWS_REGION_EU_WEST_1])) + assert len(securityhub.securityhubs) == 1 + assert securityhub.securityhubs[0].tags == [{"test_key": "test_value"}]