diff --git a/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py b/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py new file mode 100644 index 0000000000..6c43385e73 --- /dev/null +++ b/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py @@ -0,0 +1,38 @@ +from prowler.lib.logger import logger +from prowler.providers.aws.services.ecr.ecr_client import ecr_client + + +def fixer(resource_id: str, region: str) -> bool: + """ + Modify the ECR repository's policy to remove public access. + Specifically, this fixer delete the policy that had public access. + Requires the ecr:DeleteRepositoryPolicy permission. + Permissions: + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "ecr:DeleteRepositoryPolicy", + "Resource": "*" + } + ] + } + Args: + resource_id (str): The ECR repository name. + region (str): AWS region where the ECR repository exists. + Returns: + bool: True if the operation is successful (policy updated), False otherwise. + """ + try: + regional_client = ecr_client.regional_clients[region] + + regional_client.delete_repository_policy(repositoryName=resource_id) + + 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/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py b/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py new file mode 100644 index 0000000000..d2b4953cdc --- /dev/null +++ b/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py @@ -0,0 +1,135 @@ +from json import dumps +from unittest import mock + +from boto3 import client +from moto import mock_aws + +from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider + + +class Test_ecr_repositories_not_publicly_accessible_fixer: + @mock_aws + def test_ecr_repository_public(self): + ecr_client = client("ecr", region_name=AWS_REGION_EU_WEST_1) + + repository_name = "test-repo" + ecr_client.create_repository(repositoryName=repository_name) + + ecr_client.set_repository_policy( + repositoryName=repository_name, + policyText=dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"AWS": "*"}, + "Action": "ecr:*", + "Resource": f"arn:aws:ecr:{AWS_REGION_EU_WEST_1}:123456789012:repository/{repository_name}", + } + ], + } + ), + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + + from prowler.providers.aws.services.ecr.ecr_service import ECR + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer.ecr_client", + new=ECR(aws_provider), + ): + # Test Fixer + from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer import ( + fixer, + ) + + assert fixer(repository_name, AWS_REGION_EU_WEST_1) + + @mock_aws + def test_ecr_repository_not_public(self): + ecr_client = client("ecr", region_name=AWS_REGION_EU_WEST_1) + + repository_name = "test-repo" + ecr_client.create_repository(repositoryName=repository_name) + + ecr_client.set_repository_policy( + repositoryName=repository_name, + policyText=dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"AWS": "123456789012"}, + "Action": "ecr:*", + "Resource": f"arn:aws:ecr:{AWS_REGION_EU_WEST_1}:123456789012:repository/{repository_name}", + } + ], + } + ), + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + + from prowler.providers.aws.services.ecr.ecr_service import ECR + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer.ecr_client", + new=ECR(aws_provider), + ): + # Test Fixer + from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer import ( + fixer, + ) + + assert fixer(repository_name, AWS_REGION_EU_WEST_1) + + @mock_aws + def test_ecr_repository_public_error(self): + ecr_client = client("ecr", region_name=AWS_REGION_EU_WEST_1) + + repository_name = "test-repo" + ecr_client.create_repository(repositoryName=repository_name) + + ecr_client.set_repository_policy( + repositoryName=repository_name, + policyText=dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"AWS": "*"}, + "Action": "ecr:*", + "Resource": f"arn:aws:ecr:{AWS_REGION_EU_WEST_1}:123456789012:repository/{repository_name}", + } + ], + } + ), + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + + from prowler.providers.aws.services.ecr.ecr_service import ECR + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer.ecr_client", + new=ECR(aws_provider), + ): + # Test Fixer + from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer import ( + fixer, + ) + + assert not fixer("repository_name_non_existing", AWS_REGION_EU_WEST_1)