Cloud Security
AWS S3
cloud security
bucket takeover

S3 Bucket Security: Misconfigurations and Hardening

S3 bucket security on AWS: ACLs vs bucket policy vs Block Public Access, encryption, bucket takeover, data exfiltration and a hardening checklist.

SecraJuly 6, 202610 min read

S3 bucket security accounts for a disproportionate share of cloud data breaches. Amazon S3 is the most widely used object storage service in AWS and, precisely because of its ubiquity, a single misconfigured bucket can expose millions of records without any sophisticated exploit involved. This article goes beyond the general catalogue of cloud mistakes and focuses on what makes S3 distinct: its three-plane access control model, encryption, bucket takeover, data exfiltration and an AWS-specific hardening checklist.

If you are looking for a broader view of insecure cloud configurations, we cover it in the article on the most dangerous cloud misconfigurations in AWS and Azure. Here we drill down into a single service.

Why S3 Buckets Remain a Primary Target

Bucket exposure is not a theoretical problem. The Capital One case in 2019 (over 100 million customer records) is the most high-profile, but the list is long: Booz Allen Hamilton leaked US Army data through a public bucket, Deep Root Analytics exposed information on nearly 200 million American voters in 2017, and FedEx left scanned passports and driving licences accessible. The pattern repeats because S3 combines three factors: it stores extremely high-value data, it is trivial to provision, and its permission model is subtler than it appears.

On top of that attack surface, the S3 namespace is global. A bucket name is unique across the entire AWS partition, which lets an attacker reason about predictable names (company-backups, company-logs, company-prod) and discover them with no prior access to the account.

The Three Access Control Planes

The most common conceptual error is treating S3 access as if it were a single switch. In reality, three mechanisms coexist and are evaluated together, and understanding their interaction is the foundation of hardening.

ACLs: The Legacy Model You Should Disable

Access Control Lists (ACLs) are the original S3 mechanism, predating IAM. They grant bucket-level or object-level permissions to predefined groups, including the dangerous AllUsers (anyone on the internet) and AuthenticatedUsers (any AWS account holder, not just yours). That last one is especially treacherous: many people assume "authenticated users" means their organization, when in reality it covers everyone with an AWS account.

Since April 2023, AWS disables ACLs by default on new buckets through the Object Ownership: Bucket owner enforced setting. This is the recommended configuration: it disables ACLs entirely and forces all access to be managed through IAM and resource-based policies. If you have older buckets, verify their Object Ownership:

aws s3api get-bucket-ownership-controls --bucket my-bucket
aws s3api get-bucket-acl --bucket my-bucket

Bucket Policy: The Resource-Based Policy

The bucket policy is a JSON policy attached to the bucket itself. Unlike an IAM policy (which attaches to an identity), it is evaluated from the resource side and is the correct tool for controlling S3 access with granularity. The classic failure is a wildcard Principal combined with read actions:

{
  "Effect": "Allow",
  "Principal": "*",
  "Action": ["s3:GetObject", "s3:ListBucket"],
  "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
}

That policy makes the entire bucket public. A well-designed bucket policy, by contrast, is used to enforce controls: deny any non-TLS request with aws:SecureTransport, require encryption on upload with s3:x-amz-server-side-encryption, restrict access to a specific VPC endpoint with aws:SourceVpce, or scope cross-account access to your organization with aws:PrincipalOrgID. In cross-account and service-to-service scenarios, always add aws:SourceAccount and aws:SourceArn to prevent the confused deputy problem.

Block Public Access: The Safety Net

S3 Block Public Access (BPA) is the layer that overrides any configuration exposing the bucket, regardless of what the ACLs or the bucket policy say. It consists of four settings:

  • BlockPublicAcls: rejects new public ACLs.
  • IgnorePublicAcls: ignores any existing public ACLs.
  • BlockPublicPolicy: rejects bucket policies that grant public access.
  • RestrictPublicBuckets: limits access from any already-applied public policy to principals in the account and AWS services only.

Since April 2023, BPA has been enabled by default at the bucket level for new buckets, but the strong recommendation is to enable it at the account level as well, so that no bucket can become public by accident. Verify it as follows:

aws s3api get-public-access-block --bucket my-bucket
aws s3control get-public-access-block --account-id 111122223333

Enumeration and Exfiltration From the Attacker's View

A pentester starts by discovering buckets. Tools such as S3Scanner, cloud_enum or the public index GrayhatWarfare locate open buckets from domain names and keywords. With a candidate name, the check is direct and needs no credentials:

aws s3 ls s3://company-backups --no-sign-request
aws s3 cp s3://company-backups/dump.sql . --no-sign-request

If the bucket allows anonymous s3:ListBucket, the attacker lists objects; if it allows s3:GetObject, they download them. Mass exfiltration rarely needs more than that. Tools like s3-account-search can even infer the AWS account ID that owns a bucket, useful information for the subsequent pivot. In a full offensive exercise, these findings are chained together with other weaknesses, as we describe in the guide to cloud penetration testing across AWS, Azure and GCP.

On the defensive side, two native services add visibility: IAM Access Analyzer for S3 flags buckets with public or cross-account access, and Amazon Macie discovers sensitive data (PII, credentials, cards) inside the objects. Both should be part of the baseline.

Bucket Takeover: Hijacking by Name

