// SECURITY
What happens if your database has no Row-Level Security?
Updated 2026-08-11 · 6 min read
Without Row-Level Security (RLS), any table your app can reach is readable by anyone holding your public API key, which sits in the browser. That means a stranger can pull your entire user list, orders, and messages without logging in. RLS is the rule layer that decides who can see which rows; if it is off, the answer is "everyone."
What it is
Supabase and Firebase talk to the browser directly using a public key. Row-Level Security (Supabase) and Security Rules (Firebase) are the gate that decides which rows each request may read or write. Turn the gate off and the public key becomes a key to everything.
Why it matters to you
This is the single most damaging mistake in AI-built apps. CVE-2025-48757 (CVSS 9.3) showed 170+ Lovable-built apps left readable because RLS was never enabled, exposing full user lists, payment records, and API keys to anyone who opened developer tools.
How to tell if your app has it
- Open your app, press F12, and watch the Network tab for requests to *.supabase.co or firestore.
- If rows come back before you log in, those tables are public.
- In Supabase, the dashboard shows an "RLS disabled" warning on any unprotected table.
How it happens in AI-built apps
Supabase ships new tables with RLS off so you can prototype fast, and AI builders rarely turn it on or write correct policies. Two policies look safe but are not: USING(true) allows everyone, and auth.uid() IS NOT NULL allows any logged-in user to read everyone else’s rows.
The fix
Enable RLS on every table and write policies that scope rows to their owner.
alter table orders enable row level security;
create policy "own rows" on orders
for select using ( auth.uid() = user_id );Repeat for insert/update/delete, and for every table. A table with RLS enabled but no policy denies all access by default, which is safe.
Key takeaways
- The public/anon key is only safe when RLS is correct, it is not a secret.
- USING(true) and auth.uid() IS NOT NULL are the two "looks fine, is not" policies.
- Enable RLS on every table; scope rows with auth.uid() = user_id.
Sources
Frequently asked
Is Supabase insecure?
No. Supabase is secure by design, but only if you enable RLS and write correct policies. The defaults are permissive so you can build quickly, which is exactly the step AI builders skip.
How do I know which tables are open?
The Supabase dashboard flags tables with RLS disabled. Veilguard also probes what your public key can actually reach from the outside and lists every open table with the SQL to fix it.