Lovable's 'vibe-coded' apps leaked 200K messages and passport scans

5 min read 1 source clear_take
├── "This is an AI-code-generation failure, not a Lovable-specific bug — LLMs produce apps that functionally work while silently omitting security invariants"
│  └── top10.dev editorial (top10.dev) → read below

The editorial argues that framing this as a Lovable bug misses the real story. The core failure mode is that an LLM building 'an app where users can message each other' produces code where the demo works perfectly but the invariant keeping data private is silently omitted — a systemic risk for any vibe-coded production stack.

├── "The leaks are a predictable consequence of Supabase's anon-key + RLS architecture meeting inexperienced builders"
│  └── Crissy Field researchers (crissyfield.de) → read

The researchers demonstrate that Supabase's design — exposing Postgres tables via PostgREST with an anon key embedded in the frontend — places the entire security burden on correctly-written Row Level Security policies. They found RLS disabled or set to permissive patterns like USING (true) across dozens of apps, showing the default architecture is unforgiving when operators don't understand it.

└── "The exposure is severe and ongoing — this is a live data breach affecting real users, not a theoretical risk"
  └── @armcat (Hacker News, 147 pts) → view

By surfacing the Crissy Field audit on HN, armcat emphasizes the concrete scope: 200K+ private messages, passport scans, résumés, and Stripe metadata all queryable with curl. The researchers reported the issues but many apps remained exposed at publication, making this an active leak rather than a disclosed-and-patched incident.

What happened

Researchers at Crissy Field published an audit of apps built with Lovable, the AI app-builder that turns prompts into shipped React + Supabase stacks. Their finding is ugly: dozens of production Lovable apps are leaking private data — more than 200,000 private user messages, scans of passports and national IDs, résumés, internal chat logs, and in some cases payment metadata — all queryable by anyone with a browser and `curl`.

The mechanism is depressingly simple. Lovable scaffolds a Supabase backend for every project. Supabase exposes Postgres over PostgREST, which means every table is reachable via an HTTP endpoint using the project's anon key. The anon key is, by design, embedded in the frontend bundle — anyone viewing source can pull it. The only thing standing between an anon-key request and `SELECT * FROM users` is Postgres Row Level Security (RLS). In the apps Crissy Field audited, RLS was either disabled on sensitive tables or written with policies permissive enough to be functionally equivalent (`USING (true)` is a recurring pattern). The researchers didn't need an exploit; they used the same JavaScript client the apps themselves ship with.

The scope is not a handful of toy projects. The post walks through specific categories: a messaging app with a `messages` table readable in full, a KYC flow where `documents` stored passport images with a public policy, a résumé service where every uploaded CV was listable, and a SaaS with Stripe metadata sitting in an unprotected `subscriptions` table. The researchers reported the issues; many apps remained exposed at publication time.

Why it matters

This is not a Lovable-specific bug, and framing it that way misses the real story. The failure mode is that an LLM tasked with "build me an app where users can message each other" produces code that functionally works — the messages send, the UI renders, the demo looks great — while silently omitting the one invariant that keeps the data private. RLS is not a feature you can verify by clicking around. It's a negative-space property: the app is correct not because of what it does, but because of what strangers *cannot* do. LLMs are bad at negative-space properties because their training signal is "did the thing I was asked to do work."

Supabase has been warning about this for years. Their docs lead with RLS. Their dashboard flashes red banners on unprotected tables. None of that reaches a user who never opens the Supabase dashboard because Lovable handled "the backend part." The abstraction that made the app easy to build is the same abstraction that hides the thing you most need to see. Compare this to the Firebase era, which went through the same cycle around 2018 — researchers scanned open Firestore instances and found millions of exposed records from apps where developers never thought about rules because the quickstart didn't force them to. The pattern is identical; only the stack name changed.

