From ae1b114a136b485329826d251e861c0627501eb7 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:28:06 +0200 Subject: [PATCH] refactor(s3): Changed buckets variable type form list to dict (#4742) --- .../cloudtrail_bucket_requires_mfa_delete.py | 2 +- ...l_logs_s3_bucket_access_logging_enabled.py | 2 +- ...gs_s3_bucket_is_not_publicly_accessible.py | 2 +- .../s3_bucket_acl_prohibited.py | 4 +- .../s3_bucket_default_encryption.py | 4 +- .../s3_bucket_kms_encryption.py | 4 +- .../s3_bucket_level_public_access_block.py | 4 +- .../s3_bucket_no_mfa_delete.py | 4 +- .../s3_bucket_object_lock.py | 4 +- .../s3_bucket_object_versioning.py | 4 +- .../s3_bucket_policy_public_write_access.py | 4 +- .../s3_bucket_public_access.py | 4 +- .../s3_bucket_public_list_acl.py | 4 +- .../s3_bucket_public_write_acl.py | 4 +- .../s3_bucket_secure_transport_policy.py | 4 +- ...s3_bucket_server_access_logging_enabled.py | 4 +- .../providers/aws/services/s3/s3_service.py | 46 ++++---- ...udtrail_bucket_requires_mfa_delete_test.py | 6 +- ...s_s3_bucket_access_logging_enabled_test.py | 4 +- ..._bucket_is_not_publicly_accessible_test.py | 4 +- .../macie_is_enabled/macie_is_enabled_test.py | 6 +- ...3_bucket_level_public_access_block_test.py | 3 +- .../s3_bucket_no_mfa_delete_test.py | 3 +- .../s3_bucket_public_access_test.py | 3 +- .../aws/services/s3/s3_service_test.py | 105 ++++++++---------- 25 files changed, 111 insertions(+), 127 deletions(-) diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py index e333a7d94e..de78c8504d 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.py @@ -20,7 +20,7 @@ class cloudtrail_bucket_requires_mfa_delete(Check): report.resource_tags = trail.tags report.status = "FAIL" report.status_extended = f"Trail {trail.name} bucket ({trail_bucket}) does not have MFA delete enabled." - for bucket in s3_client.buckets: + for bucket in s3_client.buckets.values(): if trail_bucket == bucket.name: trail_bucket_is_in_account = True if bucket.mfa_delete: diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py index 2717da6d30..7cdabd89fe 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.py @@ -23,7 +23,7 @@ class cloudtrail_logs_s3_bucket_access_logging_enabled(Check): report.status_extended = f"Multiregion Trail {trail.name} S3 bucket access logging is not enabled for bucket {trail_bucket}." else: report.status_extended = f"Single region Trail {trail.name} S3 bucket access logging is not enabled for bucket {trail_bucket}." - for bucket in s3_client.buckets: + for bucket in s3_client.buckets.values(): if trail_bucket == bucket.name: trail_bucket_is_in_account = True if bucket.logging: diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py index 6b8246b1ce..67f981ddd0 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.py @@ -23,7 +23,7 @@ class cloudtrail_logs_s3_bucket_is_not_publicly_accessible(Check): report.status_extended = f"S3 Bucket {trail_bucket} from multiregion trail {trail.name} is not publicly accessible." else: report.status_extended = f"S3 Bucket {trail_bucket} from single region trail {trail.name} is not publicly accessible." - for bucket in s3_client.buckets: + for bucket in s3_client.buckets.values(): # Here we need to ensure that acl_grantee is filled since if we don't have permissions to query the api for a concrete region # (for example due to a SCP) we are going to try access an attribute from a None type if trail_bucket == bucket.name: diff --git a/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.py b/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.py index f23aca60c1..8e4d7fff92 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.py +++ b/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_acl_prohibited(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags report.status = "FAIL" report.status_extended = f"S3 Bucket {bucket.name} has bucket ACLs enabled." diff --git a/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.py b/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.py index 84a9422f22..b6ada18aec 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.py +++ b/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_default_encryption(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags if bucket.encryption: report.status = "PASS" diff --git a/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.py b/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.py index 5f50e8bc86..00eed7d395 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.py +++ b/prowler/providers/aws/services/s3/s3_bucket_kms_encryption/s3_bucket_kms_encryption.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_kms_encryption(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags if bucket.encryption == "aws:kms" or bucket.encryption == "aws:kms:dsse": diff --git a/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.py b/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.py index dbfbfcfd85..d1fc1623ed 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.py +++ b/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.py @@ -6,12 +6,12 @@ from prowler.providers.aws.services.s3.s3control_client import s3control_client class s3_bucket_level_public_access_block(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): if bucket.public_access_block: report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags report.status = "PASS" report.status_extended = f"Block Public Access is configured for the S3 Bucket {bucket.name}." diff --git a/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.py b/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.py index 0351c8940b..d070b0a2c2 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.py +++ b/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_no_mfa_delete(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags if bucket.mfa_delete: report.status = "PASS" diff --git a/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.py b/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.py index 2bfde6a838..8339ee9021 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.py +++ b/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_object_lock(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags if bucket.object_lock: report.status = "PASS" diff --git a/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.py b/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.py index 326ff240ea..e8617869cf 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.py +++ b/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_object_versioning(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags if bucket.versioning: report.status = "PASS" diff --git a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.py b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.py index 8828702290..33353d243b 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.py +++ b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.py @@ -6,11 +6,11 @@ from prowler.providers.aws.services.s3.s3control_client import s3control_client class s3_bucket_policy_public_write_access(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags # Check if bucket policy allow public write access if not bucket.policy: diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.py b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.py index 859659e898..a8658c094d 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.py +++ b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.py @@ -27,12 +27,12 @@ class s3_bucket_public_access(Check): findings.append(report) else: # 2. If public access is not blocked at account level, check it at each bucket level - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): if bucket.public_access_block: report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags report.status = "PASS" report.status_extended = f"S3 Bucket {bucket.name} is not public." diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.py b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.py index aa6132017b..ca319e3a27 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.py +++ b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.py @@ -21,12 +21,12 @@ class s3_bucket_public_list_acl(Check): findings.append(report) else: # 2. If public access is not blocked at account level, check it at each bucket level - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): if bucket.public_access_block: report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags report.status = "PASS" report.status_extended = ( diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.py b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.py index 5a32c1680e..1775941aa5 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.py +++ b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.py @@ -21,12 +21,12 @@ class s3_bucket_public_write_acl(Check): findings.append(report) else: # 2. If public access is not blocked at account level, check it at each bucket level - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): if bucket.public_access_block: report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags report.status = "PASS" report.status_extended = ( diff --git a/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.py b/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.py index 0a8a193d3b..3c627712aa 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.py +++ b/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_secure_transport_policy(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags # Check if bucket policy enforces SSL if not bucket.policy: diff --git a/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.py b/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.py index b98b15934e..425400fc2c 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.py +++ b/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.py @@ -5,11 +5,11 @@ from prowler.providers.aws.services.s3.s3_client import s3_client class s3_bucket_server_access_logging_enabled(Check): def execute(self): findings = [] - for bucket in s3_client.buckets: + for arn, bucket in s3_client.buckets.items(): report = Check_Report_AWS(self.metadata()) report.region = bucket.region report.resource_id = bucket.name - report.resource_arn = bucket.arn + report.resource_arn = arn report.resource_tags = bucket.tags if bucket.logging: report.status = "PASS" diff --git a/prowler/providers/aws/services/s3/s3_service.py b/prowler/providers/aws/services/s3/s3_service.py index f525ecf814..950c93f96f 100644 --- a/prowler/providers/aws/services/s3/s3_service.py +++ b/prowler/providers/aws/services/s3/s3_service.py @@ -15,20 +15,24 @@ class S3(AWSService): super().__init__(__class__.__name__, provider) self.account_arn_template = f"arn:{self.audited_partition}:s3:{self.region}:{self.audited_account}:account" self.regions_with_buckets = [] - self.buckets = self._list_buckets(provider) - self.__threading_call__(self._get_bucket_versioning, self.buckets) - self.__threading_call__(self._get_bucket_logging, self.buckets) - self.__threading_call__(self._get_bucket_policy, self.buckets) - self.__threading_call__(self._get_bucket_acl, self.buckets) - self.__threading_call__(self._get_public_access_block, self.buckets) - self.__threading_call__(self._get_bucket_encryption, self.buckets) - self.__threading_call__(self._get_bucket_ownership_controls, self.buckets) - self.__threading_call__(self._get_object_lock_configuration, self.buckets) - self.__threading_call__(self._get_bucket_tagging, self.buckets) + self.buckets = {} + self._list_buckets(provider) + self.__threading_call__(self._get_bucket_versioning, self.buckets.values()) + self.__threading_call__(self._get_bucket_logging, self.buckets.values()) + self.__threading_call__(self._get_bucket_policy, self.buckets.values()) + self.__threading_call__(self._get_bucket_acl, self.buckets.values()) + self.__threading_call__(self._get_public_access_block, self.buckets.values()) + self.__threading_call__(self._get_bucket_encryption, self.buckets.values()) + self.__threading_call__( + self._get_bucket_ownership_controls, self.buckets.values() + ) + self.__threading_call__( + self._get_object_lock_configuration, self.buckets.values() + ) + self.__threading_call__(self._get_bucket_tagging, self.buckets.values()) def _list_buckets(self, provider): logger.info("S3 - Listing buckets...") - buckets = [] try: list_buckets = self.client.list_buckets() for bucket in list_buckets["Buckets"]: @@ -47,21 +51,17 @@ class S3(AWSService): ): self.regions_with_buckets.append(bucket_region) # Check if there are filter regions + # FIXME: what if the bucket comes from a CloudTrail bucket in another audited region if provider.identity.audited_regions: - # FIXME: what if the bucket comes from a CloudTrail bucket in another audited region if bucket_region in provider.identity.audited_regions: - buckets.append( - Bucket( - name=bucket["Name"], - arn=arn, - region=bucket_region, - ) + self.buckets[arn] = Bucket( + name=bucket["Name"], + region=bucket_region, ) else: - buckets.append( - Bucket( - name=bucket["Name"], arn=arn, region=bucket_region - ) + self.buckets[arn] = Bucket( + name=bucket["Name"], + region=bucket_region, ) except ClientError as error: if error.response["Error"]["Code"] == "NoSuchBucket": @@ -89,7 +89,6 @@ class S3(AWSService): logger.error( f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - return buckets def _get_bucket_versioning(self, bucket): logger.info("S3 - Get buckets versioning...") @@ -492,7 +491,6 @@ class AccessPoint(BaseModel): class Bucket(BaseModel): name: str - arn: str versioning: bool = False logging: bool = False public_access_block: Optional[PublicAccessBlock] diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py index 880f0b5c72..b5925ed189 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete_test.py @@ -185,7 +185,7 @@ class Test_cloudtrail_bucket_requires_mfa_delete: ) # Empty s3 buckets to simulate the bucket is in another account - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_bucket_requires_mfa_delete() result = check.execute() @@ -240,7 +240,7 @@ class Test_cloudtrail_bucket_requires_mfa_delete: ) # Empty s3 buckets to simulate the bucket is in another account - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_bucket_requires_mfa_delete() result = check.execute() @@ -281,7 +281,7 @@ class Test_cloudtrail_bucket_requires_mfa_delete: ) cloudtrail_client.trails = None - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_bucket_requires_mfa_delete() result = check.execute() diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py index f1a81ef7cd..0d92f84f00 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled_test.py @@ -199,7 +199,7 @@ class Test_cloudtrail_logs_s3_bucket_access_logging_enabled: ) # Empty s3 buckets to simulate the bucket is in another account - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_logs_s3_bucket_access_logging_enabled() result = check.execute() @@ -242,7 +242,7 @@ class Test_cloudtrail_logs_s3_bucket_access_logging_enabled: ) cloudtrail_client.trails = None - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_logs_s3_bucket_access_logging_enabled() result = check.execute() diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py index aca891fe7b..52809f8f39 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible_test.py @@ -258,7 +258,7 @@ class Test_cloudtrail_logs_s3_bucket_is_not_publicly_accessible: ) # Empty s3 buckets to simulate the bucket is in another account - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_logs_s3_bucket_is_not_publicly_accessible() result = check.execute() @@ -300,7 +300,7 @@ class Test_cloudtrail_logs_s3_bucket_is_not_publicly_accessible: ) cloudtrail_client.trails = None - s3_client.buckets = [] + s3_client.buckets = {} check = cloudtrail_logs_s3_bucket_is_not_publicly_accessible() result = check.execute() diff --git a/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py b/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py index 8c433a6057..e495490ef4 100644 --- a/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py +++ b/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py @@ -16,7 +16,7 @@ class Test_macie_is_enabled: def test_macie_disabled(self): s3_client = mock.MagicMock s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) - s3_client.buckets = [] + s3_client.buckets = {} s3_client.regions_with_buckets = [] macie_client = mock.MagicMock @@ -68,7 +68,7 @@ class Test_macie_is_enabled: def test_macie_enabled(self): s3_client = mock.MagicMock s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) - s3_client.buckets = [] + s3_client.buckets = {} s3_client.regions_with_buckets = [] macie_client = mock.MagicMock @@ -120,7 +120,7 @@ class Test_macie_is_enabled: def test_macie_suspended_ignored(self): s3_client = mock.MagicMock s3_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) - s3_client.buckets = [] + s3_client.buckets = {} s3_client.regions_with_buckets = [] macie_client = mock.MagicMock diff --git a/tests/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block_test.py b/tests/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block_test.py index 4b5754b04a..f9eed46ddf 100644 --- a/tests/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block_test.py @@ -228,6 +228,7 @@ class Test_s3_bucket_level_public_access_block: def test_bucket_can_not_retrieve_public_access_block(self): s3_client = client("s3", region_name=AWS_REGION_US_EAST_1) bucket_name_us = "bucket_test_us" + bucket_arn = f"arn:aws:s3:::{bucket_name_us}" s3_client.create_bucket(Bucket=bucket_name_us) s3_client.put_public_access_block( Bucket=bucket_name_us, @@ -258,7 +259,7 @@ class Test_s3_bucket_level_public_access_block: ): # To test this behaviour we need to set public_access_block to None s3 = S3(aws_provider) - s3.buckets[0].public_access_block = None + s3.buckets[bucket_arn].public_access_block = None with mock.patch( "prowler.providers.aws.services.s3.s3_bucket_level_public_access_block.s3_bucket_level_public_access_block.s3_client", diff --git a/tests/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete_test.py b/tests/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete_test.py index 5d6b97f514..e95af63d35 100644 --- a/tests/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete_test.py @@ -73,6 +73,7 @@ class Test_s3_bucket_no_mfa_delete: def test_bucket_with_mfa(self): s3_client_us_east_1 = client("s3", region_name="us-east-1") bucket_name_us = "bucket_test_us" + bucket_arn = f"arn:aws:s3:::{bucket_name_us}" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) s3_client_us_east_1.put_bucket_versioning( Bucket=bucket_name_us, @@ -95,7 +96,7 @@ class Test_s3_bucket_no_mfa_delete: s3_bucket_no_mfa_delete, ) - service_client.buckets[0].mfa_delete = True + service_client.buckets[bucket_arn].mfa_delete = True check = s3_bucket_no_mfa_delete() result = check.execute() diff --git a/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_test.py b/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_test.py index bab8c85f66..d7ce430e61 100644 --- a/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_test.py @@ -665,6 +665,7 @@ class Test_s3_bucket_public_access: def test_bucket_can_not_retrieve_public_access_block(self): s3_client = client("s3", region_name=AWS_REGION_US_EAST_1) bucket_name_us = "bucket_test_us" + bucket_arn = f"arn:aws:s3:::{bucket_name_us}" s3_client.create_bucket(Bucket=bucket_name_us) s3_client.put_public_access_block( Bucket=bucket_name_us, @@ -685,7 +686,7 @@ class Test_s3_bucket_public_access: ): # To test this behaviour we need to set public_access_block to None s3 = S3(aws_provider) - s3.buckets[0].public_access_block = None + s3.buckets[bucket_arn].public_access_block = None with mock.patch( "prowler.providers.aws.services.s3.s3_bucket_public_access.s3_bucket_public_access.s3_client", new=s3, diff --git a/tests/providers/aws/services/s3/s3_service_test.py b/tests/providers/aws/services/s3/s3_service_test.py index 696b719be2..4365b190c6 100644 --- a/tests/providers/aws/services/s3/s3_service_test.py +++ b/tests/providers/aws/services/s3/s3_service_test.py @@ -72,6 +72,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket(Bucket=bucket_name) # S3 client for this test class @@ -79,12 +80,9 @@ class Test_S3_Service: s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert not s3.buckets[0].object_lock + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert not s3.buckets[bucket_arn].object_lock # Test S3 Get Bucket Versioning @mock_aws @@ -93,6 +91,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket(Bucket=bucket_name) # Set Bucket Versioning s3_client.put_bucket_versioning( @@ -103,18 +102,16 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].versioning is True + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].versioning is True # Test S3 Get Bucket ACL @mock_aws def test_get_bucket_acl(self): s3_client = client("s3") bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket(Bucket=bucket_name) s3_client.put_bucket_acl( AccessControlPolicy={ @@ -136,16 +133,13 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].acl_grantees[0].display_name == "test" + assert s3.buckets[bucket_arn].acl_grantees[0].ID == "test_ID" + assert s3.buckets[bucket_arn].acl_grantees[0].type == "Group" assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].acl_grantees[0].display_name == "test" - assert s3.buckets[0].acl_grantees[0].ID == "test_ID" - assert s3.buckets[0].acl_grantees[0].type == "Group" - assert ( - s3.buckets[0].acl_grantees[0].URI + s3.buckets[bucket_arn].acl_grantees[0].URI == "http://acs.amazonaws.com/groups/global/AllUsers" ) @@ -156,6 +150,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket( Bucket=bucket_name, ) @@ -216,18 +211,16 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].logging is True + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].logging is True # Test S3 Get Bucket Policy @mock_aws def test_get_bucket_policy(self): s3_client = client("s3") bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket(Bucket=bucket_name) ssl_policy = '{"Version": "2012-10-17","Id": "PutObjPolicy","Statement": [{"Sid": "s3-bucket-ssl-requests-only","Effect": "Deny","Principal": "*","Action": "s3:GetObject","Resource": "arn:aws:s3:::bucket_test_us/*","Condition": {"Bool": {"aws:SecureTransport": "false"}}}]}' s3_client.put_bucket_policy( @@ -237,12 +230,9 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].policy == json.loads(ssl_policy) + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].policy == json.loads(ssl_policy) # Test S3 Get Bucket Encryption @mock_aws @@ -251,6 +241,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket(Bucket=bucket_name) sse_config = { "Rules": [ @@ -270,12 +261,9 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].encryption == "aws:kms" + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].encryption == "aws:kms" # Test S3 Get Bucket Ownership Controls @mock_aws @@ -284,6 +272,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket( Bucket=bucket_name, ObjectOwnership="BucketOwnerEnforced" ) @@ -292,12 +281,9 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].ownership == "BucketOwnerEnforced" + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].ownership == "BucketOwnerEnforced" # Test S3 Get Public Access Block @mock_aws @@ -306,6 +292,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket( Bucket=bucket_name, ObjectOwnership="BucketOwnerEnforced" ) @@ -322,15 +309,12 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].public_access_block.block_public_acls - assert s3.buckets[0].public_access_block.ignore_public_acls - assert s3.buckets[0].public_access_block.block_public_policy - assert s3.buckets[0].public_access_block.restrict_public_buckets + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].public_access_block.block_public_acls + assert s3.buckets[bucket_arn].public_access_block.ignore_public_acls + assert s3.buckets[bucket_arn].public_access_block.block_public_policy + assert s3.buckets[bucket_arn].public_access_block.restrict_public_buckets # Test S3 Get Bucket Tagging @mock_aws @@ -339,6 +323,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket(Bucket=bucket_name) s3_client.put_bucket_tagging( Bucket=bucket_name, @@ -353,7 +338,7 @@ class Test_S3_Service: s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].tags == [ + assert s3.buckets[bucket_arn].tags == [ {"Key": "test", "Value": "test"}, ] @@ -386,6 +371,7 @@ class Test_S3_Service: s3_client = client("s3") # Create S3 Bucket bucket_name = "test-bucket" + bucket_arn = f"arn:aws:s3:::{bucket_name}" s3_client.create_bucket( Bucket=bucket_name, ObjectOwnership="BucketOwnerEnforced", @@ -396,12 +382,9 @@ class Test_S3_Service: aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) s3 = S3(aws_provider) assert len(s3.buckets) == 1 - assert s3.buckets[0].name == bucket_name - assert ( - s3.buckets[0].arn - == f"arn:{aws_provider.identity.partition}:s3:::{bucket_name}" - ) - assert s3.buckets[0].object_lock + assert s3.buckets[bucket_arn].name == bucket_name + assert s3.buckets[bucket_arn].region == AWS_REGION_US_EAST_1 + assert s3.buckets[bucket_arn].object_lock # Test S3 List Access Points @patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)