Skip to content
VibeSafeDaily

Break of the day

Cataloged October 16, 2026

Supabase tables ship with row level security off

The app looks correct while you are signed in. A request that carries only the publishable key, and no user session, can still read or write a table.

Lovable · Bolt · Cursor · Replit · v0 · Supabase

Recent breaks

All 30
  1. 02A policy uses USING (true) on private rowsRow level security is on, and the app still returns every row to any signed-in user, or to nobody at all.Exposed data
  2. 03Table grants stay wide open after policies are addedYou added policies, then a signed-out client can still insert, or a signed-in client can still delete rows the policy was meant to hide.Exposed data
  3. 04A view bypasses row level securityThe table policies look right. A view the app selects from still returns every row.Exposed data
  4. 05The service role key is in the browser bundleData API calls from the site ignore every row policy. Searching the shipped JavaScript turns up a secret or service role key.Secrets
  5. 06A VITE_ variable bundles a secret into the clientAn API key works in the browser preview. Anyone who opens the built JavaScript can read it.Secrets
  6. 07NEXT_PUBLIC_ inlines a secret at build timeA key was added as NEXT_PUBLIC_ so a client component could read it. The production bundle contains the value.Secrets
  7. 08A Client Component reads a server environment variableThe variable is not prefixed NEXT_PUBLIC_, but the secret still shows up in the HTML of a page that renders a Client Component.Secrets
  8. 09An Edge Function turns auth off and never checks the callerA function that changes data or spends money returns 200 with no session. It was set to verify_jwt = false, or auth: 'none', to clear a 401 during development.Auth

VibeSafe Daily catalogs public failure modes in apps built with Lovable, Bolt, Cursor, Replit, and v0. Every check on this site is for an app you own.