github

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.

Check my project