Contact Book a call

Security

Your Lovable app is probably public

Over 170 Lovable-built apps had open databases in one disclosure. Most vibe-coded apps ship with row-level security off. How the leak works, the three named breaches of 2026, and the twenty-minute check to run before you tell anyone your app exists.

Cover card reading "Your Lovable app is probably public" beside a database panel with a row-level security toggle switched off
The anon key is in the browser. Without row-level security it is a master key. Image: SBD.

A founder sent us a Lovable app in September. Two hundred paying users, a waitlist, a launch post ready. We asked for the Supabase project and ran one query from a browser console, logged out, using the key that ships in the page source.

It returned every user’s email, plan, and the notes they had written about their clients.

He had not done anything wrong. He had built what the tool built, and the tool had not switched on the one setting that makes a Supabase database private.

The short answer

Supabase apps put a public "anon" key in the browser by design. That key is safe only if row-level security (RLS) is on for every table and a policy says who may read what. Code generators often create tables without it. The fix takes twenty minutes per table: enable RLS, write a policy, test it logged out. Do that before launch, not after the first screenshot on X.

Per table, before launch: CVE-2025-48757: over 170 Lovable apps with open databases
Per table, before launch. CVE-2025-48757: over 170 Lovable apps with open databases.

How the leak works

Supabase gives every project two keys. The service key stays on the server and can do anything. The anon key goes in the browser so the app can talk to the database directly. That is a good design, because the database itself enforces who can see which rows, through row-level security.

If RLS is off on a table, the anon key can read and write all of it. Not just the logged-in user’s rows. All of it. And RLS is off by default on tables created through SQL, which is how most generated apps create them.

In January 2026, researchers at Hacktron disclosed CVE-2025-48757: over 170 applications built with Lovable had databases open this way. One of them exposed about 13,000 users through a publicly readable password reset token table. Lovable’s own Supabase documentation now says missing RLS is the most common way app data gets exposed.

The three breaches people cite

  • Moltbook, a social platform built entirely by vibe coding. Wiz Research found its Supabase project wide open on 31 January 2026: the publishable key was reachable from client code, and the exposed data included emails and private messages.
  • Quittr, a habit app, had every user record publicly readable in March 2026.
  • Baudr had an admin panel at /admin that anyone could open.

An audit of fifty apps built with Lovable, v0, Bolt and Cursor on DEV Community found most of the Lovable ones with RLS completely off. A separate scan in August reported that more than half of the Supabase databases it could reach returned their data to anyone who asked.

The pattern is not that the tools are bad. It is that they get you to a working screen fast, and a working screen looks finished.

The twenty-minute check

Do this on every table before launch.

  1. In the Supabase dashboard, open the table and check that RLS is enabled. If the toggle is off, turn it on. The app will immediately stop reading that table until step 2.
  2. Write a policy. For most tables it is one line: users may select rows where the user_id column equals their own auth.uid(). Write a matching one for insert and update. Do not write one for delete unless you mean it.
  3. Test it logged out. Open the app in a private window, open the console, and query the table with the anon key. You should get an empty list. If you get rows, the policy is wrong.
  4. Repeat for every table, including the ones the generator created that you forgot about: profiles, tokens, logs, uploads.
  5. Rotate the service key if it has ever been in the front-end code or a public repo. Search the repo for it.

There is a command-line tool called SupaShield that tests policies against each role before deployment. It is worth the hour it takes to set up.

Before and after

BeforeAfter
Anon key in browserReads every rowReads only the user’s rows
New table from the generatorRLS off, open to allRLS on, policy written, tested
Service keyIn the front-end bundleServer only, rotated
Who finds the gapA researcher, or a competitorYou, in a private window, before launch

What we check in an MVP audit

Row-level security is the first of roughly forty checks in our MVP audit, because it is the most common failure and the cheapest to fix. The rest cover authentication flows, secrets in the bundle, storage bucket policies, rate limits, backups, and whether the app can be run by someone who is not the founder. It is $500, takes a week, and ends with a list in order of risk.

If you would rather do it yourself, start with the twenty minutes above. It is the difference between a launch and a disclosure.

Questions we get asked

Lovable says it enables RLS now. Am I fine?

Newer projects may have it on for new tables. Check every table anyway, including older ones and ones created by SQL in a chat. The test in a logged-out window takes a minute and does not care what the tool says.

Can I just use the service key everywhere and skip RLS?

Only if the key never reaches a browser, which means every database call goes through your own server. Most vibe-coded apps call Supabase from the page. For those, RLS is the whole security model.

Is this specific to Supabase?

The pattern is specific to any database you query from the client: Firebase has the same class of problem with its rules. Supabase is the one most generators use, so it is where the breaches are.

Sources and further reading

  • Vibe coding
  • Supabase
  • Security
  • MVP audit

Keep reading

Cover card reading "How much should an AI agent be allowed to do?" beside a permissions panel with read, write, spend and escalate rows

Systems

How much should an AI agent be allowed to do?

An agent with an unscoped token dropped a production database and its backups in nine seconds. The permission model we use for every agent: read widely, write narrowly, spend with a cap, and escalate when unsure.

Cover card reading "Does an AI agent still need Zapier?" beside two columns: judgement and plumbing

Strategy

Does an AI agent still need Zapier?

A widely shared post argues Zapier goes to zero because agents click buttons and call APIs themselves. We run both every day. Where the argument is right, where it is wrong, and what we use for each job.

Cover card reading "Invoice intake with an agent: the first thirty days" beside a four-week timeline from shadow mode to steady state

Systems

Invoice intake with an agent: the first thirty days

What the first month of an invoice intake agent looks like from the inside: how the queue behaves, which invoices escalate, what the finance team changes, and the three settings that decide whether it survives month two.

For teams that tried AI and nothing stuck

Get the hours back.

About 95% of AI pilots never reach the profit line. Ours start with the work your team still does by hand, and end when it is gone.

See how we work
A team of six gathered around one screen in an open-plan office
Thirty minutes with the people who own the process. Photo: Vitaly Gariev, Unsplash.