Menu

Your Supabase users can probably give themselves your paid plan. Here's the 30-second test
📰

Your Supabase users can probably give themselves your paid plan. Here's the 30-second test

DEV Community: postgres·LeakPatrol·1 day ago
#GhXh1ngg
#devtopostgresql#devto#dev#columns#profiles
Reading 0:00
15s threshold

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 );

Enter fullscreen mode

Exit fullscreen mode

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 stop it

The usual policy on a profiles table is "users can update their own row":

create policy "Users can update own profile" on public . profiles for update using ( auth . uid () = id );

Enter fullscreen mode

Exit fullscreen mode

That policy decides which rows a user may change. It says nothing about which columns . If billing columns live on that row, the user can change those too.

Deleting the update call from your frontend doesn't fix it either.…

Continue reading — create a free account

Join HashtagPLUS to read full articles, follow hashtags, vote, and join the conversation.