mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
fix(s3): Add S3 ResourceArn (#1666)
Co-authored-by: sergargar <sergio@verica.io>
This commit is contained in:
@@ -9,6 +9,7 @@ class s3_bucket_acl_prohibited(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"S3 Bucket {bucket.name} has bucket ACLs enabled."
|
||||
if bucket.ownership:
|
||||
|
||||
@@ -9,6 +9,7 @@ class s3_bucket_default_encryption(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
if bucket.encryption:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"S3 Bucket {bucket.name} has Server Side Encryption with {bucket.encryption}."
|
||||
|
||||
@@ -9,6 +9,7 @@ class s3_bucket_no_mfa_delete(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
if bucket.mfa_delete:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
|
||||
@@ -9,6 +9,7 @@ class s3_bucket_object_versioning(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
if bucket.versioning:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
|
||||
@@ -9,6 +9,7 @@ class s3_bucket_policy_public_write_access(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
# Check if bucket policy allow public write access
|
||||
if not bucket.policy:
|
||||
report.status = "PASS"
|
||||
|
||||
@@ -24,6 +24,7 @@ class s3_bucket_public_access(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"S3 Bucket {bucket.name} is not public."
|
||||
if not (
|
||||
|
||||
@@ -9,6 +9,7 @@ class s3_bucket_secure_transport_policy(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
# Check if bucket policy enforces SSL
|
||||
if not bucket.policy:
|
||||
report.status = "FAIL"
|
||||
|
||||
@@ -9,6 +9,7 @@ class s3_bucket_server_access_logging_enabled(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = bucket.region
|
||||
report.resource_id = bucket.name
|
||||
report.resource_arn = bucket.arn
|
||||
if bucket.logging:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
|
||||
@@ -13,6 +13,7 @@ class S3:
|
||||
self.session = audit_info.audit_session
|
||||
self.client = self.session.client(self.service)
|
||||
self.audited_account = audit_info.audited_account
|
||||
self.audited_partition = audit_info.audited_partition
|
||||
self.regional_clients = generate_regional_clients(self.service, audit_info)
|
||||
self.buckets = self.__list_buckets__(audit_info)
|
||||
self.__threading_call__(self.__get_bucket_versioning__)
|
||||
@@ -47,12 +48,14 @@ class S3:
|
||||
)["LocationConstraint"]
|
||||
if not bucket_region: # If us-east-1, bucket_region is none
|
||||
bucket_region = "us-east-1"
|
||||
# Arn
|
||||
arn = f"arn:{self.audited_partition}:s3:::{bucket['Name']}"
|
||||
# Check if there are filter regions
|
||||
if audit_info.audited_regions:
|
||||
if bucket_region in audit_info.audited_regions:
|
||||
buckets.append(Bucket(bucket["Name"], bucket_region))
|
||||
buckets.append(Bucket(bucket["Name"], arn, bucket_region))
|
||||
else:
|
||||
buckets.append(Bucket(bucket["Name"], bucket_region))
|
||||
buckets.append(Bucket(bucket["Name"], arn, bucket_region))
|
||||
except Exception as error:
|
||||
logger.error(
|
||||
f"{bucket_region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
@@ -268,6 +271,7 @@ class PublicAccessBlock:
|
||||
@dataclass
|
||||
class Bucket:
|
||||
name: str
|
||||
arn: str
|
||||
versioning: bool
|
||||
logging: bool
|
||||
public_access_block: PublicAccessBlock
|
||||
@@ -279,8 +283,9 @@ class Bucket:
|
||||
ownership: str
|
||||
mfa_delete: bool
|
||||
|
||||
def __init__(self, name, region):
|
||||
def __init__(self, name, arn, region):
|
||||
self.name = name
|
||||
self.arn = arn
|
||||
self.versioning = False
|
||||
self.logging = False
|
||||
# Set all block as False
|
||||
|
||||
@@ -36,6 +36,10 @@ class Test_s3_bucket_acl_prohibited:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -68,6 +72,10 @@ class Test_s3_bucket_acl_prohibited:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -102,4 +110,8 @@ class Test_s3_bucket_acl_prohibited:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@@ -36,6 +36,10 @@ class Test_s3_bucket_default_encryption:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -83,4 +87,8 @@ class Test_s3_bucket_default_encryption:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@@ -60,6 +60,10 @@ class Test_s3_bucket_no_mfa_delete:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
|
||||
@mock_s3
|
||||
def test_bucket_with_mfa(self):
|
||||
@@ -95,3 +99,7 @@ class Test_s3_bucket_no_mfa_delete:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
|
||||
@@ -36,6 +36,10 @@ class Test_s3_bucket_object_versioning:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -73,4 +77,8 @@ class Test_s3_bucket_object_versioning:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@@ -36,6 +36,10 @@ class Test_s3_bucket_policy_public_write_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -75,6 +79,10 @@ class Test_s3_bucket_policy_public_write_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -113,4 +121,8 @@ class Test_s3_bucket_policy_public_write_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@@ -216,6 +216,10 @@ class Test_s3_bucket_public_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
@mock_s3
|
||||
@@ -291,6 +295,10 @@ class Test_s3_bucket_public_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
@mock_s3
|
||||
@@ -355,6 +363,10 @@ class Test_s3_bucket_public_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
@mock_s3
|
||||
@@ -403,4 +415,8 @@ class Test_s3_bucket_public_access:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
@@ -36,6 +36,10 @@ class Test_s3_bucket_secure_transport_policy:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -92,6 +96,10 @@ class Test_s3_bucket_secure_transport_policy:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@mock_s3
|
||||
@@ -148,4 +156,8 @@ class Test_s3_bucket_secure_transport_policy:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
assert result[0].region == "us-east-1"
|
||||
|
||||
@@ -38,6 +38,10 @@ class Test_s3_bucket_server_access_logging_enabled:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
|
||||
@mock_s3
|
||||
def test_bucket_with_logging(self):
|
||||
@@ -123,3 +127,7 @@ class Test_s3_bucket_server_access_logging_enabled:
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == bucket_name_us
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:{current_audit_info.audited_partition}:s3:::{bucket_name_us}"
|
||||
)
|
||||
|
||||
@@ -80,6 +80,10 @@ class Test_S3_Service:
|
||||
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name}"
|
||||
)
|
||||
|
||||
# Test S3 Get Bucket Versioning
|
||||
@mock_s3
|
||||
@@ -99,6 +103,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name}"
|
||||
)
|
||||
assert s3.buckets[0].versioning is True
|
||||
|
||||
# Test S3 Get Bucket ACL
|
||||
@@ -128,6 +136,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_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"
|
||||
@@ -204,6 +216,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name}"
|
||||
)
|
||||
assert s3.buckets[0].logging is True
|
||||
|
||||
# Test S3 Get Bucket Policy
|
||||
@@ -221,6 +237,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name}"
|
||||
)
|
||||
assert s3.buckets[0].policy == json.loads(ssl_policy)
|
||||
|
||||
# Test S3 Get Bucket Encryption
|
||||
@@ -250,6 +270,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name}"
|
||||
)
|
||||
assert s3.buckets[0].encryption == "aws:kms"
|
||||
|
||||
# Test S3 Get Bucket Ownership Controls
|
||||
@@ -268,6 +292,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_partition}:s3:::{bucket_name}"
|
||||
)
|
||||
assert s3.buckets[0].ownership == "BucketOwnerEnforced"
|
||||
|
||||
# Test S3 Get Public Access Block
|
||||
@@ -294,6 +322,10 @@ class Test_S3_Service:
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert (
|
||||
s3.buckets[0].arn
|
||||
== f"arn:{audit_info.audited_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
|
||||
|
||||
Reference in New Issue
Block a user