feat(s3): Add checks for publicly listable Buckets or writable buckets by ACL (#2628)

Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
Chris Farris
2023-07-31 02:35:18 -04:00
committed by GitHub
parent 4a674aae99
commit 03ad403e7a
30 changed files with 1632 additions and 24 deletions

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "high",
"ResourceType": "AwsS3Bucket",
"Description": "Check S3 Account Level Public Access Block.",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have ACLs enabled",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have default encryption (SSE) enabled or use a bucket policy to enforce it.",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check S3 Bucket Level Public Access Block.",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 bucket MFA Delete is not enabled.",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:s3:::bucket-name",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "low",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have object lock enabled",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have object versioning enabled",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "critical",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have policies which allow WRITE access.",

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "critical",
"ResourceType": "AwsS3Bucket",
"Description": "Ensure there are no S3 buckets open to Everyone or Any AWS user.",

View File

@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "s3_bucket_public_list_acl",
"CheckTitle": "Ensure there are no S3 buckets listable by Everyone or Any AWS customer.",
"CheckType": [
"Data Protection"
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "critical",
"ResourceType": "AwsS3Bucket",
"Description": "Ensure there are no S3 buckets listable by Everyone or Any AWS customer.",
"Risk": "Even if you enable all possible bucket ACL options available in the Amazon S3 console the ACL alone does not allow everyone to download objects from your bucket. Depending on which option you select any user could perform some actions.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "aws s3api put-bucket-acl --bucket <bucket_name> --acl private",
"NativeIaC": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/s3-bucket-public-read-access.html",
"Other": "",
"Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/s3-bucket-public-read-access.html"
},
"Recommendation": {
"Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account; the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.",
"Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html"
}
},
"Categories": [
"internet-exposed"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

View File

@@ -0,0 +1,54 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.s3.s3_client import s3_client
from prowler.providers.aws.services.s3.s3control_client import s3control_client
class s3_bucket_public_list_acl(Check):
def execute(self):
findings = []
# 1. Check if public buckets are restricted at account level
if (
s3control_client.account_public_access_block
and s3control_client.account_public_access_block.ignore_public_acls
and s3control_client.account_public_access_block.restrict_public_buckets
):
report = Check_Report_AWS(self.metadata())
report.status = "PASS"
report.status_extended = "All S3 public access blocked at account level."
report.region = s3control_client.region
report.resource_id = s3_client.audited_account
report.resource_arn = s3_client.audited_account_arn
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:
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_tags = bucket.tags
report.status = "PASS"
report.status_extended = (
f"S3 Bucket {bucket.name} is not publicly listable."
)
if not (
bucket.public_access_block.ignore_public_acls
and bucket.public_access_block.restrict_public_buckets
):
# 3. If bucket has no public block, check bucket ACL
for grantee in bucket.acl_grantees:
if grantee.type in "Group":
if (
"AllUsers" in grantee.URI
or "AuthenticatedUsers" in grantee.URI
) and (
grantee.permission == "FULL_CONTROL"
or grantee.permission == "READ"
or grantee.permission == "READ_ACP"
):
report.status = "FAIL"
report.status_extended = f"S3 Bucket {bucket.name} is listable by anyone due to the bucket ACL: {grantee.URI.split('/')[-1]} having the {grantee.permission} permission."
findings.append(report)
return findings

View File

@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "s3_bucket_public_write_acl",
"CheckTitle": "Ensure there are no S3 buckets writable by Everyone or Any AWS customer.",
"CheckType": [
"Data Protection"
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "critical",
"ResourceType": "AwsS3Bucket",
"Description": "Ensure there are no S3 buckets writable by Everyone or Any AWS customer.",
"Risk": "Even if you enable all possible bucket ACL options available in the Amazon S3 console the ACL alone does not allow everyone to download objects from your bucket. Depending on which option you select any user could perform some actions.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "aws s3api put-bucket-acl --bucket <bucket_name> --acl private",
"NativeIaC": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/s3-bucket-public-write-access.html",
"Other": "",
"Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/S3/s3-bucket-public-write-access.html"
},
"Recommendation": {
"Text": "You can enable block public access settings only for access points, buckets and AWS accounts. Amazon S3 does not support block public access settings on a per-object basis. When you apply block public access settings to an account; the settings apply to all AWS Regions globally. The settings might not take effect in all Regions immediately or simultaneously, but they eventually propagate to all Regions.",
"Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html"
}
},
"Categories": [
"internet-exposed"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

View File

@@ -0,0 +1,53 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.s3.s3_client import s3_client
from prowler.providers.aws.services.s3.s3control_client import s3control_client
class s3_bucket_public_write_acl(Check):
def execute(self):
findings = []
# 1. Check if public buckets are restricted at account level
if (
s3control_client.account_public_access_block
and s3control_client.account_public_access_block.ignore_public_acls
and s3control_client.account_public_access_block.restrict_public_buckets
):
report = Check_Report_AWS(self.metadata())
report.status = "PASS"
report.status_extended = "All S3 public access blocked at account level."
report.region = s3control_client.region
report.resource_id = s3_client.audited_account
report.resource_arn = s3_client.audited_account_arn
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:
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_tags = bucket.tags
report.status = "PASS"
report.status_extended = (
f"S3 Bucket {bucket.name} is not publicly writable."
)
if not (
bucket.public_access_block.ignore_public_acls
and bucket.public_access_block.restrict_public_buckets
):
# 3. If bucket has no public block, check bucket ACL
for grantee in bucket.acl_grantees:
if grantee.type in "Group":
if (
"AllUsers" in grantee.URI
or "AuthenticatedUsers" in grantee.URI
) and (
grantee.permission == "FULL_CONTROL"
or grantee.permission == "WRITE"
or grantee.permission == "WRITE_ACP"
):
report.status = "FAIL"
report.status_extended = f"S3 Bucket {bucket.name} is writable by anyone due to the bucket ACL: {grantee.URI.split('/')[-1]} having the {grantee.permission} permission."
findings.append(report)
return findings

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have secure transport policy.",
@@ -31,4 +31,4 @@
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
}

