Description
Ensure that no Amazon S3 bucket is open to everyone (the AllUsers group) or to any AWS user (the AuthenticatedUsers group) through its access control list (ACL), and that no bucket policy grants public access. Buckets are not considered public when the S3 Block Public Access settings Ignore public ACLs and Restrict public buckets are both enabled, either for the whole account or for the bucket.
Rationale
A public bucket can be read, and in some cases changed, by anyone on the Internet or by any AWS customer. This can lead to mass data exposure, malware hosting, tampering with objects or deletion of data, and attackers may find secrets stored in objects that allow further access. S3 Block Public Access at account and bucket level, explicit principals in bucket policies, and disabling ACLs through S3 Object Ownership provide layered protection. Content that must be public should be served through Amazon CloudFront or presigned URLs instead.
Impact
Prevents anonymous and cross-account public access to bucket contents
Reduces the risk of data exposure, tampering and deletion
Websites, downloads or integrations that rely on public access to the bucket stop working until they are moved to an alternative such as CloudFront with origin access control or presigned URLs
Default Value
New buckets are private: they have no bucket policy, ACLs are disabled through S3 Object Ownership (Bucket owner enforced), and all four S3 Block Public Access settings are enabled by default for buckets created since April 2023.
Pre-Requisites
IAM permissions: s3:ListAllMyBuckets, s3:GetBucketAcl, s3:GetBucketPolicy, s3:GetBucketPolicyStatus, s3:GetBucketPublicAccessBlock, s3:PutBucketPublicAccessBlock, s3:GetAccountPublicAccessBlock and s3:PutAccountPublicAccessBlock
A list of buckets that must legitimately serve public content, and an agreed alternative for them
A copy of the current Block Public Access settings
Remediation
Test Plan
Console:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the Amazon S3 console and select Block Public Access settings for this account. If both the public ACL setting (Block public access to buckets and objects granted through any access control lists (ACLs)) and the public policy setting (Block public and cross-account access to buckets and objects through any public bucket or access point policies) are On, all buckets pass.
Otherwise, select Buckets, select a bucket and open the Permissions tab.
If both of the same settings are On under Block public access (bucket settings), the bucket passes.
Otherwise, in the Access control list (ACL) section, check whether Everyone (public access) or Authenticated users group (anyone with an AWS account) has any permission.
In the Bucket policy section, check for a statement with "Effect": "Allow" and a principal of "*" or {"AWS": "*"} without a restricting condition.
Repeat for each bucket.
If public access is granted through the ACL or the policy, follow the implementation steps.
CLI:
Show the account-level Block Public Access settings:
aws s3control get-public-access-block --account-id <ACCOUNT_ID>
Show the bucket-level Block Public Access settings:
aws s3api get-public-access-block --bucket <BUCKET_NAME>
Show the group grants in the bucket ACL:
aws s3api get-bucket-acl --bucket <BUCKET_NAME> --query "Grants[?Grantee.Type=='Group'].[Grantee.URI,Permission]" --output table
Show whether the bucket policy is public:
aws s3api get-bucket-policy-status --bucket <BUCKET_NAME> --query PolicyStatus.IsPublic
A bucket fails if IgnorePublicAcls and RestrictPublicBuckets are not both true at account level or at bucket level, and either the ACL has a grant to a URI ending in AllUsers or AuthenticatedUsers, or the bucket policy is public.
Implementation Steps
Console:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the Amazon S3 console, select the bucket found in the Test Plan and open the Permissions tab.
Under Block public access (bucket settings), choose Edit.
Select Block all public access, or at least:
Block public access to buckets and objects granted through any access control lists (ACLs), and
Block public and cross-account access to buckets and objects through any public bucket or access point policies.
Choose Save changes and confirm.
Remove any public grants from the bucket ACL and public statements from the bucket policy, or disable ACLs by setting Object Ownership to Bucket owner enforced.
Repeat for each affected bucket.
To protect all buckets at once, apply the same settings under Block Public Access settings for this account. Warning: the account-level settings apply to every bucket in the account and will break buckets that are public on purpose, such as static websites or public downloads. Save the current account-level settings first (see the CLI steps below).
CLI:
Turn on S3 Block Public Access for the bucket. The command replaces the whole Block Public Access configuration of the bucket, and any setting not included is turned off, so all four settings are given here:
aws s3api put-public-access-block --bucket <BUCKET_NAME> --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
To protect all buckets in the account, S3 Block Public Access can be turned on at account level. Warning: this applies to every bucket in the account and will break buckets that are public on purpose. Before changing it, save the current account-level settings:
aws s3control get-public-access-block --account-id <ACCOUNT_ID> > account-public-access-block-backup.json
Turn on S3 Block Public Access at account level:
aws s3control put-public-access-block --account-id <ACCOUNT_ID> --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
Backout Plan
Before making changes, save the current Block Public Access settings:
aws s3api get-public-access-block --bucket <BUCKET_NAME> --query PublicAccessBlockConfiguration > public-access-block-backup.json
To roll back:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the Amazon S3 console, select the bucket and open the Permissions tab.
Under Block public access (bucket settings), choose Edit.
Restore the previous settings from the saved backup and choose Save changes.
If the account-level settings were changed, restore them under Block Public Access settings for this account.
CLI:
aws s3api put-public-access-block --bucket <BUCKET_NAME> --public-access-block-configuration file://public-access-block-backup.json
If the account-level settings were changed, restore them with the values saved in account-public-access-block-backup.json. The example below turns all four settings off; set each one to true or false as recorded in the backup:
aws s3control put-public-access-block --account-id <ACCOUNT_ID> --public-access-block-configuration BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
If no account-level configuration existed before (the backup command returned a NoSuchPublicAccessBlockConfiguration error), remove it instead:
aws s3control delete-public-access-block --account-id <ACCOUNT_ID>
Note: rolling back makes the bucket publicly accessible again. Use it only as a temporary measure while an alternative for public content is arranged.
Reference
https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html
https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html
https://docs.aws.amazon.com/cli/latest/reference/s3api/put-public-access-block.html
https://docs.aws.amazon.com/cli/latest/reference/s3control/put-public-access-block.html