Lovable Security: What CVE-2025-48757 Taught Us and How to Check Your App
The defining Lovable security issue is CVE-2025-48757: a critical flaw where Lovable-generated apps connected to Supabase without a working Row Level Security policy, so a remote, unauthenticated attacker could read or write the app's database directly. To check whether your own Lovable app is affected, you do two things — verify Row Level Security inside Supabase (which no outside tool can do for you), and run an external scan for the other half: a leaked service-role key, missing security headers, and exposed files. This guide explains exactly what happened and how to check both.
What was the Lovable vulnerability (CVE-2025-48757)?
In May 2025, MITRE published CVE-2025-48757, affecting Lovable through 2025-04-15. The official description is blunt:
"An insufficient database Row-Level Security policy in Lovable through 2025-04-15 allows remote unauthenticated attackers to read or write to arbitrary database tables of generated sites."
It carries a CVSS base score of 9.3 (critical) and is classified as CWE-863: Incorrect Authorization. In plain terms: the apps shipped Supabase's public anon key in their frontend — which is normal and expected — but left Row Level Security (RLS) turned off. With RLS off, that public key isn't gated by anything, so anyone who opens DevTools, grabs the key, and points it at the Supabase API can pull or modify every row.
It's worth noting Lovable disputes the CVE, taking the position that customers are responsible for protecting their own application data. That's a fair point about responsibility — but it doesn't change the technical reality that the default output left a lot of apps exposed.
Why did so many Lovable apps leak data?
Because the dangerous configuration was the path of least resistance. When you wire a Supabase backend into a generated app and never explicitly enable RLS, PostgreSQL happily returns every row to any caller holding the anon key. Nothing visibly breaks during the demo — the app works — so the gap ships.
The scale was not theoretical. Security researcher Matt Palmer crawled 1,645 Lovable-powered projects and found 303 insecure endpoints across 170 sites — about one in ten (10.3%), the result of missing or insufficient Row Level Security. Across the affected apps, reported exposed data included names, email addresses, phone numbers, home addresses, payment details, and third-party API keys — readable by anyone who modified a network query.
This is the same root cause we cover in depth for the platform generally in Supabase security: what an external scan can and cannot tell you — Lovable just made it the default for a wave of apps at once. And it's a textbook instance of the broader pattern in the security risks of vibe coding: AI-generated code optimizes for "works on the first try," not "safe in production," and access control is exactly the part a quick demo skips.
Is Lovable safe to use now?
Mostly, with a critical caveat. Lovable updated its code-generation pipeline to include RLS policies in new projects, and added a feature that flags whether an RLS policy exists on a table. Both are real improvements.
But two things still put the responsibility on you:
- Existing apps weren't retroactively fixed. An app generated before the change stays vulnerable until its owner manually enables and configures RLS.
- "A policy exists" is not "a policy works." Flagging that an RLS policy is present doesn't confirm it actually blocks unauthorized access — a permissive or incorrect policy can still leak data. Confirming correctness is a job only you can do, inside your database.
So the honest answer to "is Lovable safe" is: the platform's new defaults are better, but the security of your app comes down to whether your RLS is correctly configured — and that's something you have to verify yourself.
Where Lovable security breaks down — and who can check each part
The incident splits cleanly into what an external scan can see and what only you can verify from inside Supabase.
| What can go wrong | Who can verify it |
|---|---|
| Missing or incorrect RLS (the CVE-2025-48757 root cause) | You only, inside Supabase — no external scanner can test RLS |
| Anon key not properly gated by RLS | You only — depends on the policies above |
| Service-role key leaked into the frontend bundle | An external scan can catch this |
.env / .git / config files served publicly | An external scan can catch this |
| Missing security headers, weak TLS, permissive CORS | An external scan can check the deployed domain |
The trap to avoid: a scanner that claims to "check your Lovable security" and clears your RLS from the outside cannot actually have tested it — RLS lives in your database, and nothing in an HTTP response reveals whether a policy is correct.
How do I check my Lovable app?
Do both halves. They cover different failure modes and neither substitutes for the other.
Half 1 — verify RLS yourself, inside Supabase (this is the CVE)
This is the part that actually caused the breaches, and it's the part only you can do:
- Enable RLS on every public table. Any table reachable by the anon key must have RLS turned on. A table with RLS off is wide open. The Supabase Row Level Security guide is the canonical reference.
- Write explicit policies. Enabling RLS with no policies denies everything; you then add scoped
SELECT/INSERT/UPDATE/DELETEpolicies (typically keyed onauth.uid()). Test them as an anonymous user and a logged-in user. - Run Supabase's Security Advisor. It flags tables with RLS disabled. Don't stop there — confirm each policy actually restricts access the way you intend.
Half 2 — scan the deployed app from the outside
The external surface is where an automated scan earns its keep. SteelSuit is a black-box scanner — it sees only what your deployed site serves, with no database or repo access — so it covers exactly the half that's visible to an attacker:
- Leaked secrets. It fetches your HTML and JavaScript bundles and runs TruffleHog's 800+ detectors over them in pattern-match-only mode (
--no-verification— it never calls Supabase with a found key). If a Supabase service-role key — the one that bypasses RLS entirely — shipped to the browser, it gets flagged. For the publishable-vs-secret distinction, see how to find exposed API keys on your website. - Exposed files. It probes for
/.env,/.env.local, and/.git/config— common places a Supabase URL and keys get accidentally served. - External posture. TLS configuration, security headers (CSP, HSTS, X-Frame-Options), and CORS behavior on the domain hosting your app.
A free fast scan takes about 26 seconds and needs no signup; the deeper scan (~5–6 minutes) runs after you prove domain ownership via DNS-TXT. For a Lovable app, the single most valuable thing it can return is the one finding that turns an RLS gap into a full breach: a service-role key that shipped to the browser.
To be explicit about the boundary: SteelSuit does not and cannot test your RLS policies — that's Half 1, inside Supabase. What it does is make sure the external mistakes that compound an RLS gap (a leaked service-role key, an exposed .env) aren't also true.
The takeaway
CVE-2025-48757 wasn't an exotic exploit — it was a missing checkbox, repeated across a wave of AI-generated apps. The lesson isn't "don't use Lovable"; it's that the security of an AI-built app is your responsibility, and it has two halves. Inside Supabase, enable and verify RLS on every table — that's the gap that leaked the data, and only you can close it. From the outside, scan for a leaked service-role key, exposed files, and weak headers. The platform improved its defaults; your job is to confirm your app actually got the fix.
Frequently asked
Is Lovable safe to use?
Lovable itself is a legitimate AI app builder, but apps it generated were the subject of CVE-2025-48757 — a critical (CVSS 9.3) flaw where missing Supabase Row Level Security let anyone read or write the database. Lovable has updated its code generation to add RLS to new projects, but apps built before that fix stay vulnerable until their owner manually enables and configures RLS. So 'is Lovable safe' depends less on the platform today and more on whether your specific app has RLS correctly configured — which is on you to verify inside Supabase.
What is CVE-2025-48757?
CVE-2025-48757 is a critical information-disclosure vulnerability affecting Lovable through 2025-04-15. Its official description: an insufficient database Row-Level Security policy allows remote unauthenticated attackers to read or write to arbitrary database tables of generated sites. It is classified as CWE-863 (Incorrect Authorization) with a CVSS base score of 9.3. The practical cause is that Lovable apps shipped the public Supabase anon key in the frontend while leaving RLS off, so anyone could query the database directly.
Can a scanner check my Lovable app's RLS?
No. Row Level Security policies live inside your Supabase database, not on the network, so no external black-box scanner — SteelSuit included — can see or test them. Anyone claiming to verify your RLS from the outside is overstating what is possible. You must check RLS yourself inside Supabase: enable it on every public table, write explicit policies, and run Supabase's Security Advisor. An external scan complements this by catching a leaked service-role key, weak headers, and exposed files — the parts that ARE visible from outside.
How do I secure a Lovable app?
Two halves. Inside Supabase (only you can do this): enable Row Level Security on every table reachable by the anon key, write explicit access policies, and run the Security Advisor to confirm nothing is left open — this is the exact gap behind CVE-2025-48757. From the outside (a scan can help): make sure your service-role key never shipped to the browser, no .env or .git is served, and security headers and TLS are in place. Do both; neither replaces the other.
Did Lovable fix the vulnerability?
Lovable updated its code-generation pipeline to include RLS policies in new schemas, and added a feature that flags whether an RLS policy exists on a table. But existing apps generated before the fix remain vulnerable unless their owner enables RLS, and a flag that a policy *exists* is not the same as confirming the policy actually blocks unauthorized access. The responsibility for verifying that your data is protected still sits with you.