The Hacker News thread (147 points at the time of writing) is split along predictable lines. One camp blames Lovable: an AI builder marketing itself to non-developers has a duty to default-deny, run a policy audit before deploy, and refuse to publish projects with public-write tables containing fields named `password_hash` or `ssn`. The other camp argues this is the inevitable cost of "vibe coding" — if you ship an app you don't understand, the blast radius is on you, not on the tool. Both are right, and neither matters to the 200,000 people whose DMs are now a public GET request.

There's a second-order issue that deserves naming: the researchers found that many of these apps had been live for months. The exposure wasn't a brief window between "deploy" and "notice." It was the steady state. No monitoring flagged it because nothing was technically broken — the error logs were clean, the uptime was 100%, the users were happy. The only signal that something was wrong was that the data was visible to people who weren't supposed to see it, which is not a signal any dashboard surfaces.

What this means for your stack

If you're using Lovable, Bolt, v0, Replit Agent, or any of the prompt-to-app builders, the audit checklist is short but non-negotiable. Open the Supabase (or equivalent) dashboard directly, list every table, and for each one answer two questions: is RLS enabled, and does the policy actually restrict access to the row's owner? A policy of `USING (auth.uid() = user_id)` is the floor, not the ceiling. Tables without a `user_id` column — think shared resources, admin tables, anything with `is_public` — need explicit allowlists, not permissive defaults.

The second-order practice is to treat the LLM output as a junior contractor's PR, not a finished product. Read the generated SQL migrations before they run. Grep the project for `policy` and count the hits against the number of tables; if you have ten tables and two policies, you have eight problems. Where possible, pin the AI builder to a template that starts from "deny all" and adds explicit grants, rather than the reverse. Supabase ships such a template; Lovable does not default to it.

For teams shipping LLM-assisted code at scale, this incident is an argument for a specific CI check: a schema linter that fails the build on any table lacking an RLS policy, or any policy using `USING (true)` on a table with columns matching a sensitive-data regex (`email`, `phone`, `*_hash`, `passport*`, `ssn`, `dob`). It's twenty lines of SQL introspection and it would have caught every incident in the Crissy Field report. The security tooling industry has spent a decade building SAST for application code; the equivalent for generated-infra is a greenfield problem that will matter more every quarter.

Looking ahead

Expect two things to follow. First, a wave of copycat audits — the technique is public, the targets are enumerable (Lovable project URLs are guessable), and the findings are embarrassing enough to be newsworthy. Bolt and Replit Agent apps are almost certainly next. Second, pressure on the builders themselves to ship a "security gate" before deploy: a pre-flight that enumerates tables, checks policies, and refuses to publish on obvious failures. That's a reasonable product response, but it only moves the line — it doesn't eliminate the underlying issue, which is that letting an LLM handle a negative-space property without human review is a category of risk the industry has not yet priced in correctly.

Hacker News 715 pts 292 comments

Lovable apps expose passport details and more than 200K private messages

→ read on Hacker News
neathack · Hacker News

Hi, I’m the author of this blog post. I submitted it to HN two weeks ago, but it didn’t gain much traction, so I’m glad to see it resubmitted. Happy to answer any questions, though I think the situation is fairly self-explanatory.

igorandri · Hacker News

Igor here, Head of Security at Lovable. Thanks to the Crissy Field team for their work. The root cause in these apps was insufficent Row-Level Security, which is exactly what our scanning is built to catch. We scan every app automatically before publish and offer a deeper SAST scan, both free for al

SOLAR_FIELDS · Hacker News

The part people are ignoring is Supabase's culpability in this matter: https://github.com/orgs/supabase/discussions/4547This was supposedly fixed on October 30, but there are reports floating around that for existing projects, the defaults still apply.Lovable deser

ArchEagle · Hacker News

And that is why you should not use ai and use devs instead

Oras · Hacker News

One might argue that data breaches been there way before AI, the difference with these AI generated apps is:- They are an easy target, they don’t need any sophisticated hacking knowledge (article mentions inspecting network calls in browsers).- There tons of those, and more created everyday. For the

// share this

// get daily digest

Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.