RLS Enabled Without Policies
RLS is enabled on a table but no policies are defined, which silently blocks all access including legitimate queries from your application.
How It Works
When RLS is enabled on a Supabase table but no policies exist, PostgreSQL defaults to denying all access. This means your application cannot read, insert, update, or delete any rows through the client library. While this is secure by default, it often leads developers to bypass RLS entirely using the service_role key on the client side, which is far worse. The table appears broken, so devs either disable RLS or leak the service key — both critical security mistakes.
-- RLS is on, but no policies exist
ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;
-- No policies created!
-- Developer "fixes" it by using service_role in the frontend:
const supabase = createClient(url, SERVICE_ROLE_KEY); // DANGER!ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users_read_own_orders" ON public.orders
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "users_insert_own_orders" ON public.orders
FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "users_update_own_orders" ON public.orders
FOR UPDATE USING (auth.uid() = user_id);Real-World Example
A common pattern in Supabase projects on GitHub: developers enable RLS to satisfy linting warnings, but never create policies. When their app breaks, they switch to the service_role key in client code, unknowingly giving every user full admin access to the database.
How to Prevent It
- Always create at least one policy per operation when enabling RLS
- Test RLS policies from the client immediately after writing migrations
- Use Supabase CLI to verify policies: supabase db lint
- Never use the service_role key in client-side code as a workaround
Affected Technologies
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
Row Level Security Disabled
criticalSupabase tables without RLS enabled allow any authenticated or anonymous user to read, insert, update, and delete all rows using the client library.
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.
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.