I've mentioned storage buckets in passing before, and I want to give the topic its own dedicated teardown, because the specific mistake here is easy to misunderstand as "less bad" than an exposed database, when in practice it can hand over just as much.
The two separate settings, and why they get confused
Cloud storage, Supabase Storage, Firebase Storage, an S3-style bucket, has two related but distinct settings worth telling apart. Whether a specific file can be read if you know its exact path is one setting. Whether the bucket will hand back a full list of every file it contains, without you needing to know any specific filename in advance, is a separate one. A lot of builders reasonably lock down or think about the first case and never check the second.
Why the listing setting matters so much
If individual files require a guessable-but-not-truly-secret path, an uploaded document, a generated report, a user's profile image, that's a manageable risk as long as nobody can enumerate what exists. The moment a bucket allows public listing, that assumption collapses entirely. Anyone can request the full file list, see every filename that exists, and then simply request each one directly. The obscurity of any individual filename stops mattering the instant the whole list is handed out for free.
What this actually looks like as a real request
For most cloud storage providers, listing a bucket's contents is a single, simple API call, sometimes reachable directly through a browser URL with no special tooling required at all. If that call succeeds without any authentication, whoever finds the bucket's name, sometimes visible in your own frontend code or a public config, can pull a complete inventory of every file stored there in one request.
How to actually check your own buckets
- Find your storage bucket's name or endpoint, often visible in your app's own client-side configuration.
- Try listing its contents directly, using your provider's documented listing endpoint, with no authentication attached.
- If you get back a list of files rather than a permission error, that's the setting worth fixing immediately, separate from whether individual files are otherwise protected.
- Check this for every bucket your app uses, not just the one you remember setting up. Buckets added for a specific feature months ago are exactly the ones most likely to have been left on a permissive default.
The fix
Nearly every provider lets you disable public listing while still allowing direct, authenticated or scoped access to individual files when appropriate. The two settings are meant to be controlled independently precisely because they represent different risks. Checking that files require the right permission to read and separately confirming the bucket itself refuses to list its full contents closes off the specific gap this post is about, and it's a five-minute check per bucket, not a redesign.