Is Lovable safe? What it gets wrong, and how to check
A real CVE exposed 303 endpoints across 170+ Lovable apps. Here are the six gaps Lovable leaves behind, and how to check yours.
Lovable is genuinely good at turning a prompt into a working app. What it is not good at is the part nobody asks for: deciding who is allowed to read which row of your database. That gap is not theoretical — in May 2025 it produced a CVE affecting hundreds of live apps.
Why Lovable specifically
Lovable wires your frontend straight to Supabase. The browser holds a key (the anon key) and talks to the database directly — no backend in between. That design is fine and intended, but it moves the entire security burden onto database rules. If those rules are missing or too loose, the browser key becomes a master key.
The part that caught people out: Lovable's own security scan checked whether an RLS policy existed, not whether it did anything. A policy written as USING (true) — meaning "allow everyone" — passed the check while leaving the table wide open.
“Attackers could read user emails, passwords, payment data, and even admin credentials across 303 vulnerable API endpoints.”
The six gaps, in plain terms
- Open database — anyone can read your tables with the key from your own page. This is the CVE, and the most common serious problem.
- Exposed API keys — an OpenAI or Stripe secret ends up in the JavaScript bundle, where anyone can read it.
- Unprotected pages — /admin exists and answers, because hiding a route from the menu is not the same as protecting it.
- Leftover files — .env, backups or source maps deployed alongside the app.
- Session security — login cookies readable by any script on the page.
- Security headers — the boring layer that turns a small bug into an account takeover.
Check the big one yourself in two minutes
Is your database readable by strangers?
- 1Open your live app and press F12 to open DevTools.
- 2Go to the Network tab and reload the page.
- 3Find any request to a URL ending in .supabase.co. Click it.
- 4In the request headers, copy the value of apikey — that is your anon key. It is meant to be public.
- 5Now run the curl command below, replacing the placeholders with your project URL, that key, and a table name such as profiles or users.
Ask your own database for rows, as a stranger
curl "https://YOUR-PROJECT.supabase.co/rest/v1/profiles?select=*&limit=5" \ -H "apikey: YOUR_ANON_KEY" \ -H "Authorization: Bearer YOUR_ANON_KEY"
If that returns [] you are fine — RLS is doing its job. If it returns actual rows, every one of your users' records is public right now, and you should fix it before anything else on this page.
Audit every table in my Supabase database for Row Level Security. For each table: 1. Enable RLS if it is not already on. 2. Show me the existing policies. Flag any policy whose USING clause is "true" or otherwise unconditional — those pass a naive check but allow everyone. 3. Replace them with policies scoped to the signed-in user, typically auth.uid() = user_id for owner-only rows. 4. Tables that no browser client should ever touch directly must have RLS enabled and no policy at all, so they deny by default. Then list every table you changed, and tell me which ones still allow anonymous reads on purpose and why.
Where to go next
Each of the six gaps has its own page with the specific check and fix prompt. Start with the open database — it is the one that leaks real user data — then work down the list.
This is one check out of 40+
Paste your site address and we run the whole list from the outside — leaked keys, open databases, unprotected pages — then hand you one prompt that fixes what we find. Free, about 30 seconds, no signup.
Check my site — free