Bucket takeover is an S3-specific variant of subdomain takeover. It happens when a DNS record (usually a CNAME) points to an S3 endpoint, for example assets.yourdomain.com to assets-yourdomain.s3-website-eu-west-1.amazonaws.com, and the underlying bucket is deleted without removing the DNS record. Because the S3 namespace is global, any attacker can claim that same bucket name and serve malicious content under your subdomain: phishing with your brand, cookie theft or malware distribution backed by your domain's trust.

The tell-tale sign is a NoSuchBucket error when resolving the subdomain. The defence is hygiene: when decommissioning infrastructure, remove the DNS record first and only then delete the bucket, and periodically audit your DNS zones for dangling CNAMEs pointing to S3 endpoints with no live bucket behind them.

Encryption at Rest and in Transit

Since January 2023, S3 encrypts all new objects by default with SSE-S3 (AES-256). This eliminates the "unencrypted bucket" scenario but does not close the debate. For regulated data, it is best to use SSE-KMS with a customer managed key (CMK), which adds an extra authorization layer: even if an attacker obtains s3:GetObject, they also need kms:Decrypt permission on the key. Enable S3 Bucket Keys to dramatically reduce the cost of KMS calls on high-traffic buckets.

Encryption in transit is enforced by denying, in the bucket policy, any request where aws:SecureTransport is false, which forces HTTPS on every operation. Combining SSE-KMS with a CMK and a per-key deny policy is also an effective way to segregate data across teams.

Ransomware Resilience

An attacker with write permissions does not only read data: they can encrypt or delete it to demand a ransom. Three controls reduce that risk. Versioning keeps prior copies of every overwritten or deleted object. MFA Delete requires a second factor to permanently remove object versions. And S3 Object Lock in compliance mode enforces WORM (write once, read many) storage that prevents object deletion even by the root account for the defined retention period, making it the ideal basis for immutable backups.

S3 Hardening Checklist

  1. Enable Block Public Access at the account level, not just per bucket.
  2. Set Object Ownership to Bucket owner enforced to disable ACLs.
  3. Review every bucket policy for Principal: "*" and for AuthenticatedUsers.
  4. Deny non-TLS requests with the aws:SecureTransport condition.
  5. Restrict access with aws:PrincipalOrgID, aws:SourceVpce or aws:SourceIp where applicable.
  6. Use SSE-KMS with a CMK for regulated data and enable Bucket Keys.
  7. Enable versioning, MFA Delete and Object Lock on critical buckets.
  8. Turn on server access logging and CloudTrail data events for S3.
  9. Run IAM Access Analyzer for S3 and Macie continuously.
  10. Assess the whole against the CIS AWS Foundations Benchmark (S3 section) and the AWS Foundational Security Best Practices.

These controls are not static: configuration drift is constant in active accounts. Measuring it continuously is precisely the role of a CSPM, as we explain in what CSPM is and how cloud security posture management works. And because a bucket rarely falls in isolation, it is worth understanding how its compromise combines with AWS IAM privilege escalation within a real attack chain.

Frequently asked questions

Is enabling Block Public Access enough to protect an S3 bucket?

Block Public Access prevents public exposure, which is the cause of most high-profile breaches, but it does not cover misconfigured cross-account access, exfiltration by an over-privileged internal identity, or the lack of encryption with a managed key. It is an essential control, not a complete defence. Real hardening combines BPA with Object Ownership, restrictive bucket policies, SSE-KMS encryption and audit logging.

What is the difference between an ACL and a bucket policy in S3?

ACLs are the legacy mechanism, predating IAM, and grant permissions to predefined groups with very little granularity. A bucket policy is a resource-based JSON policy that supports fine-grained conditions (mandatory TLS, restriction by VPC, by organization or by IP). AWS's current recommendation is to disable ACLs through Object Ownership set to Bucket owner enforced and to manage all access with IAM and bucket policies.

What is a bucket takeover attack?

It is a form of subdomain takeover. When a DNS record points to an S3 endpoint and the associated bucket is deleted without removing the record, an attacker can claim that bucket name (the namespace is global) and serve malicious content under your subdomain. Prevention means always deleting the DNS record before the bucket and auditing for dangling CNAMEs that return a NoSuchBucket error.

Are S3 buckets encrypted automatically?

Yes. Since January 2023, S3 applies SSE-S3 (AES-256) encryption by default to all new objects. Even so, for sensitive or regulated data it is better to use SSE-KMS with a customer managed key, because it adds an independent authorization layer: reading the object also requires kms:Decrypt permission on the key, which limits exfiltration even if s3:GetObject is granted.

How is data exfiltration from a bucket detected?

By enabling CloudTrail data events for S3 and server access logging, then correlating anomalous patterns: unusual GetObject volumes, access from atypical IPs or regions, or mass ListBucket calls. Amazon GuardDuty with S3 Protection generates findings on these behaviours, and Macie identifies which buckets contain sensitive data so you can prioritize monitoring.

Conclusion

S3 bucket security comes down to details that seem minor: a misunderstood AuthenticatedUsers, a CNAME left dangling, a bucket policy with a wildcard Principal. None of them requires an exploit, and all of them are preventable with configuration discipline. The recipe is well known: Block Public Access at the account level, ACLs disabled, bucket policies with strict conditions, encryption with a managed key, ransomware resilience and continuous auditing. If you handle sensitive data in S3 and have not validated your exposure with an offensive exercise, at Secra we verify it through our cloud audit service.

About the author

Secra Solutions team

Ethical hackers with OSCP, OSEP, OSWE, CRTO, CRTL and CARTE certifications, 7+ years of experience in offensive cybersecurity, and authors of CVE-2025-40652 and CVE-2023-3512.

Share article