Row Level Security disabled on a table
What it looks like
-- supabase/migrations/20250101_orders.sql
create table public.orders (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users,
total_cents integer,
card_last4 text
);
-- no: alter table public.orders enable row level security;What happens
Anyone with the project URL and the public anon key, both of which sit in the app's JavaScript, can read, edit or delete every row in the table.
Where it shows up
Descriptive, not a verdict: builders and stacks whose defaults make this reachable, or that a public incident names. Each hub states the tool's own security features.
Seen in public
A scan of 1,645 Lovable-built apps found 170 (about 10.3%) with database endpoints readable without login because Supabase row-level security policies were missing or too broad; recorded as CVE-2025-48757, CVSS 9.3.
- 1,645 Apps scanned
- 170 Apps with inadequate RLS
- 10.3% Share of scanned apps
- 303 Exposed endpoints
- 9.3 Critical CVSS 3.1 base score (CVE record)
- 8.26 Researcher's own CVSS base score
- 2025-03-21 Scan date
- 2025-05-29 Public disclosure
May 2025 · Matt Palmer (Replit, Inc.) · all sources
Moltbook, a social network for AI agents built with AI-generated code, ran a Supabase database without row-level security policies, leaving 1.5 million API tokens and 35,000 email addresses readable and writable without login.
- 1.5 million API authentication tokens exposed
- 35,000 Email addresses exposed
- about 17,000 Human account owners in database
- 2026-01-31 Reported to maintainer
- 2026-01-31 (within about 2 hours) First fix applied
Feb 2026 · Wiz Research · all sources
Check it yourself
Uses your builder's dashboard and your browser. No tools to install.
- In the Supabase dashboard open Table Editor. Tables without Row Level Security (RLS, the per-row access rules Postgres applies to each query) show an
RLS disabledorUnrestrictedlabel next to the name. - Open Advisors, then Security Advisor, and look for the finding
RLS Disabled in Public. - Optional: from your computer, run
curl "https://YOUR-PROJECT.supabase.co/rest/v1/orders?select=*" -H "apikey: YOUR_ANON_KEY"with a table name from your app and the anon key from Project Settings. The anon key is already public, so this is safe to type. - A bad result is any table marked unrestricted, any Security Advisor finding on RLS, or a curl response that returns rows while you are not signed in.
What we check
We enumerate every table reachable through the API using the anon key, then again as two ordinary signed-in users, and record which rows each role can read, insert, update and delete. The report lists each table, the role, the operation and a sample of the data reached, with identifiers redacted.
Fix direction
Run alter table public.<name> enable row level security; for each table, then write policies that match rows to auth.uid(). Supabase enables RLS by default on tables created in the dashboard, and its Security Advisor flags tables where it is off, so use both as a running check after each change.
Mechanism documented in: Row Level Security (verified 2026-09-21); Database Advisors (verified 2026-09-21).
Covered by
Pre-launch check ($490, 48 hours) and Security sweep ($290, 24 hours)
Both include a re-check after your fixes.
Related patterns
- RLS policy that allows everything with using (true)Data accessCritical
The table looks protected in the dashboard, yet any visitor with the public anon key can read, insert, update and delete every row.
- Any signed-in user can read every rowData accessCritical
Anyone who creates a free account can page through every other customer's records, which is a data breach with a sign-up form as the only step.
- Service-role key shipped in the browser bundleSecrets and keysCritical
Anyone who opens the app can copy the key from the downloaded JavaScript and read, change or delete every row in every table.
- Record ids accepted without an ownership checkData accessCritical
Anyone who changes the id in a URL or request can read, edit or delete another customer's record.
Questions
how do i know if my supabase rls is enabled
Open Table Editor in the Supabase dashboard: a table without Row Level Security carries an RLS disabled or Unrestricted label. The Security Advisor under Advisors lists the same tables as RLS Disabled in Public. Supabase turns RLS on by default for tables created in the dashboard, so the gap usually comes from tables created by SQL or migrations.
what happens if rls is disabled in supabase
Supabase's documentation states that a table in an exposed schema without RLS is readable and writable by any role with a grant on it. In practice that means the anon key, which every visitor can copy from your app's JavaScript, can read and change every row. Enabling RLS with no policies blocks all API access, and policies then open it row by row.
does supabase warn about tables without rls
Yes. The Security Advisor in the dashboard flags tables in the public schema where RLS is off, and Supabase has said it emails project owners about such tables. The warnings appear after the table exists, so a table added by an AI builder can sit open until someone reads the advisor. Check it after each schema change.
Back to the catalogue, or run the self-check for your stack.