Since April 2023, new S3 buckets have Block Public Access turned on and ACLs disabled by default. That closed the most common way data leaked. Exposed buckets still turn up, though, and almost always for one of four reasons. Here is what Block Public Access covers, the gaps around it, and how to check each one across all your accounts.
What Block Public Access does
Block Public Access is four settings that override bucket policies and ACLs: block new public ACLs, ignore existing public ACLs, block new public bucket policies, and restrict access to buckets that already have a public policy. They can be set per bucket and for the whole account. With all four on at the account level, nothing in that account can be made public by a bucket policy or ACL, whatever anyone writes later.
The four gaps
- Buckets older than the default. Buckets created before April 2023 kept their old settings. Many accounts have a few with Block Public Access off and ACLs still in use, including grants to “AllUsers” or “AuthenticatedUsers” (any AWS account at all).
- Someone turned it off on purpose. Static website hosting, a public download, a quick demo. The bucket is meant to be public; the problem starts when other files land in it later.
- Access that isn't “public” but is too wide. A bucket policy that grants another AWS account, a whole organization, or a condition that is easier to meet than it looks. Block Public Access doesn't stop cross-account access you granted explicitly.
- Private bucket, reachable role. The bucket is private, but a role used by an internet-facing workload can read it. If that workload is compromised, so is the data. This is the gap only attack path analysis shows.
How to check
- Account setting:
aws s3control get-public-access-block --account-id 111122223333should show all four settings as true in every account. - Per bucket:
aws s3api get-bucket-policy-status --bucket NAMEtells you whether AWS considers the bucket policy public. - Cross-account access: IAM Access Analyzer reports buckets shared outside your account or organization.
- What can reach it: for buckets with sensitive data, list the roles that can read them and check whether any of those roles runs on something the internet can reach.
Close it for good
aws s3control put-public-access-block --account-id 111122223333 \ --public-access-block-configuration \ BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
Do this in every account, then use a service control policy to deny s3:PutAccountPublicAccessBlock so it can't be turned off again. Serve public files through CloudFront with origin access control instead of a public bucket, and keep public and private content in separate buckets. For the last gap, tag sensitive buckets (for example data-class=pii) and narrow the roles that can read them.
A bucket finding matters most when it sits on a path to data, which is how Alye Security ranks it.