Skip to content

Scan rule · RSC-SEC-028

Database tables anonymously readable (proven)

SecuritySeverity: HighCWE-284OWASP A01-2021

Answers the actual question: do rows really come out with the publicly shipped key? Counting happens purely via the `Content-Range` header of a HEAD request — not a single row is fetched.

Why this matters

A table being granted to the anon role does not yet mean data comes out — Row Level Security decides that. This rule settles the difference: it asks for the row count and thereby proves whether the table is genuinely open.

The proof is deliberately minimal: a HEAD request with `Range: 0-0` and `Prefer: count=exact`. It returns the count in a response header and no content. Only the key the app itself publishes in every browser is used — that fetches less than a normal page view of the same app.

If a number greater than zero comes back, the login is irrelevant: anyone can read this data straight from the database without using the app. Fix: enable RLS on the table, bind every policy to `auth.uid()`, then scan again — the finding must disappear.

Scan tier

External scan (anonymous)

How to fix it

Enable Row Level Security and bind every policy to `auth.uid()`, then re-check.

Scan your own app for free