Scan rule · RSC-SEC-028
Database tables anonymously readable (proven)
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
How to fix it
Enable Row Level Security and bind every policy to `auth.uid()`, then re-check.