skip to content

An external scanner reports that your receipts store is readable by anyone on the internet — which grant produces that, and what was not leaked?

level: juniorimportance: must knowfreq 70%

answer

  1. stores are closed until someone opens them
  2. the finding is a grant, not a breach
  3. nobody authenticated, so nothing was stolen
  4. knowing a key differs from discovering keys
  5. a per-object grant hides from a store-level review

basics

~20 s

A grant written on the store side — at store or object level — naming any caller as allowed to read produces public access. Nothing was leaked: the store is doing exactly what its policy says, so no credential was stolen and no defect was exploited.

solid answer

~40 s

Object stores start closed, so a store is only reachable by an anonymous request if someone wrote a grant on the store side naming an unrestricted caller — either on the store's policy or on individual objects. The scanner needed no credential, which is the whole finding: this is not a stolen key, not an exploited bug, and not a platform failure, so rotating secrets fixes nothing. Two separate capabilities are worth telling apart: reading an object whose exact key you already know, and listing the store to discover keys. A store that allows listing turns a guessing problem into a download. Treat the data as copied, remove the grant, then find who wrote it and why.

go deeper

for a junior

Know that object stores deny by default, so public access is always something someone granted on the store side. Be able to say that an anonymous reader means no credential was stolen.

for a middle

Explain the difference between being able to read a known key and being able to list the store, and where a grant can hide when the store's own policy looks clean.

for a senior

Handle it as a data-exposure incident: remove the grant, bound the exposure from access records, trace the change in the management audit trail, then separate public assets from private data.

for a principal

Decide the standing rule. One store per exposure class, a deliberate exception path for genuinely public assets, and a preventive control so the question stops arriving from strangers.

The mobile backend keeps user-uploaded receipts in an object store and serves them to the app. Someone running an internet-wide scan reports that the receipts are readable without any credential. Understanding what that finding is — and is not — is a first-screen question for anyone who has deployed a service that writes files. ## What "public" actually means here Object stores are closed by default: an unmatched request is denied. So a public store is not a gap, it is a **grant**. Somewhere on the store side there is a rule naming an unrestricted caller — *anyone*, or the anonymous caller — as allowed to read. It can sit in two places: - on the **store's policy**, which applies to everything in it (or to a key prefix inside it); - on an **individual object**, granted one at a time, often by whatever code uploads it. The second is the nastier variant, because a store whose policy reads perfectly tight can still contain thousands of individually exposed objects, and the store-level view shows nothing. ## Readable is not the same as listable | Capability granted | What an anonymous caller can do | Practical effect | |---|---|---| | Read an object | fetch an object whose full key it already knows | exposure depends on whether keys are guessable | | List the store | enumerate every key in the store | turns the store into a downloadable archive | Teams often lean on unguessable keys — a long random component in the object name — and call that acceptable. It is a real mitigation and a weak one: keys escape through links, logs, referrer headers and shared screenshots, and a single accidental listing grant deletes the mitigation entirely. If the scanner produced a **list** of your objects, assume complete exposure. If it produced one object it already knew about, exposure is narrower but the grant is the same defect. ## Why nothing was leaked This is the part candidates get wrong. The scanner authenticated as nobody. That means: - **no credential was stolen**, so rotating keys, passwords or tokens changes nothing about the finding; - **no software defect was exploited**, so there is no patch to apply; - **the platform behaved correctly** — it enforced the policy it was given, and the policy said yes. The defect is entirely in the grant, and the fix is entirely in the grant. Rotating secrets in response is a common and expensive misdiagnosis that leaves the store open while everyone is busy. ## How stores end up like this The recurring routes are mundane: 1. Someone loosened the policy to unblock a demo, a browser upload or a mobile client that could not sign requests, and it was never tightened. 2. A rule meant to widen the **resource** — every key under a prefix — was written to widen the **caller** instead. 3. A pattern for serving a public website's assets was copied onto a store that also holds private data, because one store was cheaper to operate than two. 4. The upload path grants each new object out individually, so the exposure grows with traffic and no one edits anything. ## What to do, in order 1. **Remove the grant** and confirm an unauthenticated request now fails. Stop the bleeding before investigating. 2. **Assume the data is copied.** Public means public for as long as the grant existed; the response is a data-exposure response, not a configuration cleanup. 3. **Read the audit trail** of reads against the store to bound what was fetched and from where — accepting that access logging may not have been on, which is itself a finding. 4. **Find the change** in the management API's audit record: who wrote the grant, when, and with what stated purpose. That tells you whether this was one mistake or a pattern. 5. **Separate the stores.** If genuinely public assets and private user data share one store, the long-term fix is two stores with different policies, not a cleverer single policy. The last step is the one that stops a repeat. A store that holds only public assets can be public without anyone losing sleep; a store that holds user documents should be one whose policy nobody has a reason to loosen.

  • The store's policy looks tight, yet objects are still fetchable anonymously. Where else can the grant be?
    On the objects themselves. Many stores allow a grant per object, and an upload path can set one on every write, so exposure accumulates without anyone editing the store's policy. Audit at object level, or use an account-level setting that refuses public grants outright, since that applies whatever individual objects say.
  • Is relying on long random object keys instead of a policy an acceptable control?
    Only as a second layer. Unguessable keys narrow discovery, but keys travel in links, logs, referrer headers and screenshots, and one listing grant makes them all enumerable. The access decision should be a policy the store enforces; treat key entropy as defence in depth, never as the control itself.

saying these in an interview costs you the question

  • Calls it a breach and starts rotating credentials first
  • Says the platform or a bug exposed the store
  • Treats unguessable object keys as equivalent to a policy
  • Assumes a clean store policy proves no object is public
  • Fixes the grant and skips assessing what was downloaded