Skip to main content

S3 Bucket ACLs Disabled

Overview

This check ensures that Amazon S3 buckets have Access Control Lists (ACLs) disabled by setting Object Ownership to "Bucket owner enforced." When ACLs are disabled, all access is managed through bucket policies and IAM policies, providing centralized and auditable access control.

Risk

When ACLs remain enabled on S3 buckets:

  • Unintended access: ACLs can grant public or cross-account access that bypasses your bucket policies
  • Loss of control: Object uploaders can set their own permissions, preventing the bucket owner from managing access
  • Audit complexity: Per-object ACL permissions make it difficult to understand who has access to what
  • Data exposure: Misconfigured ACLs are a common cause of S3 data breaches

Remediation Steps

Prerequisites

  • AWS account access with permissions to modify S3 bucket settings
  • The bucket name you want to remediate

Important: Before disabling ACLs, ensure any applications or users currently relying on ACL-based permissions have equivalent access through bucket policies or IAM policies.

AWS Console Method

  1. Open the Amazon S3 console
  2. Click on the bucket you want to update
  3. Select the Permissions tab
  4. Scroll to Object Ownership and click Edit
  5. Select ACLs disabled (recommended) under "Bucket owner enforced"
  6. Acknowledge the warning about existing ACLs being replaced
  7. Click Save changes
AWS CLI (optional)

Run this command to disable ACLs on an existing bucket:

aws s3api put-bucket-ownership-controls \
--bucket <your-bucket-name> \
--ownership-controls '{"Rules":[{"ObjectOwnership":"BucketOwnerEnforced"}]}' \
--region us-east-1

Replace <your-bucket-name> with your actual bucket name.

To check current ownership settings:

aws s3api get-bucket-ownership-controls \
--bucket <your-bucket-name> \
--region us-east-1
CloudFormation (optional)

Use this template to create a new S3 bucket with ACLs disabled:

AWSTemplateFormatVersion: '2010-09-09'
Description: S3 bucket with ACLs disabled (BucketOwnerEnforced)

Parameters:
BucketName:
Type: String
Description: Name of the S3 bucket

Resources:
S3BucketOwnershipControls:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerEnforced

Outputs:
BucketName:
Description: Name of the S3 bucket
Value: !Ref S3BucketOwnershipControls

Deploy the stack:

aws cloudformation create-stack \
--stack-name s3-acl-disabled-bucket \
--template-body file://template.yaml \
--parameters ParameterKey=BucketName,ParameterValue=<your-bucket-name> \
--region us-east-1
Terraform (optional)

For existing buckets, add this resource to enforce bucket owner ownership:

resource "aws_s3_bucket_ownership_controls" "example" {
bucket = "<your-bucket-name>"

rule {
object_ownership = "BucketOwnerEnforced"
}
}

For new buckets, include ownership controls in the bucket definition:

resource "aws_s3_bucket" "example" {
bucket = "<your-bucket-name>"
}

resource "aws_s3_bucket_ownership_controls" "example" {
bucket = aws_s3_bucket.example.id

rule {
object_ownership = "BucketOwnerEnforced"
}
}

Apply the configuration:

terraform init
terraform plan
terraform apply

Verification

After making changes, verify ACLs are disabled:

  1. In the S3 console, go to your bucket's Permissions tab
  2. Under Object Ownership, confirm it shows "Bucket owner enforced"
  3. The Access control list (ACL) section should display a message that ACLs are disabled
CLI verification
aws s3api get-bucket-ownership-controls \
--bucket <your-bucket-name> \
--region us-east-1

Expected output:

{
"OwnershipControls": {
"Rules": [
{
"ObjectOwnership": "BucketOwnerEnforced"
}
]
}
}

Re-run the Prowler check to confirm the finding is resolved:

prowler aws --check s3_bucket_acl_prohibited --filter-region us-east-1

Additional Resources

Notes

  • Migration warning: When you switch to "Bucket owner enforced," all existing object and bucket ACLs are replaced. Make sure equivalent permissions exist in bucket policies or IAM policies before making this change.
  • New buckets: As of April 2023, new S3 buckets have ACLs disabled by default. This check primarily flags older buckets created before this change.
  • Cross-account uploads: If other AWS accounts upload objects to your bucket, those objects will automatically be owned by your account when ACLs are disabled.
  • Directory buckets: This setting does not apply to S3 Express One Zone directory buckets, which do not support ACLs.