diff --git a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json index 38ad8e59..18a4562d 100644 --- a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json +++ b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.metadata.json @@ -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.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.metadata.json index 044f24ff..aba852a0 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited.metadata.json @@ -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", diff --git a/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json index 74fb74e8..ed775ab6 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption.metadata.json @@ -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.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json index dc9c7be2..f742c35d 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_level_public_access_block/s3_bucket_level_public_access_block.metadata.json @@ -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.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json index d984eb09..4b0ce3e3 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_no_mfa_delete/s3_bucket_no_mfa_delete.metadata.json @@ -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.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json index ec917a24..67b34fda 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock.metadata.json @@ -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", diff --git a/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json index ca99e6e8..7f30ae81 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning.metadata.json @@ -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", diff --git a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json index d8d27c47..9e66b462 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access.metadata.json @@ -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.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json index 8578eec6..009030e5 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access.metadata.json @@ -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.", diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/__init__.py b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json new file mode 100644 index 00000000..68d062ec --- /dev/null +++ b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.metadata.json @@ -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 --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": "" +} 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 new file mode 100644 index 00000000..66a07819 --- /dev/null +++ b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl.py @@ -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 diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/__init__.py b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json new file mode 100644 index 00000000..46feea81 --- /dev/null +++ b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.metadata.json @@ -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 --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": "" +} 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 new file mode 100644 index 00000000..2693c3c4 --- /dev/null +++ b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl.py @@ -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 diff --git a/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json index 5c859625..cdf3520b 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy.metadata.json @@ -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": "" -} +} \ No newline at end of file diff --git a/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json b/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json index 63977b4f..05657ecf 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled.metadata.json @@ -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": "" -} +} \ No newline at end of file diff --git a/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py b/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py index 148b4f56..1a1c0b6e 100644 --- a/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py +++ b/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py @@ -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 diff --git a/tests/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited_test.py b/tests/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited_test.py index f2f0ccad..0821083a 100644 --- a/tests/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_acl_prohibited/s3_bucket_acl_prohibited_test.py @@ -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, diff --git a/tests/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption_test.py b/tests/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption_test.py index b7b2e38d..445df480 100644 --- a/tests/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_default_encryption/s3_bucket_default_encryption_test.py @@ -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, 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 d6de96de..418bcfd8 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 @@ -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, 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 ff2e7af2..0effb7dd 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 @@ -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, diff --git a/tests/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock_test.py b/tests/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock_test.py index e380e6ba..f275f2be 100644 --- a/tests/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_object_lock/s3_bucket_object_lock_test.py @@ -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, diff --git a/tests/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning_test.py b/tests/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning_test.py index d4137fce..1cff6bc6 100644 --- a/tests/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_object_versioning/s3_bucket_object_versioning_test.py @@ -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, diff --git a/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_test.py b/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_test.py index 950893bd..1d4de2db 100644 --- a/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_test.py @@ -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, 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 b9715584..38a357a1 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 @@ -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 diff --git a/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_test.py b/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_test.py new file mode 100644 index 00000000..f9d0240c --- /dev/null +++ b/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_test.py @@ -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 diff --git a/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_test.py b/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_test.py new file mode 100644 index 00000000..0eeacaec --- /dev/null +++ b/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_test.py @@ -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 diff --git a/tests/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy_test.py b/tests/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy_test.py index a2d79a39..1f6bb48d 100644 --- a/tests/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_secure_transport_policy/s3_bucket_secure_transport_policy_test.py @@ -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, diff --git a/tests/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled_test.py b/tests/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled_test.py index 31a5ffc8..e7a3cc67 100644 --- a/tests/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_server_access_logging_enabled/s3_bucket_server_access_logging_enabled_test.py @@ -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,