S3 Bucket Accidentally Public? Lock It Down Fast

Server & Cloud Intermediate 👁 1 views 📅 May 29, 2026

Your S3 bucket was set to public by accident. Here's how to lock it down in three steps: quick block, moderate ACL fix, and a full audit.

Quick Fix (30 Seconds): Block All Public Access

This is the safety net. If you just realized your bucket is public, do this first. It stops everything cold.

  1. Log into the AWS Console.
  2. Go to S3 > your bucket > Permissions tab.
  3. Under Block public access (bucket settings), click Edit.
  4. Check all four boxes:
Block public access to buckets and objects granted through new public bucket policies
Block public access to buckets and objects granted through new public bucket or access point policies
Block public access to buckets and objects granted through public bucket policies
Block public and cross-account access to buckets and objects through any public bucket or access point policies

Click Save. This overrides any bucket policy or ACL that allows public access. It won't delete existing policies or ACLs, but it stops them from working. You're safe for now.

Warning: If your bucket serves public content (like a website or CDN), this will break that. But if you didn't intend it to be public, this is the right move. You can unblock specific objects later.

Moderate Fix (5 Minutes): Remove Public ACLs and Policies

Once you've blocked public access, you need to clean up the mess. Public ACLs and bucket policies are the two ways a bucket can become public.

Step 1: Check the Bucket Policy

Still in the Permissions tab, scroll to Bucket Policy. If there's a policy there, look for something like this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

That "Principal": "*" means anyone on the internet can read objects. Delete the entire policy or replace it with a restrictive one. If you're not sure what's needed, just delete it — you can always add a proper policy later.

Step 2: Check Object ACLs

Object ACLs can also make individual files public. To see if that's the case, run this AWS CLI command from your terminal:

aws s3api list-objects --bucket your-bucket-name --query "Contents[].Key" --output text | xargs -I {} aws s3api get-object-acl --bucket your-bucket-name --key {}

Look for any ACL that has a grant with "URI": "http://acs.amazonaws.com/groups/global/AllUsers" or "URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers". That means the object is publicly readable.

To remove public ACLs from all objects, use this one-liner (careful — it modifies every object):

aws s3api list-objects --bucket your-bucket-name --query "Contents[].Key" --output text | xargs -I {} aws s3api put-object-acl --bucket your-bucket-name --key {} --acl private

This sets every object to private. If you have thousands of objects, this might take a minute or two. Wait for it to finish.

Step 3: Turn Off ACLs Entirely (Recommended)

ACLs are outdated. AWS recommends using bucket policies and IAM instead. To disable ACLs on the bucket:

  1. Go to Permissions > Object Ownership.
  2. Check ACLs disabled.
  3. Select Bucket owner enforced.
  4. Click Save.

This stops anyone from setting object ACLs going forward. Your bucket will rely on bucket policies and IAM policies only.

Advanced Fix (15+ Minutes): Full Audit and Hardening

You've locked the door. Now let's check if anyone walked in while it was open. Also, let's make sure it never happens again.

Step 1: Check S3 Access Logs

If you had S3 server access logging enabled before the exposure, you can see exactly what was accessed. Head to your logging bucket or enable it now (for future incidents). Then use Athena or CloudWatch Logs Insights to query. Example Athena query:

SELECT request_uri, user_agent, remote_ip
FROM s3_access_logs
WHERE bucket = 'your-bucket-name'
  AND operation = 'REST.GET.OBJECT'
  AND remote_ip NOT LIKE 'your-office-ip%'

If you didn't have logging enabled, you can't see the past. But enable it now — it's cheap and saves your butt in audits.

Step 2: Enable AWS Config Rules

Go to AWS Config > Rules. Add the managed rule s3-bucket-public-read-prohibited and s3-bucket-public-write-prohibited. These will flag any bucket that's made public in the future. You can even set up automatic remediation using AWS Systems Manager Automation.

Step 3: Set Up Bucket Policies for Least Privilege

Instead of a blanket public policy, write specific policies. For example, if your app needs to read objects, limit access to only the required role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/MyAppRole"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/path/to/data/*"
    }
  ]
}

Hardcode the ARN. Use "Principal": "*" only if absolutely necessary, and if you do, restrict the action and resource path tightly.

Step 4: Enable S3 Object Lock (For Compliance)

If your bucket contains sensitive data (PII, financial records), enable Object Lock to prevent deletion or overwrites for a retention period. This protects against accidental or malicious deletions after cleanup.

Step 5: Notify Your Team and Document

This step matters more than you think. Write a post-mortem: what happened, how you found it, how you fixed it. Include the date and time the bucket was public (if known). Run a scan using a tool like s3-inspector (open source) to check for other buckets. Share the findings with your team so they don't repeat the mistake.

And next time, use Terraform or CloudFormation with a deny-all public access block baked into your templates. Manual console changes are how this happens.

You're done. Your bucket is locked, audited, and hardened. Sleep well.

Was this solution helpful?