DEV Community

FlawPilot
FlawPilot

Posted on

Lovable App Security We Scanned a Real App and Found 29 Open Issues

 Quick answer: Lovable app security's most common failure isn't a missing header. It's an unset Supabase Row-Level Security policy. Skip it and the app still works, because the query still succeeds, just for anyone, not only its owner. We scanned a real Lovable app and found exactly that gap, live.

Picture the app you shipped last sprint. You described a dashboard, Lovable wired up the tables, the auth, the UI, and it all just worked the first time you clicked through it. That's the whole appeal. It's also exactly why nobody goes back and checks the one setting that doesn't announce itself when it's missing. So we did. We took a real, live Lovable app, built the way most Lovable apps get built (fast, from a prompt, shipped the same week), and ran it through FlawPilot, a free scan that checks a site's security, performance, infrastructure, and SEO in about two minutes, no login required. We won't name the app, but every number below is real, pulled straight from its report.

The scorecard

63 out of 100. "At risk." 252 points out of a possible 400, and 29 things sitting open: 1 critical, 5 high, 15 medium, 8 low.

Split out:

  • Security: 55/100. At risk. 13 findings.
  • Performance: 96/100. Excellent. 2 findings.
  • Infrastructure: 58/100. At risk. 9 findings.
  • SEO & Discoverability: 62/100. Needs attention. 5 findings.

Nothing was defaced. The app looked, and behaved, exactly like it was supposed to. That's the part worth sitting with: every screen worked, every click did the right thing, and the one critical finding on this report had never once shown up as a bug.

What it got right

96/100 on performance is close to a clean sweep. Lovable's scaffolding leans on Vite and React defaults that are already fast out of the box: quick first paint, sensible bundle size, nothing render-blocking that shouldn't be.

Which is exactly the trap. A fast, polished frontend is the thing you notice with your own eyes, so it's the thing that gets credited as "done." Everything below is the kind of gap that only shows up once something outside the team, a scanner, a bot, or someone who isn't supposed to, goes looking for it on purpose.

What was hiding underneath

A Supabase table had no Row-Level Security policy at all. Rated Critical, and it's the finding that matters most on this whole report. Lovable apps run on Supabase by default, and Supabase enforces access at the database layer through RLS policies, not through the app's own login screen. Turn RLS on for a table and the database itself checks who's allowed to see which row. Leave it off, and the table is exactly as open as the anon key that ships in every Lovable app's JS bundle: open to anyone who opens dev tools and watches a single network request. This app's login screen worked correctly the whole time. The database behind it never checked whether the person asking was allowed to see the data they were asking for.

The fix, in Supabase, is two SQL statements:

-- Enable Row-Level Security on the table
ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;

-- Scope reads to the row's own owner
CREATE POLICY "Users can view their own orders"
ON public.orders
FOR SELECT
USING (auth.uid() = user_id);
Enter fullscreen mode Exit fullscreen mode

No rewrite, no data migration, just a policy that tells the database who's allowed to see which row instead of trusting the app's UI to gate it for you. Repeat per table, per operation (SELECT, INSERT, UPDATE, DELETE) as needed.

The rest of the report was more familiar territory:

  • No DMARC record: anyone could send email pretending to be this domain (High)
  • No Content-Security-Policy header: an injected script has nowhere to be stopped (High)
  • No Strict-Transport-Security header: first request can get downgraded to plain HTTP (High)
  • No clickjacking protection: the app can be framed invisibly inside another page (High)
  • No CAA record: any certificate authority could issue a cert for the domain (Medium)
  • No DKIM signature: outgoing mail at real risk of landing in spam (Medium)
  • Missing sitemap.xml, thin meta descriptions: dragged the SEO score to 62 (Medium)
  • Verbose error pages left on: handing back stack traces to anyone who triggers one (Medium)

None of this showed up while clicking through the app. All of it shows up the moment something outside the team, a scanner, a bot, an attacker, bothers to check.

Why this is the default, not a fluke

That combination, an unset RLS policy sitting next to missing headers and no DMARC, is close to the single most repeated pattern across Lovable apps specifically. Lovable isn't careless, it's optimizing for "the prompt works," and a Supabase table without an RLS policy still returns exactly the data you asked for in testing. The query succeeds either way. Nothing about that failure looks like a failure until someone sends a request the app wasn't expecting.

This isn't hypothetical. In March 2025, this exact gap, missing RLS in Lovable-generated apps, was catalogued as CVE-2025-48757 (CVSS base score 8.26, High), and left more than 170 live production apps with databases any unauthenticated visitor could read, write to, or delete from, just by inspecting the app's own network requests. Nobody shipped a bug that broke anything. The gap was a security control nobody had reason to think about, sitting quietly under apps that worked perfectly for months.

The broader research backs this up. Veracode's GenAI Code Security testing has run over 100 models across 80 coding tasks over four years, and the average pass rate on a security review has held at roughly 56%, meaning close to 44% of AI-generated code fails a review outright. A 2023 Stanford study (Perry et al., ACM CCS) found the same pattern at the human level: developers using an AI coding assistant wrote measurably less secure code than developers working without one, and felt more confident about it, not less. The role that used to catch an unset RLS policy, a senior engineer flagging it in code review, mostly doesn't exist in a Lovable workflow, because there's often no review step between describing the app and the app going live.

How to actually fix this

A severity label is only useful if it turns into something you actually do. Here's how FlawPilot handles that on this exact report.

Every finding gets grouped by area and dropped into a ranked "What to do next" list, not a raw dump of jargon. Item one was the RLS finding, and next to it, in plain English: enable Row-Level Security on this table and add a policy scoping rows to the authenticated user.

Four of the five High findings here (CSP, HSTS, clickjacking, DMARC) are pure configuration, no application logic involved. The RLS fix is a Supabase policy, not a rewrite. Clear those five and close out the CAA and DKIM gaps next to them, and a security score that opened at 55 is realistically headed for the 90s.

Try it on your own app

No setup, no coding, no passwords required. Drop in a URL, and in about two minutes you get a full scorecard: security, performance, infrastructure, and SEO, each out of 100, every finding in plain English, with a toggle between a plain-language view and the full technical one.

Scan your Lovable app for free →


FAQ

Is Lovable secure by default?
Not fully. Lovable handles HTTPS and gets you a working auth flow fast, but Row-Level Security on your Supabase tables is opt-in, and HTTP security headers, DMARC, and DNS hardening aren't configured automatically either.

What's the single most common Lovable security issue?
A Supabase table with no Row-Level Security policy, also the most severe, since it can leave underlying data readable or writable by anyone.

Does scanning my site give FlawPilot access to my Supabase project?
No. The scan only checks publicly accessible signals, the same things any browser or bot on the internet can already see. It never touches your Supabase dashboard, your database directly, or your credentials.

Can I fix this myself without hiring anyone?
Header, DNS, and email-authentication fixes usually live in your hosting or DNS provider's dashboard. The RLS fix lives in your Supabase project's SQL editor or policy UI and takes minutes once you know which table needs it.

How often should I actually check this?
Before anything you'd call a real release, and again any time you add a new table, since a new table means RLS is opt-in again.


The app worked the whole time. The database behind it never once did. That gap is the part worth remembering long after the specific header names and CVE numbers fade: "it works" and "it's secure" get checked by two different questions, and only one of them shows up on screen.

Top comments (0)