diff --git a/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py b/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py new file mode 100644 index 00000000000..bf44b90b4de --- /dev/null +++ b/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py @@ -0,0 +1,43 @@ +from prowler.lib.logger import logger +from prowler.providers.aws.services.rds.rds_client import rds_client + + +def fixer(resource_id: str, region: str) -> bool: + """ + Modify the attributes of an RDS instance to disable public accessibility. + Specifically, this fixer sets the 'PubliclyAccessible' attribute to False + to prevent the RDS instance from being publicly accessible. + + Requires the rds:ModifyDBInstance permission: + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "rds:ModifyDBInstance", + "Resource": "*" + } + ] + } + + Args: + resource_id (str): The DB instance identifier. + region (str): AWS region where the DB instance exists. + + Returns: + bool: True if the operation is successful (public access is disabled), False otherwise. + """ + try: + regional_client = rds_client.regional_clients[region] + regional_client.modify_db_instance( + DBInstanceIdentifier=resource_id, + PubliclyAccessible=False, + ApplyImmediately=True, + ) + except Exception as error: + logger.error( + f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py b/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py new file mode 100644 index 00000000000..5577a5623ba --- /dev/null +++ b/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py @@ -0,0 +1,102 @@ +from unittest import mock + +from boto3 import client +from moto import mock_aws + +from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider + + +class Test_rds_instance_no_public_access_fixer: + @mock_aws + def test_rds_private(self): + conn = client("rds", region_name=AWS_REGION_US_EAST_1) + conn.create_db_instance( + DBInstanceIdentifier="db-primary-1", + AllocatedStorage=10, + Engine="postgres", + DBName="staging-postgres", + DBInstanceClass="db.m1.small", + ) + + from prowler.providers.aws.services.rds.rds_service import RDS + + 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, + ): + with mock.patch( + "prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer.rds_client", + new=RDS(aws_provider), + ): + # Test Fixer + from prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer import ( + fixer, + ) + + assert fixer("db-primary-1", AWS_REGION_US_EAST_1) + + @mock_aws + def test_rds_public(self): + conn = client("rds", region_name=AWS_REGION_US_EAST_1) + conn.create_db_instance( + DBInstanceIdentifier="db-primary-1", + AllocatedStorage=10, + Engine="postgres", + DBName="staging-postgres", + DBInstanceClass="db.m1.small", + PubliclyAccessible=True, + ) + + from prowler.providers.aws.services.rds.rds_service import RDS + + 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, + ): + with mock.patch( + "prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer.rds_client", + new=RDS(aws_provider), + ): + + # Test Fixer + from prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer import ( + fixer, + ) + + assert fixer("db-primary-1", AWS_REGION_US_EAST_1) + + @mock_aws + def test_rds_cluster_public_snapshot_error(self): + conn = client("rds", region_name=AWS_REGION_US_EAST_1) + conn.create_db_instance( + DBInstanceIdentifier="db-primary-1", + AllocatedStorage=10, + Engine="postgres", + DBName="staging-postgres", + DBInstanceClass="db.m1.small", + PubliclyAccessible=True, + ) + + from prowler.providers.aws.services.rds.rds_service import RDS + + 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, + ): + with mock.patch( + "prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer.rds_client", + new=RDS(aws_provider), + ): + + # Test Fixer + from prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer import ( + fixer, + ) + + assert not fixer("db-primary-2", AWS_REGION_US_EAST_1)