diff --git a/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/__init__.py b/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled.metadata.json b/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled.metadata.json new file mode 100644 index 0000000000..94687e6c99 --- /dev/null +++ b/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled.metadata.json @@ -0,0 +1,32 @@ +{ + "Provider": "aws", + "CheckID": "guardduty_s3_protection_enabled", + "CheckTitle": "Check if GuardDuty S3 Protection is enabled.", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "ServiceName": "guardduty", + "SubServiceName": "", + "ResourceIdTemplate": "arn:aws:guardduty:::detector/", + "Severity": "high", + "ResourceType": "AwsGuardDutyDetector", + "Description": "This control checks whether GuardDuty S3 Protection is enabled in the account.", + "Risk": "Without GuardDuty S3 Protection enabled, your S3 buckets are not monitored for potential security risks at the object level, which may lead to undetected malicious activities and data breaches.", + "RelatedUrl": "https://docs.aws.amazon.com/guardduty/latest/ug/s3_detection.html", + "Remediation": { + "Code": { + "CLI": "aws guardduty update-detector --detector-id --data-sources '{\"S3Logs\": {\"Enable\": true}}'", + "NativeIaC": "", + "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/guardduty-controls.html#guardduty-10", + "Terraform": "" + }, + "Recommendation": { + "Text": "Enable GuardDuty S3 Protection to monitor object-level API operations in your S3 buckets.", + "Url": "https://docs.aws.amazon.com/guardduty/latest/ug/s3_detection.html" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled.py b/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled.py new file mode 100644 index 0000000000..5aaf134b37 --- /dev/null +++ b/prowler/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled.py @@ -0,0 +1,25 @@ +from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.guardduty.guardduty_client import guardduty_client + + +class guardduty_s3_protection_enabled(Check): + def execute(self): + findings = [] + for detector in guardduty_client.detectors: + if detector.status: + report = Check_Report_AWS(self.metadata()) + report.region = detector.region + report.resource_id = detector.id + report.resource_arn = detector.arn + report.resource_tags = detector.tags + report.status = "FAIL" + report.status_extended = ( + "GuardDuty detector does not have S3 Protection enabled." + ) + if detector.s3_protection: + report.status = "PASS" + report.status_extended = ( + "GuardDuty detector has S3 Protection enabled." + ) + findings.append(report) + return findings diff --git a/prowler/providers/aws/services/guardduty/guardduty_service.py b/prowler/providers/aws/services/guardduty/guardduty_service.py index 4dc7e3da6e..2c331cd90c 100644 --- a/prowler/providers/aws/services/guardduty/guardduty_service.py +++ b/prowler/providers/aws/services/guardduty/guardduty_service.py @@ -66,6 +66,12 @@ class GuardDuty(AWSService): and detector_info["Status"] == "ENABLED" ): detector.status = True + + data_sources = detector_info.get("DataSources", {}) + s3_logs = data_sources.get("S3Logs", {}) + if s3_logs.get("Status") == "ENABLED": + detector.s3_protection = True + except Exception as error: logger.error( f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" @@ -190,3 +196,4 @@ class Detector(BaseModel): member_accounts: list = [] administrator_account: str = None tags: Optional[list] = [] + s3_protection: bool = False diff --git a/tests/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled_test.py b/tests/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled_test.py new file mode 100644 index 0000000000..731d075a15 --- /dev/null +++ b/tests/providers/aws/services/guardduty/guardduty_s3_protection_enabled/guardduty_s3_protection_enabled_test.py @@ -0,0 +1,139 @@ +from unittest import mock + +from prowler.providers.aws.services.guardduty.guardduty_service import Detector +from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_US_EAST_1 + + +class Test_guardduty_s3_protection_enabled: + def test_no_detectors(self): + guardduty_client = mock.MagicMock() + guardduty_client.detectors = [] + + with mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_service.GuardDuty", + new=guardduty_client, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled.guardduty_client", + new=guardduty_client, + ): + + from prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled import ( + guardduty_s3_protection_enabled, + ) + + check = guardduty_s3_protection_enabled() + result = check.execute() + + assert len(result) == 0 + + def test_detector_disabled(self): + guardduty_client = mock.MagicMock() + detector_arn = f"arn:aws:guardduty:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:detector/1234567890" + guardduty_client.detectors = [ + Detector( + id="1234567890", + arn=detector_arn, + region=AWS_REGION_US_EAST_1, + tags=[], + enabled_in_account=False, + s3_protection=False, + ) + ] + + with mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_service.GuardDuty", + new=guardduty_client, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled.guardduty_client", + new=guardduty_client, + ): + + from prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled import ( + guardduty_s3_protection_enabled, + ) + + check = guardduty_s3_protection_enabled() + result = check.execute() + + assert len(result) == 0 + + def test_detector_enabled_s3_protection_disabled(self): + guardduty_client = mock.MagicMock() + detector_arn = f"arn:aws:guardduty:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:detector/1234567890" + guardduty_client.detectors = [ + Detector( + id="1234567890", + arn=detector_arn, + region=AWS_REGION_US_EAST_1, + tags=[], + enabled_in_account=True, + s3_protection=False, + status=True, + ) + ] + + with mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_service.GuardDuty", + new=guardduty_client, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled.guardduty_client", + new=guardduty_client, + ): + + from prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled import ( + guardduty_s3_protection_enabled, + ) + + check = guardduty_s3_protection_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "GuardDuty detector does not have S3 Protection enabled." + ) + assert result[0].resource_id == "1234567890" + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_arn == detector_arn + assert result[0].resource_tags == [] + + def test_detector_enabled_s3_protection_enabled(self): + guardduty_client = mock.MagicMock() + detector_arn = f"arn:aws:guardduty:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:detector/1234567890" + guardduty_client.detectors = [ + Detector( + id="1234567890", + arn=detector_arn, + region=AWS_REGION_US_EAST_1, + tags=[], + enabled_in_account=True, + s3_protection=True, + status=True, + ) + ] + + with mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_service.GuardDuty", + new=guardduty_client, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled.guardduty_client", + new=guardduty_client, + ): + from prowler.providers.aws.services.guardduty.guardduty_s3_protection_enabled.guardduty_s3_protection_enabled import ( + guardduty_s3_protection_enabled, + ) + + check = guardduty_s3_protection_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == "GuardDuty detector has S3 Protection enabled." + ) + assert result[0].resource_id == "1234567890" + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_arn == detector_arn + assert result[0].resource_tags == []