View File

@@ -7,7 +7,7 @@
],
"ServiceName": "s3",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"ResourceIdTemplate": "arn:partition:s3:::bucket_name",
"Severity": "medium",
"ResourceType": "AwsS3Bucket",
"Description": "Check if S3 buckets have server access logging enabled",
@@ -31,4 +31,4 @@
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
}

View File

@@ -6,6 +6,7 @@ from moto import mock_s3, mock_s3control
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -21,7 +22,7 @@ class Test_s3_account_level_public_access_blocks:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
@@ -81,6 +82,7 @@ class Test_s3_account_level_public_access_blocks:
== f"Block Public Access is configured for the account {AWS_ACCOUNT_NUMBER}."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3
@@ -128,4 +130,5 @@ class Test_s3_account_level_public_access_blocks:
== f"Block Public Access is not configured for the account {AWS_ACCOUNT_NUMBER}."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_acl_prohibited:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -8,6 +8,7 @@ from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_REGION = "us-east-1"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
class Test_s3_bucket_default_encryption:
@@ -22,7 +23,7 @@ class Test_s3_bucket_default_encryption:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -8,6 +8,7 @@ from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_REGION = "us-east-1"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
class Test_s3_bucket_level_public_access_block:
@@ -22,7 +23,7 @@ class Test_s3_bucket_level_public_access_block:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_no_mfa_delete:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_object_lock:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_object_versioning:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_policy_public_write_access:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -7,6 +7,7 @@ from moto import mock_s3, mock_s3control
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_public_access:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
@@ -111,6 +112,7 @@ class Test_s3_bucket_public_access:
== "All S3 public access blocked at account level."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3
@@ -161,6 +163,7 @@ class Test_s3_bucket_public_access:
== "All S3 public access blocked at account level."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3

View File

@@ -0,0 +1,709 @@
from unittest import mock
from boto3 import client, session
from moto import mock_s3, mock_s3control
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
class Test_s3_bucket_public_list_acl:
# Mocked Audit Info
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
session_config=None,
original_session=None,
audit_session=session.Session(
profile_name=None,
botocore_session=None,
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
profile=None,
profile_region=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
organizations_metadata=None,
audit_resources=None,
mfa_enabled=False,
)
return audit_info
@mock_s3
@mock_s3control
def test_no_buckets(self):
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 0
@mock_s3
@mock_s3control
def test_bucket_account_public_block_without_buckets(self):
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "All S3 public access blocked at account level."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3
@mock_s3control
def test_bucket_account_public_block(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "All S3 public access blocked at account level."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3
@mock_s3control
def test_bucket_public_block(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is not publicly listable."
)
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
@mock_s3control
def test_bucket_public_list_ACL_AllUsers_READ(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
"Type": "Group",
},
"Permission": "READ",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is listable by anyone due to the bucket ACL: AllUsers having the READ permission."
)
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
@mock_s3control
def test_bucket_public_list_ACL_AllUsers_READ_ACP(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
"Type": "Group",
},
"Permission": "READ_ACP",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is listable by anyone due to the bucket ACL: AllUsers having the READ_ACP permission."
)
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
@mock_s3control
def test_bucket_public_list_ACL_AllUsers_FULL_CONTROL(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
"Type": "Group",
},
"Permission": "FULL_CONTROL",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is listable by anyone due to the bucket ACL: AllUsers having the FULL_CONTROL permission."
)
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
@mock_s3control
def test_bucket_public_list_ACL_AuthenticatedUsers_READ(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
"Type": "Group",
},
"Permission": "READ",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is listable by anyone due to the bucket ACL: AuthenticatedUsers having the READ permission."
)
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
@mock_s3control
def test_bucket_public_list_ACL_AuthenticatedUsers_READ_ACP(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
"Type": "Group",
},
"Permission": "READ_ACP",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is listable by anyone due to the bucket ACL: AuthenticatedUsers having the READ_ACP permission."
)
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
@mock_s3control
def test_bucket_public_list_ACL_AuthenticatedUsers_FULL_CONTROL(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
"Type": "Group",
},
"Permission": "FULL_CONTROL",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl import (
s3_bucket_public_list_acl,
)
check = s3_bucket_public_list_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is listable by anyone due to the bucket ACL: AuthenticatedUsers having the FULL_CONTROL permission."
)
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

