github

Overly Permissive Policies (USING true) in Supabase

Supabase security checks · HIGH

A policy lets every matching user through, not only the owner of each row.

What goes wrong

A Supabase RLS policy with USING (true) matches every row. On a SELECT policy, the target role can read all rows. On INSERT, UPDATE or DELETE, all writes are allowed.

How it happens

It gets added to make things work during development and is never restricted before deployment. AI code generators default to it because it is the simplest policy that works.

How to find it

List the policies in pg_policies whose USING or WITH CHECK expression is just true.

SELECT tablename, policyname, cmd, roles, qual AS using_expr, with_check
FROM pg_policies
WHERE schemaname = 'public'
  AND (qual = 'true' OR with_check = 'true');

How to fix it

Replace it with an ownership check. USING (true) on SELECT is acceptable for tables meant to be public, like blog posts or products, but writes should always be restricted.

ALTER POLICY "<policy_name>" ON public.<table_name>
  USING ((SELECT auth.uid()) = <user_id_column>);

Check your own project

Locksoup runs these checks on your Supabase database in about a minute, with a read-only role, and gives you the SQL to fix what it finds.

Check my project