Why cloud storage keeps getting exposed
Almost nobody sets a bucket to public on purpose, so a control that only stops that action prevents very little. Exposure arrives through resource policies written to unblock an integration, disk and database snapshots shared to help a supplier, presigned links issued with the longest expiry the provider allows, and content delivery configurations that read from an origin nobody treated as sensitive. That ceiling is seven days on AWS and on Google Cloud, shorter again when an AWS link is signed with role credentials because it expires with the session, and unbounded on Azure when the shared access signature is signed with an account key. The providers have closed the obvious default, which means what remains is composite and mostly invisible in a console review.
Is misconfigured storage still the most common cloud incident?
Publicly reachable data remains one of the most frequently reported causes of cloud data loss, and the reason it persists is that the failure has moved rather than gone away. New buckets on the major providers now block anonymous access by default, and grants based on legacy access control lists are disabled by default on AWS, so the single-click mistake that produced the headlines of a few years ago is largely designed out.
What produces exposure now is a policy someone wrote deliberately. A wildcard principal added so a partner's script could fetch a file. A grant to all authenticated users, which on some services means any account on that provider rather than anyone in your organisation. A policy that was correct for one prefix and then applied to the whole store. None of these look like a mistake in a change review, because each was requested by someone with a real problem.
The consequence is that the useful question is not whether a store is marked public. It is what an unauthenticated request and an unrelated cloud account can each actually read, which is a computed answer, not a setting you can look at.
What gets exposed that is not a bucket?
Snapshots, images and derived copies, which are the exposures teams find last because nobody thinks of them as storage. A disk snapshot shared with everyone contains the filesystem it came from, including credentials on disk. A shared machine image contains whatever was baked into it. A database snapshot restored by a stranger yields the entire database without touching your running instance or generating a single log line in your application.
| Exposure path | How it usually happens | Why a review misses it | First control |
|---|---|---|---|
| Resource policy with a wildcard principal | Added to unblock a partner or a script | Reads as an intentional, approved change | External access analysis, not a policy read |
| Grant to all authenticated users | Misread as meaning your own staff | The label sounds restrictive | Deny at organisation level |
| Disk or machine image shared publicly | Shared with a supplier, scope set too wide | Not thought of as data | Periodic query for shared snapshots |
| Database snapshot marked public | Copied for a test, sharing left on | The live database is correctly private | Organisation policy denying public snapshots |
| Presigned or shared-access link | Issued with the provider's maximum expiry, unbounded on Azure with an account key | No setting exists to inspect afterwards | Cap expiry in code, log issuance |
| CDN or static site in front of a private store | Origin opened to make the edge work | The store is private, the path is not | Signed origin access, test the origin directly |
| Infrastructure state and log archives | Stored in a general-purpose bucket | Treated as build output rather than secrets | Separate store, separate account |
Why does a policy review miss an open store?
Because access is the result of several documents evaluated together, and no single one of them tells you the answer. Effective access on the major providers combines the resource policy, the caller's own identity policy, account-level public access blocks, organisation-level denials, and in some services a network rule or endpoint policy as well. A reviewer reading the bucket policy alone is reading one term of an expression.
The evaluation order also defeats intuition. An explicit denial anywhere usually wins, which is what makes organisation-level denials so useful, but the absence of a denial plus a broad allow in either document can be enough. Conditions add another layer, and a condition that looks restrictive, such as one keyed on a source network or a source account, may be trivially satisfied or may not apply to the request pattern you were worried about.
This is why the practical control is an external access evaluator rather than human review. All three major providers now offer a service that computes which resources are reachable from outside your organisation, and reads that as a finding rather than as a configuration value. It is the one piece of cloud tooling that consistently earns its place on day one.
How would you know if data had been read?
Frequently you would not, because data plane logging is separate from control plane logging and is generally off by default. Your audit trail records that a policy was changed. It does not record that ten thousand objects were then downloaded, unless you enabled object-level logging on that store, which costs money and produces volume, so it is commonly left off precisely on the stores holding the most data.
That gap shapes real incidents. Organisations often learn about exposure from a researcher, a customer, or a public listing rather than from their own monitoring, and then cannot answer the question that actually matters to a regulator or a customer: was anything accessed, by whom, and when. Without data plane logs the honest answer is that you cannot tell, and the response has to assume the worst.
So decide deliberately where read logging is on. Do not try to enable it everywhere. Classify the small number of stores holding personal data, credentials, backups or intellectual property, turn object-level logging on for those, send it somewhere the account itself cannot delete, and accept sampling or nothing for the rest. That choice is cheap to make now and impossible to make retrospectively.
What actually prevents this rather than detecting it?
Denials that sit above the account, combined with default-private modules in your infrastructure code. An organisation-level policy that refuses to allow public access blocks to be disabled, refuses public snapshot sharing, and refuses removal of the logging configuration will stop the entire class of accidents, and it does so without slowing anybody down, because no legitimate delivery task requires those actions.
For anything genuinely meant to be public, move it. A separate account whose only purpose is public content is a structural control: the blast radius of a mistake in that account is a set of files you intended to publish, and it lets you keep the strict denials everywhere else without exceptions. Exceptions are what erode this control, and separating the public case removes the demand for them.
Then make the safe path the default path. If the storage module in your infrastructure code emits encryption, versioning, public access blocking and a logging destination without being asked, the common case is right without any reviewer thinking about it. Teams do not misconfigure storage because they want to; they misconfigure it because the raw resource has more knobs than the task appeared to need.
What can you test this week?
Run the provider's external access analysis across every account and read the findings as an inventory rather than a report. Then query for shared resources by type: snapshots, machine images, database snapshots, container registries, and anything with a resource policy containing a wildcard principal. That combination takes an afternoon and typically finds two or three things nobody knew were reachable.
Next, test from outside. Take the hostnames your content delivery network serves and request the origin directly, bypassing the edge. A surprising proportion of estates have a locked-down edge in front of an origin that answers anyone who asks, which means every control implemented at the edge, including authentication and rate limiting, is optional for anybody who finds the origin address.
Finish with a question rather than a scan: for each of your three most sensitive data stores, could you produce a list of every read in the last thirty days. If the answer is no, that is the highest-value change on this page, and it is a configuration switch rather than a project.
Common questions
- Why is misconfigured cloud storage still so common?
- Because the failure has changed shape. New buckets on the major providers block anonymous access by default, so the single-click mistake is mostly designed out. What remains is deliberate policy: a wildcard principal added to unblock a partner, a grant to all authenticated users misread as meaning your own staff, or a policy correct for one prefix and applied to a whole store. Each looks like an approved change in review.
- What does grant to all authenticated users mean?
- On several cloud services it means any authenticated account on that provider, not only accounts inside your organisation. Since anyone can create an account with the provider, the practical effect is close to public, with the difference that the requester is logged. It is one of the most consistently misread settings in cloud storage and is a good candidate for an organisation-level denial.
- Can a public snapshot expose a private database?
- Yes. A database snapshot marked as shared can be restored by whoever it is shared with, producing a full copy of the data without any request reaching your running instance and without appearing in your application logs. Disk snapshots and machine images behave the same way, and both commonly contain credentials left on the filesystem. Query for shared snapshots and images periodically, not just for public buckets.
- Will a policy review find an exposed bucket?
- Often not, because effective access is computed from several documents at once: the resource policy, the caller's identity policy, account-level public access blocks, organisation-level denials and sometimes network rules. Reading one of them tells you one term of the expression. Use the provider's external access analysis, which computes what is actually reachable from outside your organisation, and treat its output as an inventory.
- Do cloud audit logs show that data was downloaded?
- Not by default. Control plane logs record that a policy was changed; they do not record object reads. Data plane logging is a separate, chargeable setting that is commonly left off on exactly the largest stores. Without it you cannot answer whether anything was accessed during an exposure, which forces the response to assume the worst. Enable it selectively on stores holding personal data, credentials or backups.
- How should we handle content that is meant to be public?
- Put it in a separate account whose only purpose is public content. That keeps strict organisation-level denials in force everywhere else without exceptions, and reduces the blast radius of a mistake to files you already intended to publish. Exceptions granted inside a general-purpose account are what erode the control, because the denial has to be weakened for everyone.