A Supabase table without row-level security is readable and writable by anyone who has the anon key — and the anon key ships in every client bundle by design. An attacker who opens devtools on the login page can pull the JWT, hit the REST endpoint directly, and dump or mutate the entire table. AI coding tools routinely create tables with the Supabase CLI or dashboard without emitting the ENABLE ROW LEVEL SECURITY statement and without writing policies, because the default CREATE TABLE syntax doesn't require it. This is the single most common cause of public Supabase data leaks — the pattern has been behind dozens of disclosed incidents where customer emails, private messages, and payment records were scraped from production anon endpoints.
Critical because a disabled or missing RLS policy exposes every row in the table to unauthenticated reads and writes through the public anon key, with no code change required to exploit it.
For each user table, add ALTER TABLE public.{table} ENABLE ROW LEVEL SECURITY; and define explicit policies. Without RLS, anyone with the anon key can read/write any row.
Deeper remediation guidance and cross-reference coverage for this check lives in the saas-authentication Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.
project-snapshot.auth-access.no-supabase-rls-disabledcritical@supabase/supabase-js, @supabase/ssr, or supabase/ directory). Enumerate every .sql file in supabase/migrations/, supabase/schemas/, or any project-level migrations directory. Count occurrences of DISABLE ROW LEVEL SECURITY and ALTER TABLE ... DISABLE ROW LEVEL SECURITY. Then enumerate every CREATE TABLE statement and check whether each user-data table (anything not _meta/_audit/migrations) is followed by ENABLE ROW LEVEL SECURITY.DISABLE ROW LEVEL SECURITY statements AND every user-data table has a corresponding ENABLE ROW LEVEL SECURITY statement somewhere in migrations.DISABLE ROW LEVEL SECURITY statement, or at least one user-data CREATE TABLE without a matching ENABLE ROW LEVEL SECURITY."Supabase not detected: no @supabase/* dependency or supabase/ directory".USING (true) (which is effectively disabled).CREATE TABLE statement that lacks a paired ENABLE ROW LEVEL SECURITY."Found N user tables in migrations; all N have ENABLE ROW LEVEL SECURITY.""Table profiles created in 20260101_init.sql but no ENABLE ROW LEVEL SECURITY found" or "3 user tables without RLS: profiles, posts, messages".saas-authentication audit.ALTER TABLE public.{table} ENABLE ROW LEVEL SECURITY; and define explicit policies. Without RLS, anyone with the anon key can read/write any row.