Mass Assignment via Column Updates in Supabase
Supabase security checks · HIGH
Users can update every column of their own rows, including ones they shouldn't touch, like roles or balances.
What goes wrong
Row level security (RLS) in Supabase is row-level, not column-level. An UPDATE policy that lets users change their own rows also lets them change any column in those rows, including is_admin, role, credits, balance or plan. An attacker adds extra fields to a PATCH request.
How it happens
The table has an UPDATE policy for the row’s owner and no column-level privileges protecting the sensitive columns.
How to find it
Check the tables that have UPDATE policies for sensitive columns such as role, admin, balance, credits, plan or permissions, then cross-reference with the column-level privileges.
How to fix it
Use column-level privileges so users can only UPDATE the columns they may edit. You can also add a BEFORE UPDATE trigger that resets sensitive columns to their old values, or handle sensitive updates in Edge Functions.
REVOKE UPDATE ON public.<table_name> FROM authenticated; GRANT UPDATE (<safe_column_1>, <safe_column_2>) ON public.<table_name> TO authenticated;
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.