Your Supabase users can probably give themselves your paid plan. Here's the 30-second test
A lot of apps built with Lovable, Bolt or Cursor handle "upgrade to Pro" with one line in the browser: await supabase . from ( " profiles " ). update ({ is_pro : true }). eq ( " id " , user . id ); If that line works for your code, it works for anyone. Open DevTools, run the same thing in the console, and the paid plan is theirs. Same for plan , credits , role or trial_ends_at . Why RLS doesn't…
Supabase users may unintentionally gain access to a paid plan by following a simple 30-second procedure. This can be demonstrated by executing code in the browser's Developer Tools console, which grants the user the paid features. The usual method of restricting user updates to their own profile using PostgreSQL Row Level Security (RLS) is ineffective in this situation because it does not cover specific columns.
To prevent unauthorized access, there are three main solutions: granting updates per column, implementing a trigger to guard billing columns, or separating billing information into a distinct table with proper permissions. It is crucial to ensure that only the payment webhook can modify billing-related data, using a secure server-side key. Disabling Row Level Security is not recommended, even if issues arise.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.