Skip to content
VibeSafeDaily

LibraryExposed data

Supabase tables ship with row level security off

Cataloged October 16, 2026 · Lovable · Bolt · Cursor · Replit · v0 · Supabase

Symptom

The app looks correct while you are signed in. A request that carries only the publishable key, and no user session, can still read or write a table.

Root cause

Supabase's row level security guide says a table in an exposed schema without RLS is readable and writable by any role that already has a grant on it. Matt Palmer's May 29, 2025 writeup, filed as CVE-2025-48757, describes Lovable-generated projects that call a database from the browser with the public anon key and rely on RLS that was never turned on, or that does not match the data. He writes that this affects projects created on or before April 15, 2025, and may also affect later ones. Lovable's security overview says misconfigured RLS is a common cause of data leaks, and its Quick scan flags tables without per-record access control. Lovable also says its scans cannot guarantee complete security.

Fix prompt

In this project only, secure every table in an exposed schema. Do not query or modify any other Supabase project.

1. List tables in the public schema and enable row level security on each one that clients can reach.
2. Revoke all privileges on those tables from anon and authenticated, then grant back only the operations this app actually uses.
3. Add a policy per operation. For private rows, compare (select auth.uid()) to the row's owner column. Do not use USING (true) on private data.
4. For views over those tables, set security_invoker = true.
5. Keep the secret key and service role key out of client code.
6. Add a SQL test that the anon role, and a second authenticated user, cannot read another user's private rows.

Do not change unrelated files.

Paste this into the coding tool that has your own project open.

2-minute self-check

These steps are for an app you own. Do not run them against someone else's project.

  1. Open your own Supabase project, not someone else's. In the Table Editor, confirm Row Level Security is enabled on every table that holds user data.
  2. In Authentication, create two test users in your project. In the SQL editor, impersonate user A and confirm a select returns only A's rows. Repeat as user B.
  3. From your project's API settings, copy your own project URL and publishable key. Signed out, request one of your private tables. The response should not include other people's rows.

Sources

Same symptom