Fixes · Security holes

Supabase tables without Row Level Security: anyone can read and change your data

With Row Level Security off, or a policy of using (true), the public anon key in your app lets anyone read, change or delete every row. The app still works, which is why nobody notices.

Most common in apps built with Lovable, Bolt.

What you see

Nothing looks wrong: the app works in every test. But anyone can open the browser's developer tools, take the Supabase URL and anon key, and query your tables directly.

Why it happens

Supabase gives the browser a public key and relies on Row Level Security (RLS) to decide what each user may see. A table created without RLS, or with a policy that allows everyone (using (true) on an insert, update or delete), protects nothing.

How to fix it

  1. In Supabase → Table editor, make sure every table shows RLS enabled.
  2. For each table, add policies tied to the signed-in user, e.g. using (auth.uid() = user_id).
  3. Keep using (true) only for read policies on data that's meant to be public.
  4. Test it: sign in as one user and try to read another's rows.

Or ask your AI tool to fix it

Paste this into Lovable, Bolt, v0, Replit or Cursor, and let it make the change.

Enable Row Level Security on every table in the public schema, and add policies so each user can only read and change their own rows (auth.uid() = user_id), with public read access only where data is meant to be public. Add it as a new migration, and don't remove any existing data.

Don't change what the app does.
Never put a secret key or password in the code: read it from an environment variable.
If a step has to be done outside the code, like revoking a key in a provider's dashboard, list it for me at the end instead of skipping it.

How Launchpad helps

The launch check reads every migration and lists each table without RLS, and each policy that lets anyone write. Free, for any public repository or zip.

Check your app for this, freeJoin the waitlist

Related