Row Level Security Disabled
Supabase tables without RLS enabled allow any authenticated or anonymous user to read, insert, update, and delete all rows using the client library.
How It Works
In Supabase, every table has Row Level Security (RLS) disabled by default. Without RLS, any user with the anon key can perform full CRUD operations on the table through the PostgREST API. This means anyone with your project URL and anon key (which is public) can read every row, delete data, or insert malicious records. The anon key is designed to be public, so RLS is the only barrier preventing unauthorized data access. A single table without RLS can expose your entire dataset.
-- Migration file
CREATE TABLE public.documents (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
user_id uuid REFERENCES auth.users(id),
title text NOT NULL,
content text,
created_at timestamptz DEFAULT now()
);
-- No ALTER TABLE ... ENABLE ROW LEVEL SECURITY!CREATE TABLE public.documents (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
user_id uuid REFERENCES auth.users(id),
title text NOT NULL,
content text,
created_at timestamptz DEFAULT now()
);
ALTER TABLE public.documents ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can access own documents" ON public.documents
FOR ALL USING (auth.uid() = user_id);Real-World Example
Multiple startups using Supabase have been found with RLS disabled on user data tables. In 2023, security researchers disclosed that several YC-backed startups had publicly accessible Supabase tables exposing user emails, payment data, and private messages — all because RLS was never enabled.
How to Prevent It
- Always add ALTER TABLE ... ENABLE ROW LEVEL SECURITY in every migration
- Use Supabase Dashboard to audit RLS status on all tables
- Add a CI check that scans migrations for missing ENABLE ROW LEVEL SECURITY
- Never assume the anon key is secret — it is public by design
Affected Technologies
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
RLS Policy with USING(true)
criticalRLS policies that use USING(true) or WITH CHECK(true) effectively disable row-level security by allowing all operations for all users.
RLS Enabled Without Policies
highRLS is enabled on a table but no policies are defined, which silently blocks all access including legitimate queries from your application.
Service Role Key Exposed
criticalThe Supabase service_role key is hardcoded in frontend code, committed to a repository, or exposed in client bundles, granting full database admin access to anyone.
Public Storage Buckets
mediumSupabase storage buckets with overly permissive policies allow any user to upload, read, or delete files including other users' private documents and images.