diff --git a/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/__init__.py b/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled.metadata.json b/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled.metadata.json new file mode 100644 index 0000000000..445e334de8 --- /dev/null +++ b/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled.metadata.json @@ -0,0 +1,32 @@ +{ + "Provider": "aws", + "CheckID": "guardduty_rds_protection_enabled", + "CheckTitle": "Check if GuardDuty RDS 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": "Check if GuardDuty RDS Protection is enabled to ensure monitoring and threat detection for RDS activity.", + "Risk": "Without GuardDuty RDS Protection enabled, suspicious login activities to your databases may go undetected, increasing the risk of unauthorized access, data breaches, or compromised database security.", + "RelatedUrl": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/guard-duty-rds-protection.html", + "Remediation": { + "Code": { + "CLI": "", + "NativeIaC": "", + "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/guardduty-controls.html#guardduty-9", + "Terraform": "" + }, + "Recommendation": { + "Text": "Enable GuardDuty RDS Protection to continuously monitor and detect anomalous login behaviors on your Aurora databases, helping to identify and respond to potential access threats without impacting database performance.", + "Url": "https://docs.aws.amazon.com/guardduty/latest/ug/rds-protection.html" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled.py b/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled.py new file mode 100644 index 0000000000..d765c86848 --- /dev/null +++ b/prowler/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_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_rds_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 RDS Protection enabled." + ) + if detector.rds_protection: + report.status = "PASS" + report.status_extended = ( + "GuardDuty detector has RDS 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 2c331cd90c..0ee0f7d26c 100644 --- a/prowler/providers/aws/services/guardduty/guardduty_service.py +++ b/prowler/providers/aws/services/guardduty/guardduty_service.py @@ -7,7 +7,6 @@ from prowler.lib.scan_filters.scan_filters import is_resource_filtered from prowler.providers.aws.lib.service.service import AWSService -################################ GuardDuty class GuardDuty(AWSService): def __init__(self, provider): # Call AWSService's __init__ @@ -72,6 +71,13 @@ class GuardDuty(AWSService): if s3_logs.get("Status") == "ENABLED": detector.s3_protection = True + for feat in detector_info.get("Features", []): + if ( + feat.get("Name") == "RDS_LOGIN_EVENTS" + and feat.get("Status", "DISABLED") == "ENABLED" + ): + detector.rds_protection = True + except Exception as error: logger.error( f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" @@ -197,3 +203,4 @@ class Detector(BaseModel): administrator_account: str = None tags: Optional[list] = [] s3_protection: bool = False + rds_protection: bool = False diff --git a/tests/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled_test.py b/tests/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_protection_enabled_test.py new file mode 100644 index 0000000000..5587d9e0d1 --- /dev/null +++ b/tests/providers/aws/services/guardduty/guardduty_rds_protection_enabled/guardduty_rds_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_rds_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_rds_protection_enabled.guardduty_rds_protection_enabled.guardduty_client", + new=guardduty_client, + ): + + from prowler.providers.aws.services.guardduty.guardduty_rds_protection_enabled.guardduty_rds_protection_enabled import ( + guardduty_rds_protection_enabled, + ) + + check = guardduty_rds_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, + rds_protection=False, + ) + ] + + with mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_service.GuardDuty", + new=guardduty_client, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_rds_protection_enabled.guardduty_rds_protection_enabled.guardduty_client", + new=guardduty_client, + ): + + from prowler.providers.aws.services.guardduty.guardduty_rds_protection_enabled.guardduty_rds_protection_enabled import ( + guardduty_rds_protection_enabled, + ) + + check = guardduty_rds_protection_enabled() + result = check.execute() + + assert len(result) == 0 + + def test_detector_enabled_rds_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, + rds_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_rds_protection_enabled.guardduty_rds_protection_enabled.guardduty_client", + new=guardduty_client, + ): + + from prowler.providers.aws.services.guardduty.guardduty_rds_protection_enabled.guardduty_rds_protection_enabled import ( + guardduty_rds_protection_enabled, + ) + + check = guardduty_rds_protection_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "GuardDuty detector does not have RDS 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_rds_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, + rds_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_rds_protection_enabled.guardduty_rds_protection_enabled.guardduty_client", + new=guardduty_client, + ): + from prowler.providers.aws.services.guardduty.guardduty_rds_protection_enabled.guardduty_rds_protection_enabled import ( + guardduty_rds_protection_enabled, + ) + + check = guardduty_rds_protection_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == "GuardDuty detector has RDS 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 == [] diff --git a/tests/providers/aws/services/guardduty/guardduty_service_test.py b/tests/providers/aws/services/guardduty/guardduty_service_test.py index 401cdf8dc0..9ed2ac0049 100644 --- a/tests/providers/aws/services/guardduty/guardduty_service_test.py +++ b/tests/providers/aws/services/guardduty/guardduty_service_test.py @@ -109,7 +109,10 @@ class Test_GuardDuty_Service: # Test GuardDuty session def test_get_detector(self): guardduty_client = client("guardduty", region_name=AWS_REGION_EU_WEST_1) - response = guardduty_client.create_detector(Enable=True) + response = guardduty_client.create_detector( + Enable=True, + DataSources={"S3Logs": {"Enable": True}}, + ) aws_provider = set_mocked_aws_provider() guardduty = GuardDuty(aws_provider) @@ -124,6 +127,8 @@ class Test_GuardDuty_Service: assert len(guardduty.detectors[0].findings) == 1 assert guardduty.detectors[0].member_accounts == ["123456789012"] assert guardduty.detectors[0].administrator_account == "123456789013" + assert guardduty.detectors[0].s3_protection + assert not guardduty.detectors[0].rds_protection assert guardduty.detectors[0].region == AWS_REGION_EU_WEST_1 assert guardduty.detectors[0].tags == [{"test": "test"}]