Lovable added a security scan after 170 apps leaked user data. That's good. But there's a gap between "has a security scan" and "is actually secure." Here's what Lovable 2.0 checks, what it misses, and why the difference matters.
Built with Lovable? Paste your URL into vibeAudit — 30 seconds, free, no signup. We'll show you what Lovable's scanner misses.
What Happened: CVE-2025-48757
In early 2025, security researchers discovered that 170 Lovable-built apps had no Row Level Security enabled. The result: 18,000+ users' data was exposed — passports, government IDs, financial records, private messages. The vulnerability was assigned CVE-2025-48757 with a CVSS score of 9.3 (Critical).
The root cause was simple. Lovable created Supabase tables without enabling RLS. Every table was publicly readable by anyone with the anon key — which was already in the JavaScript bundle. (Full breakdown of Lovable vulnerabilities here)
Lovable responded by adding a security scan in version 2.0. That's the right move. But let's look at what it actually does.
What Lovable 2.0 Scans For
Lovable's built-in security scan checks one thing: does Row Level Security exist on your tables?
That's it. If RLS is enabled, you get a green checkmark. If it's disabled, you get a warning. It's a binary check — on or off.
This would have caught CVE-2025-48757. Those 170 apps had RLS completely disabled. Lovable's scanner would have flagged them. Credit where it's due.
But here's the problem.
What Lovable 2.0 Misses
Enabling RLS doesn't mean your data is protected. A policy has to be correct. And Lovable's scanner doesn't check policy correctness.
This passes Lovable's scan with a green checkmark:
-- RLS is "enabled" ✓
ALTER TABLE user_data ENABLE ROW LEVEL SECURITY;
-- But the policy allows EVERYONE to read EVERYTHING
CREATE POLICY "allow_all" ON user_data
FOR SELECT USING (true);
-- This is functionally identical to having no RLS at all.
-- Every row is readable by every user.
-- Lovable's scanner says you're secure. You're not.
It's a smoke detector that checks if the battery exists, not if it's charged.
Beyond policy correctness, Lovable's scanner also doesn't check:
- API key exposure — Are your Supabase, Stripe, or OpenAI keys in your JavaScript bundle?
- Authentication gaps — Can anyone hit your API routes without logging in?
- Security headers — Is CSP, X-Frame-Options, or HSTS configured?
- CORS misconfigurations — Can any origin make requests to your API?
- XSS vectors — Are user inputs sanitized before rendering?
- Open redirects — Can attackers redirect your users to phishing pages?
Want to see what Lovable's scan misses on your app? vibeAudit runs 30+ checks including policy correctness, API key exposure, auth gaps, and header analysis. 30 seconds, free. (Full RLS guide here)
Side-by-Side: Lovable Scan vs vibeAudit
| Security Check | Lovable 2.0 | vibeAudit |
|---|---|---|
| RLS enabled (exists) | ✓ | ✓ |
| RLS policy correctness | ✗ | ✓ |
| USING(true) detection | ✗ | ✓ |
| Data extraction testing | ✗ | ✓ |
| API key exposure scan | ✗ | ✓ |
| Authentication checks | ✗ | ✓ |
| Security headers (CSP, HSTS) | ✗ | ✓ |
| CORS misconfiguration | ✗ | ✓ |
| XSS / injection testing | ✗ | ✓ |
| Open redirect detection | ✗ | ✓ |
Lovable's scan is better than nothing. It would have prevented CVE-2025-48757. But it checks one thing out of dozens that matter.
Why This Matters: The USING(true) Problem
Let's make this concrete. Here are two Supabase setups. Both pass Lovable's security scan. Only one is actually secure.
-- Setup A: Passes Lovable scan ✓ | Actually secure ✓
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users_own_messages" ON messages
FOR SELECT USING (auth.uid() = sender_id);
-- Users can only read their own messages. Correct.
-- Setup B: Passes Lovable scan ✓ | Actually secure ✗
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "read_all" ON messages
FOR SELECT USING (true);
-- Every user can read every message. Including DMs.
-- Including messages with passwords, tokens, personal data.
-- Lovable says you're fine. You're not.
vibeAudit doesn't just check if RLS is on. It runs adaptive scanning: it finds the RLS configuration, then tests what data can actually be extracted with the anon key. If your policy says USING(true), vibeAudit flags it as critical — because it is.
FAQ
Q: Is Lovable's security scan useless?
No. It catches the most basic case — RLS completely disabled. That's better than nothing. But it doesn't check if your policies actually protect anything.
Q: What is CVE-2025-48757?
A critical vulnerability (CVSS 9.3) where 170 Lovable-built apps had no RLS enabled on Supabase tables, exposing 18,000+ users' passports, IDs, and financial data.
Q: Does USING(true) actually pass Lovable's scan?
Yes. Lovable's scanner checks if RLS is enabled on the table. A policy with USING(true) means RLS is technically "on" but provides zero row-level filtering.
Q: What does vibeAudit check that Lovable doesn't?
Policy correctness, data extraction testing, API key exposure, authentication gaps, security headers, CORS, XSS, open redirects, and 20+ other checks.
Q: Is vibeAudit safe to use on my Lovable app?
Yes. vibeAudit runs read-only scans. It never modifies your app, writes data, or stores your results.
Lovable's scan checks the lock exists. vibeAudit checks if it's locked. Paste your URL into vibeAudit — 30 seconds, free, no signup. (See all Lovable vulnerabilities | Full RLS guide) Read-only scan, your app is never modified.