HackBlue

Tools · Cloud security · 07 / 24

S3 Block Public Access explained: the four settings and where to turn them on

Understand each Block Public Access setting, enable it at the account level, and check buckets that still need a deliberate exception.

9 min read · practice only with authorization

Four settings

BlockPublicAcls rejects new public ACLs. IgnorePublicAcls makes S3 ignore any public ACLs already present. BlockPublicPolicy rejects bucket policies that grant public access. RestrictPublicBuckets limits access under an existing public policy to AWS service principals and authorized users in the account. All four can be set per bucket and for the whole account.

Since April 2023, new buckets have all four enabled and ACLs disabled by default. Older buckets and accounts may not.

Set it account-wide

Account-level Block Public Access overrides bucket settings, so one call protects every current and future bucket. If a bucket truly must be public, such as one hosting static website assets, a better design is a private bucket behind CloudFront with origin access control, which keeps Block Public Access on.

In AWS Organizations, an SCP can deny s3:PutAccountPublicAccessBlock so nobody can turn it off.

Snippet
aws s3control put-public-access-block --account-id 111122223333 \
  --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
aws s3control get-public-access-block --account-id 111122223333

Lab: find buckets that are public today

List every bucket and check its policy status and bucket-level block settings. get-bucket-policy-status returns IsPublic true when the policy grants public access. Create a test bucket in a sandbox, disable its block settings, add a public-read policy, and confirm the check flags it. Then turn on account-level blocking and see IsPublic become irrelevant because access is restricted.

Delete the test bucket afterward and confirm the account-level settings are still enabled.

Snippet
for b in $(aws s3api list-buckets --query 'Buckets[].Name' --output text); do
  pub=$(aws s3api get-bucket-policy-status --bucket "$b" --query PolicyStatus.IsPublic --output text 2>/dev/null || echo none)
  bpa=$(aws s3api get-public-access-block --bucket "$b" --query 'PublicAccessBlockConfiguration.[BlockPublicPolicy,RestrictPublicBuckets]' --output text 2>/dev/null || echo unset)
  echo "$b policyPublic=$pub block=$bpa"
done

Monitor changes

CloudTrail records PutPublicAccessBlock, DeletePublicAccessBlock, PutBucketPolicy, and PutBucketAcl. Alert on any deletion of block settings. AWS Config’s managed rules s3-bucket-public-read-prohibited and s3-account-level-public-access-blocks-periodic check continuously.

Access Analyzer external access findings also catch buckets shared with other accounts, which Block Public Access does not prevent.

Diagram

The four Block Public Access switches

Turn on all four at the account level.

  • BlockPublicAcls

    Reject new public ACLs.

  • IgnorePublicAcls

    Ignore existing public ACLs.

  • BlockPublicPolicy

    Reject public bucket policies.

  • RestrictPublicBuckets

    Neutralize existing public policies.

Check yourself

1. Which setting makes S3 disregard public ACLs that already exist?

2. Where should Block Public Access be enabled for broadest coverage?

3. How can a website serve S3 content without a public bucket?