Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · S3

S3.12: ACLs should not be used to manage bucket access

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub S3.12 check?

S3.12 checks that a bucket does not use ACLs to manage access. It reports FAILED unless the bucket's Object Ownership is set to BucketOwnerEnforced, which disables ACLs entirely in favour of IAM and bucket policies.

Why does S3.12 matter?

ACLs predate IAM and grant access through a parallel, easily-overlooked mechanism, meaning a bucket can look locked down in its policy while an ACL quietly grants access to another party. Disabling ACLs collapses access control onto one auditable model and removes a whole class of accidental exposure.

How do I fix S3.12?

  1. Find buckets still allowing ACLs with get-bucket-ownership-controls.
  2. Replicate any access currently granted via ACLs into the bucket policy.
  3. Set Object Ownership to BucketOwnerEnforced with put-bucket-ownership-controls.
  4. Watch for log-delivery, CloudFront origin and x-amz-acl-sending tools that rely on ACLs and migrate them first.

Remediation script · bash

# Close the highest-blast-radius mode first: confirm and remove the root access key.
# (Deletion is done as the root user via the console; an IAM identity cannot do it.)
aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'
# Expect 0 after deletion.

# Close a public EKS endpoint (only after confirming a private path exists).
aws eks update-cluster-config --name svc-orders \
  --resources-vpc-config endpointPublicAccess=false,endpointPrivateAccess=true

# Disable legacy ACLs on a bucket and let policy govern access.
aws s3api put-bucket-ownership-controls --bucket my-legacy-assets \
  --ownership-controls 'Rules=[{ObjectOwnership=BucketOwnerEnforced}]'

# Migrate a Transfer Family server off plain FTP to SFTP only.
aws transfer update-server --server-id s-0a1b2c3d4e5f --protocols SFTP

Full walkthrough (console steps, edge cases and verification) in the lesson Disable insecure access modes and protocols.

Is S3.12 a false positive?

Cross-account log delivery and some CloudFront setups historically used ACLs; migrate those to policy-based grants before enforcing, or writes will start failing.

Part of the learning path Lock down access
  • S3.1 Account-level S3 public access is not fully blocked
  • S3.2 Public S3 buckets expose data to anyone on the internet
  • S3.3 Buckets can be written to by anyone on the internet
  • S3.5 S3 is accepting unencrypted HTTP requests
  • S3.6 Bucket policy grants broad access to other AWS accounts
  • S3.8 Buckets can still be made public; Block Public Access is off
  • S3.9 No S3 access logs, so reads and writes go unaudited
  • S3.10 Versioned buckets should have lifecycle configurations
  • S3.11 Buckets should have event notifications enabled
  • S3.13 Buckets have no lifecycle rules and grow forever
  • S3.15 Buckets should have Object Lock enabled
  • S3.17 Buckets should be encrypted at rest with KMS keys