All posts
VibeZero Team5 min read

Is Lovable safe?

Yes, and one documented failure got 170+ Lovable apps breached. What CVE-2025-48757 showed, why the security scan missed it, and the checks that answer it.

  • security
  • vibe coding
  • lovable

Yes. Lovable is safe to build with, and the apps it generates are not safe to launch without checking one specific thing. Those two sentences are both true, and collapsing them into a single yes or no is what makes this question hard to answer honestly.

The specific thing is database access control. It has a CVE, a disclosure timeline, and a count of production apps that leaked because of it. That is unusually good evidence for a question people normally answer with vibes, so this post is mostly the evidence.

The failure that has a CVE

On 20 March 2025, security researcher Matt Palmer found that a Lovable-built site exposed its Supabase database to unauthenticated reads. The next day he confirmed the same misconfiguration across many other projects and emailed Lovable. That became CVE-2025-48757, a CVSS 9.3 flaw in which Lovable-generated projects shipped Supabase tables with missing or insufficient Row Level Security.

The mechanism is worth understanding, because it is not a bug in the sense of a broken line of code. Supabase exposes your Postgres tables over a REST API, and the anon key that authorizes that API ships in your frontend bundle by design. Row Level Security is the only thing standing between that public key and your data. Lovable created tables and did not enable it. The result is that the login screen is real, the session is real, and none of it matters: an attacker skips the UI entirely and queries the REST endpoint with the key they read out of your JavaScript.

More than 170 deployed projects were confirmed exposed, leaking emails, API keys, and payment records. Palmer’s disclosure statement records the timeline: Lovable confirmed receipt on 24 March, a Palantir engineer independently found and tweeted about the same issue on 14 April, a 45-day disclosure window opened, and the CVE published on 29 May.

Why the security scan did not settle it

Lovable shipped a security scan feature with Lovable 2.0 on 24 April 2025, during that window. This is the part most summaries of the incident skip, and it is the most useful thing in the whole story.

The scanner, in Palmer’s description, “merely checks for the existence of any RLS policy, not its correctness or alignment with application logic.” A table with a policy passes. A table with the policy for all using (true) also passes, and that policy permits everything to everyone. The check is real and the property it certifies is not the property you care about.

On 24 May, a month after the scan shipped, Palmer reassessed a live site and bypassed its access controls by removing the Authorization header. He was able to insert records, including one setting "payment_status": "paid", which walks straight past the Stripe integration.

What Lovable actually gets right

A fair answer has to include this part, because the risk profile is not “Lovable is careless.”

Lovable puts your app on Supabase, which means you get Postgres with real row-level access control available, real auth, and Edge Functions where a secret can live server-side. The primitives you need are all there and they are good ones. Lovable also generates authentication reliably: ask for login and you get login, with sessions and password hashing handled by Supabase rather than invented. Compare that to the era of hand-rolled auth and it is a clear improvement.

The gap is narrower than “AI writes insecure code.” It is that the generator creates tables without turning on the mechanism that protects them, and the resulting app works perfectly, which removes the only signal a non-specialist builder would have noticed.

Three checks that answer it for your app

The general question is unanswerable. The specific one takes about ten minutes.

1. Is RLS on for every table? Run this in the Supabase SQL editor:

select tablename, rowsecurity
from pg_tables
where schemaname = 'public';

Any row with rowsecurity = false is world-readable by anyone holding the key in your bundle.

2. Does the policy actually deny? Do not trust the presence of a policy. Attempt the read yourself with nothing but the anon key, which is public information:

curl -s "https://<project-ref>.supabase.co/rest/v1/profiles?select=*" \
  -H "apikey: <your-anon-key>"

An empty array [] is the correct answer. Rows coming back means anyone on the internet can read that table right now.

3. Is anything secret in your bundle? Build and look:

npm run build
grep -rEo "eyJ[A-Za-z0-9_-]{20,}|sb_secret_[A-Za-z0-9]{20,}|sk-[A-Za-z0-9]{20,}" dist/

The anon key showing up is expected and fine once check 1 and 2 pass. A service_role key showing up is not, because that key carries BYPASSRLS and makes the first two checks irrelevant. Rotate it before doing anything else.

If those three pass, you have closed the thing that produced the CVE. The full walkthrough covers the fixes in order, and the mechanism itself is worth reading once in the RLS explainer because it applies to every Supabase project regardless of what generated it, including Bolt.new ones.

Safe is not a property of the platform

The honest version of the answer is that “is Lovable safe” is the wrong shape of question. Lovable is a code generator. The question that has an answer is whether the specific app it generated for you enforces access control at the database, and that is checkable in ten minutes by anyone, today, with the three commands above.

What the CVE story adds is a warning about the second-order failure. The scan existed, it returned green, and the data was still readable. A check that cannot fail is not evidence of safety, and the gap between “a policy exists” and “the policy denies” is exactly where those 170 apps lived. That is why VibeZero scores a Lovable repo across five layers and reports a blocker rather than a checkmark (see Lovable security for what that covers). A result you cannot fail is not a result.

ShareXLinkedIn