Skip to content

Data security

Public buckets & blob exposure

Public buckets and blob exposure is one of the most frequently reported classes of cloud data leak, and it happens because "public" is not one setting but several overlapping ones: an object storage container can be reachable by an anonymous internet URL, by every authenticated user in the provider's entire customer base, by an over-broad organization principal, or through a policy statement that a template quietly carried forward. A container can also look locked at the account level while an individual object ACL, a static-website endpoint, or a long-lived pre-signed URL leaks its contents anyway. This page focuses narrowly on object storage — Amazon S3, Azure Blob Storage, and Google Cloud Storage — and on how effective reachability differs from the label on the bucket. We evaluate every container against who can actually read, list, and write to it, because the gap between intended access and effective access is exactly where breaches live.

Overview

What this check looks like in practice

Object storage is the most common place cloud data leaks, because "public" can mean an anonymous internet URL, an over-broad account principal, or a policy that quietly grants read to everyone. Buckets drift open through one-off sharing, legacy defaults, or a permission copied from a template nobody reviewed. We check every storage container against who can actually reach it, not just how it was labeled.

Clean modern server aisle and organized storage environment representing protected enterprise data and storage posture
Data & storage

Why it matters

To an attacker, open object storage is a high-yield, low-effort target: enumeration tooling sweeps predictable bucket names, anonymous list-and-get requires no credential, and a single readable container can hold database exports, backups, logs, or customer documents at rest. To an auditor, an internet-readable store of regulated data is a direct control failure, and to a regulator it is a reportable disclosure the moment the objects can be accessed — copies that have already left cannot be recalled. What makes this sub-topic distinct from encryption or database exposure is that the failure is almost always a permissions-and-defaults problem rather than a cryptography or network one: the store is working exactly as configured, and the configuration is wrong. Because exposure often arrives through drift — a one-off share, a legacy default, a policy copied without review — a container that was private at launch can silently open months later without anyone deliberately touching it.

What we assess

What we look for

  • Buckets or containers readable, listable, or writable by anonymous principals or by all-authenticated users across the entire provider (AWS AllUsers / AuthenticatedUsers, GCS allUsers / allAuthenticatedUsers, Azure anonymous blob or container access)
  • Account- or organization-level public-access guardrails left disabled — S3 Block Public Access not enforced at the account level, Azure storage accounts with 'allow blob public access' enabled, and GCS buckets missing enforced public access prevention
  • Bucket policies, IAM bindings, and object ACLs granting broad Get/List — wildcard principals, org-wide read, or object-level ACLs that override an otherwise-private container
  • Static-website hosting endpoints and CDN origins that serve stores holding sensitive data, plus pre-signed / SAS URLs with long or unbounded expiry acting as durable public links
  • Access-mechanism drift: containers using legacy ACL-based access where the provider now recommends bucket-owner-enforced ownership and policy-only control
  • Storage inventory with no owner, data classification, or documented purpose — containers nobody can attest are safe to be reachable
  • Cross-account and cross-tenant grants that expose containers to external accounts beyond the organization boundary
  • Logging and detection gaps around storage access — no server access / data-plane audit logging, so anonymous reads would leave no trail

Across your clouds

AWS, Azure & Google Cloud

AWS

We check S3 Block Public Access at both the account and per-bucket level, bucket policies and ACLs for AllUsers/AuthenticatedUsers and wildcard-principal grants, S3 Object Ownership (bucket-owner-enforced to disable ACLs), S3 Access Points and their policies, static-website hosting, and pre-signed URL practices; IAM Access Analyzer for S3 surfaces buckets shared outside the account or organization.

Azure

We check the storage account 'allow blob public access' setting and each container's public access level (private vs. blob vs. container anonymous access), network rules and default-deny storage firewalls, shared access signature (SAS) scope and expiry, account-key exposure, and static-website endpoints; Azure Policy can enforce that anonymous access stays disabled account-wide.

Google Cloud

We check Cloud Storage public access prevention (ideally enforced via organization policy), IAM bindings for allUsers and allAuthenticatedUsers at bucket and object scope, uniform bucket-level access (to remove per-object ACL drift), signed URL expiry, and bucket labels for ownership, classification, and residency.

Example finding

A production log-archive bucket is readable by all-authenticated users because a legacy object ACL overrides account-level blocking

Risk: The bucket was labeled private and account-level public blocking appeared enabled, but individual objects still carry an all-authenticated-users read ACL (AWS AuthenticatedUsers / GCS allAuthenticatedUsers). Any principal with a valid provider account — not just members of the organization — can retrieve archived logs that contain access tokens, internal hostnames, and customer identifiers, and because there is no data-plane access logging on the bucket, those reads leave no trace.

Fix: Switch the bucket to owner-enforced ownership so object ACLs no longer grant access (S3 bucket-owner-enforced / GCS uniform bucket-level access; on Azure, disable anonymous access on the storage account), remove the offending grants, enforce account- and org-level public-access prevention as a standing guardrail, rotate any credentials that appeared in the archived logs, and enable data-plane access logging so future reads are recorded.

Remediation

How to close it

  1. 1 Enforce the account- and organization-level guardrail first so no single container can be made public: S3 Block Public Access at the account level, Azure 'allow blob public access' disabled with Azure Policy, and GCS public access prevention enforced via organization policy.
  2. 2 Disable ACL-based access in favor of policy-only control — S3 Object Ownership set to bucket-owner-enforced and GCS uniform bucket-level access — so object-level ACLs can no longer silently override a private container.
  3. 3 Inventory every container and resolve effective access with the provider's analyzer (IAM Access Analyzer for S3, Azure network/access review, GCS IAM policy analysis), then remove anonymous and all-authenticated grants along with any wildcard or external principals that are not justified.
  4. 4 Constrain time-limited access: give pre-signed URLs and SAS tokens the shortest viable expiry, prefer short-lived scoped tokens over static account keys, and review static-website and CDN origins that front sensitive stores.
  5. 5 Assign an owner and data classification to every container and delete or archive orphaned stores; treat any unlabeled, unowned container as a candidate for lockdown.
  6. 6 Turn on data-plane access logging and alerting for storage so anonymous or anomalous reads are recorded and detectable, and schedule a recurring re-check because access drifts open over time.

Questions

Isn't enabling account-level public-access blocking enough on its own?

It is the most important single control, but it is not sufficient by itself. Account-level blocking stops new public grants and neutralizes many existing ones, yet exposure can still arrive through legacy object ACLs where ACLs remain enabled, through pre-signed or SAS URLs, through static-website and CDN origins, and through cross-account or external principal grants that are technically not 'public' but still reach beyond your organization. We verify effective reachability across all of those paths, not just the top-level toggle.

How is a public bucket different from a public database or an open network port?

Object storage exposure is almost always a permissions-and-defaults failure rather than a network or cryptography one — the store is functioning exactly as configured, and anonymous access needs no credential and no exploit. That makes it uniquely low-effort for an attacker and uniquely easy to overlook internally, which is why we treat effective bucket and blob permissions as their own review, distinct from database exposure and network exposure.

Do you access the contents of our buckets during the check?

No. The assessment is read-only and examines the configuration and access model around each container — public-access settings, policies, ACLs, ownership mode, SAS/pre-signed URL practices, and logging — not the objects inside. We report which stores are effectively reachable and by whom so you can prioritize the fixes; we do not read, copy, or move your data.

See where you stand

A health check finds and prioritizes real exposure. It is not a certification or a promise you will never be breached — closing the findings is what changes your risk.

Related domain surfaces

The rest of what we assess

The same read-only assessment covers every domain — see what else it looks at.