S3 bucket policies and ACLs should not be configured for public read access¶
Description¶
S3 bucket policies and ACLs should not be configured for public read access. It is a security risk for a bucket to have an ACL or bucket policy that is configured for public read access, even if the bucket itself is not currently public. A bucket configured for public read access can potentially be made public, allowing any AWS user or anonymous user to access the data in it.
Remediation Steps¶
AWS Console¶
Navigate to S3.
Select the S3 bucket.
Select Permissions > Access Control List.
In Public access, select Everyone and uncheck:
List objects
Write objects
Read bucket permissions
Write bucket permissions
Click Save.
Navigate to S3.
In the left navigation, select Block public access (account settings).
Click Edit.
Check the Block all public access checkbox.
Click Save Changes.
Enter confirm and click confirm.
AWS CLI¶
To make an S3 bucket not publicly accessible:
aws s3api put-bucket-acl \
--bucket fugue-bucket-example --acl private
aws s3api put-public-access-block \
--bucket fugue-bucket-example \
--public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
CloudFormation¶
JSON¶
Ensure that AWS::S3::Bucket contains the following:
{
"Properties" : {
"PublicAccessBlockConfiguration" : {
"BlockPublicAcls" : true,
"BlockPublicPolicy" : true,
"IgnorePublicAcls" : true,
"RestrictPublicBuckets" : true
}
}
}
JSON Example Configuration¶
{
"Type" : "AWS::S3::Bucket",
"Properties" : {
"PublicAccessBlockConfiguration" : {
"BlockPublicAcls" : true,
"BlockPublicPolicy" : true,
"IgnorePublicAcls" : true,
"RestrictPublicBuckets" : true
}
}
# other required fields here
}
YAML¶
Ensure that AWS::S3::Bucket contains the following:
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls : true
RestrictPublicBuckets : true
YAML Example Configuration¶
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls : true
RestrictPublicBuckets : true
# other required fields here
Terraform¶
Ensure that the aws_s3_bucket
acl
field does NOT contain EITHER of the following:“public-read”
“public-read-write”
Ensure that the
grant
block does NOT contain BOTH an invaliduri
andpermissions
field:Invalid
uri
:Invalid
permissions
:“READ”
“FULL_CONTROL”
“READ_ACP”
If a bucket policy is defined in the bucket’s
policy
field, ensure the JSON document does NOT contain BOTH an invalid principal, an invalid action, and an invalid effect:Invalid principals:
"Principal": { "AWS": "*" }
"Principal": "*"
Invalid actions:
"*"
"s3:*"
"s3:List*"
"s3:Get*"
"s3:ListBucket*"
"s3:GetObject*"
"s3:ListBucket"
"s3:ListBucketVersions"
"s3:ListBucketMultipartUploads"
"s3:GetObject"
"s3:GetObjectVersion"
"s3:GetObjectTorrent"
Invalid effect:
"Effect": "Allow"
If a bucket policy as defined as an aws_s3_bucket_policy, ensure the JSON document in the
policy
field does NOT contain BOTH an invalid principal, an invalid action, and an invalid effect, as listed aboveWhile a aws_s3_bucket_public_access_block is not required for the bucket, it’s highly recommended. Ensure the following aws_s3_bucket_public_access_block fields are all set to
true
:block_public_acls
block_public_policy
ignore_public_acls
restrict_public_buckets
Example Configuration¶
# Compliant ACL
resource "aws_s3_bucket" "b" {
acl = "private"
# other required fields here
}
# Compliant grant
resource "aws_s3_bucket" "bucket" {
bucket = "mybucket"
grant {
id = data.aws_canonical_user_id.current_user.id
type = "CanonicalUser"
permissions = ["FULL_CONTROL"]
}
# other required fields here
}
# Compliant bucket policy
resource "aws_s3_bucket" "b" {
bucket = "my-tf-test-bucket"
# other required fields here
}
resource "aws_s3_bucket_policy" "b" {
bucket = aws_s3_bucket.b.id
policy = jsonencode({
Version = "2012-10-17"
Id = "MYBUCKETPOLICY"
Statement = [
{
Sid = "IPAllow"
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = [
aws_s3_bucket.b.arn,
"${aws_s3_bucket.b.arn}/*",
]
Condition = {
NotIpAddress = {
"aws:SourceIp" = "8.8.8.8/32"
}
}
},
]
})
# other required fields here
}
# Compliant bucket public access block
resource "aws_s3_bucket" "b" {
# other required fields here
}
resource "aws_s3_bucket_public_access_block" "private" {
bucket = "${aws_s3_bucket.b.id}"
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}