View File

@@ -0,0 +1,709 @@
from unittest import mock
from boto3 import client, session
from moto import mock_s3, mock_s3control
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
class Test_s3_bucket_public_write_acl:
# Mocked Audit Info
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
session_config=None,
original_session=None,
audit_session=session.Session(
profile_name=None,
botocore_session=None,
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
profile=None,
profile_region=AWS_REGION,
credentials=None,
assumed_role_info=None,
audited_regions=None,
organizations_metadata=None,
audit_resources=None,
mfa_enabled=False,
)
return audit_info
@mock_s3
@mock_s3control
def test_no_buckets(self):
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 0
@mock_s3
@mock_s3control
def test_bucket_account_public_block_without_buckets(self):
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "All S3 public access blocked at account level."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3
@mock_s3control
def test_bucket_account_public_block(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "All S3 public access blocked at account level."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == AWS_ACCOUNT_ARN
assert result[0].region == AWS_REGION
@mock_s3
@mock_s3control
def test_bucket_public_block(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is not publicly writable."
)
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
@mock_s3control
def test_bucket_public_write_ACL_AllUsers_WRITE(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
"Type": "Group",
},
"Permission": "WRITE",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is writable by anyone due to the bucket ACL: AllUsers having the WRITE permission."
)
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
@mock_s3control
def test_bucket_public_write_ACL_AllUsers_WRITE_ACP(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
"Type": "Group",
},
"Permission": "WRITE_ACP",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is writable by anyone due to the bucket ACL: AllUsers having the WRITE_ACP permission."
)
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
@mock_s3control
def test_bucket_public_write_ACL_AllUsers_FULL_CONTROL(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
"Type": "Group",
},
"Permission": "FULL_CONTROL",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is writable by anyone due to the bucket ACL: AllUsers having the FULL_CONTROL permission."
)
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
@mock_s3control
def test_bucket_public_write_ACL_AuthenticatedUsers_WRITE(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
"Type": "Group",
},
"Permission": "WRITE",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is writable by anyone due to the bucket ACL: AuthenticatedUsers having the WRITE permission."
)
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
@mock_s3control
def test_bucket_public_write_ACL_AuthenticatedUsers_WRITE_ACP(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
"Type": "Group",
},
"Permission": "WRITE_ACP",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is writable by anyone due to the bucket ACL: AuthenticatedUsers having the WRITE_ACP permission."
)
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
@mock_s3control
def test_bucket_public_write_ACL_AuthenticatedUsers_FULL_CONTROL(self):
s3_client = client("s3", region_name=AWS_REGION)
bucket_name_us = "bucket_test_us"
s3_client.create_bucket(Bucket=bucket_name_us)
bucket_owner = s3_client.get_bucket_acl(Bucket=bucket_name_us)["Owner"]
# Generate S3Control Client
s3control_client = client("s3control", region_name=AWS_REGION)
s3control_client.put_public_access_block(
AccountId=AWS_ACCOUNT_NUMBER,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_public_access_block(
Bucket=bucket_name_us,
PublicAccessBlockConfiguration={
"BlockPublicAcls": False,
"IgnorePublicAcls": False,
"BlockPublicPolicy": False,
"RestrictPublicBuckets": False,
},
)
s3_client.put_bucket_acl(
Bucket=bucket_name_us,
AccessControlPolicy={
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
"Type": "Group",
},
"Permission": "FULL_CONTROL",
},
],
"Owner": bucket_owner,
},
)
from prowler.providers.aws.services.s3.s3_service import S3, S3Control
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3_client",
new=S3(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl.s3control_client",
new=S3Control(audit_info),
):
# Test Check
from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl import (
s3_bucket_public_write_acl,
)
check = s3_bucket_public_write_acl()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"S3 Bucket {bucket_name_us} is writable by anyone due to the bucket ACL: AuthenticatedUsers having the FULL_CONTROL permission."
)
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

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_secure_transport_policy:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,

View File

@@ -7,6 +7,7 @@ from moto import mock_s3
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_ACCOUNT_NUMBER = "123456789012"
AWS_ACCOUNT_ARN = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
AWS_REGION = "us-east-1"
@@ -22,7 +23,7 @@ class Test_s3_bucket_server_access_logging_enabled:
region_name=AWS_REGION,
),
audited_account=AWS_ACCOUNT_NUMBER,
audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root",
audited_account_arn=AWS_ACCOUNT_ARN,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,