Articles / Public Storage Buckets: How Data Still Leaks in 2026
Cloud · Storage

Public Storage Buckets: How Data Still Leaks in 2026

The exposed cloud storage bucket is the breach that refuses to die. AWS added Block Public Access, Azure disabled anonymous blob access by default, Google tightened uniform bucket-level access — and yet, in 2026, sensitive data still ends up readable by anyone who knows the URL. The default got safer; the ways to defeat it got subtler.

Object storage — Amazon S3, Azure Blob Storage, Google Cloud Storage — is where the modern enterprise keeps its bulk data: backups, logs, exports, media, analytics dumps. It is cheap, effectively infinite, and reachable over HTTPS from anywhere. That last property is the whole problem. A single wrong setting turns a private data lake into a public website, and unlike a compromised server, a public bucket leaves no crash and no alert — just quiet, continuous read access.

The defaults got safer. So why does it keep happening?

guess / CT logsyesunauth GETAttackerenumerates bucket namesPublic at any layer?ACL, policy, presigned URLStorage bucketS3 / Blob / GCSSensitive objectsbackups, exports, .envOne override defeatsthe private default
A private default still leaks when any single exposure layer is left open.

Because "public" is no longer a single toggle. Exposure now hides in several layers, and a bucket locked at one layer can still be wide open at another:

  • Overrides at the object level. The bucket blocks public access, but individual objects or a legacy ACL grant AllUsers read. The container looks safe; the contents are not.
  • Over-broad bucket policies. A policy with "Principal": "*" — or an Azure container set to anonymous blob access, or a GCS bucket granting allUsers the Storage Object Viewer role — opens the door while the account-level switch stays on.
  • Presigned URLs gone feral. Time-limited links generated with a long expiry, then pasted into tickets, chat, and client-side code, become durable public handles to private objects.
  • Authenticated-user misreads. Granting access to AuthenticatedUsers in AWS means any AWS account on earth, not just yours — a subtlety that still catches teams out.
  • Public by design, sensitive by accident. A bucket that genuinely must serve public assets quietly accumulates a database export or an env file dropped in the wrong prefix.
Why it matters: A leaked bucket is a zero-effort breach for the attacker. There is no exploit, no malware, no lateral movement — just an HTTP GET against data you thought was private.

How attackers find them

Nobody stumbles onto these by luck. Bucket names are semi-guessable — company-backups, acme-prod-logs — and enumeration tools spray permutations against the storage endpoints all day. Certificate transparency logs, code repositories, and old presigned URLs indexed by search engines all leak names. Once a readable bucket is found, listing its contents is often a single unauthenticated request. Discovery is cheap for the attacker precisely because the data is served over the same public web everyone else uses.

The check an attacker runs first — run it yourselfaws s3 ls s3://acme-prod-backups --no-sign-request # returns an object listing = world-readable

Shutting it down

  • Turn on account-level public-access blocks and leave them on. Block Public Access (AWS), disallow anonymous access at the storage-account level (Azure), and enforce public-access prevention via org policy (GCP).
  • Prefer IAM policies to object ACLs. Enable uniform / bucket-level access so per-object ACLs cannot silently re-open data. Fewer knobs means fewer ways to be wrong.
  • Treat presigned URLs as secrets. Keep expiries short, scope them to a single object and verb, and never embed long-lived ones in client code.
  • Separate public and private by design. Public assets live in their own dedicated bucket with nothing sensitive near it — never as a prefix inside a private store.
  • Scan continuously and from the outside. Cloud posture tooling flags any bucket that becomes world-readable; an external check confirms what the internet can actually see.

The public bucket persists not because the platforms are careless but because storage is easy to create and easy to forget. Every team can stand one up in seconds, and the riskiest bucket in your estate is usually the one no central team knows exists. Safe defaults help, but they only protect the buckets you know about — and you can't defend what you haven't discovered.

Test for it — in practice
  • Confirm the account-level public-access block is switched on for each account, and that no bucket quietly overrides it with a Principal: * policy or a legacy AllUsers ACL.
  • For a bucket you believe is private, sanity-check from outside your own credentials whether it lists anything at all.

Checking a known bucket is easy; enumerating every bucket across every account and confirming what the internet can actually reach is what our assessment runs for you.

Keep reading
CSPM: Finding Misconfigurations Before Attackers Do