Supabase RLS check: is your data readable by anyone?

Your anon key ships in your frontend by design. Row Level Security is the only thing between that key and your users' data. Here's how to check it from the outside and the inside.

Test from the outside (what an attacker sees)

Find your project URL and anon key in the browser Network tab (requests to *.supabase.co). Then ask only for a row count. This doesn't download any data:

curl -I "https://YOUR-REF.supabase.co/rest/v1/profiles?select=*" \
  -H "apikey: YOUR_ANON_KEY" -H "Range: 0-0" -H "Prefer: count=exact"

Look at the Content-Range header. 0-0/1342 means 1,342 rows are readable by anyone on the internet. */0 means either RLS is hiding the rows or the table is empty. A 401 or 404 means the table isn't reachable.

Check from the inside (SQL editor)

select schemaname, tablename, rowsecurity from pg_tables where schemaname = 'public';
select tablename, policyname, cmd, roles, qual from pg_policies where schemaname = 'public';

Red flags: rowsecurity = false on any table, or qual = true on a table holding user data. "RLS enabled" with a true policy is still wide open — the dashboard shield turns green anyway.

The fix

alter table public.profiles enable row level security;
drop policy if exists "Enable read access for all users" on public.profiles;
create policy "read own profile" on public.profiles
  for select to authenticated using (auth.uid() = id);

Or paste this into Lovable/Cursor:

List every table in my Supabase public schema with its RLS status and policies. For each table with user data, replace any USING (true) / public policy with owner-only policies based on auth.uid(). Show me the SQL migration and the queries in the app that will break, before changing anything.

Note: enabling RLS with no policies blocks everything, so your app may break until you add the right policy. Test after each table.

Why check every week?

Every time the AI adds a table or "fixes" a permission error, it can re-open the door. New tables are exposed by default in many projects.

Do it in 60 seconds.

Start with the free outside-in scan. Need your real RLS policies reviewed? Deep Scan, €9 one-off.

VibeGuard checks ~20 common table names with HEAD requests for row counts only. It never reads or stores your data, and it can't see tables with unusual names or test logged-in access.