Is my Lovable app secure? A 15-minute self-check before you share the link
What Lovable's built-in security scan covers, the gaps it leaves for you to check, and a step-by-step test you can run yourself, with prompts to paste back into Lovable.
You built an app in Lovable, it works, and you are about to post the link. Then the question hits: is it actually safe? Can a stranger see my users' emails? Did the AI put a secret key somewhere it shouldn't?
Short answer: Lovable gives you a good head start, but "the security scan is green" and "my users' data is safe" are not the same thing. This post explains what Lovable already checks, where the gaps are, and how to test the gaps yourself in about 15 minutes. You don't need to read code.
What Lovable already checks for you
Lovable has a built-in Security view with two scans:
- Quick scan. Runs automatically when you publish. It reviews your database access rules (for example, tables without row-level security, or rules that let everyone through), checks your npm packages against known vulnerabilities, and flags an MCP server your app exposes without a login.
- Deep scan. You start it yourself. It reads your app's code for authorization bypasses, injection, leaked secrets, sensitive data exposure, login flaws and payment logic.
Use both. Open the Security view, run the Deep scan, and fix everything marked critical before you share the link. It is free and it catches a lot.
Why a green scan isn't the whole answer
Lovable's scans look at your project from the inside. Three kinds of problem are easy to miss from there:
- Rules that are switched on but wrong. A table can have row-level security enabled and still let one signed-in user read another user's rows. Spotting that means understanding what each table is for, which a scanner can only guess.
- What actually got published. Your live site is what attackers see. Keys, files and settings that ended up in the published version are the real test.
- Changes after the scan. Every new prompt can add a table, a function or a key. The scan you ran last week says nothing about the version you published today.
That is not a knock on Lovable. Researchers have been finding open databases in AI-built apps since 2025, and in September 2026 UpGuard counted 16,326 Supabase databases that anyone could read. Most of the apps in that study were not built with Lovable, but the mistakes are the same everywhere. A second, outside check costs you 15 minutes.
The 15-minute self-check
You need your published app, a second browser (or a private window), and access to your database, either the Cloud tab in Lovable or your Supabase dashboard if you connected your own project.
1. Make two test accounts (2 minutes)
Sign up twice with two different emails: call them Alice and Bob. As Alice, create some data: a profile, a task, an order, a message, whatever your app stores. Most of the checks below compare what Bob can see with what he should see.
2. The neighbour test (3 minutes)
Sign in as Bob in the private window. Then try to reach Alice's data:
- Open any page that shows one item, such as
/tasks/123or/orders/abc. Swap in the ID of one of Alice's items (you can see it in the address bar in Alice's window). - Open the browser's developer tools (F12), go to the Network tab, and reload. Click requests to
supabase.coand look at the Response. Do you see anything that belongs to Alice?
If Bob can see any of Alice's rows, your row-level security policies are too wide, even if every table shows RLS as enabled. The usual cause is a policy that says "any signed-in user may read", which means anyone who signs up can read everything.
Paste into Lovable: "Review the RLS policies on every table that stores user data. Each user must only be able to read, update and delete rows where user_id equals auth.uid(). Remove any policy that lets all authenticated users read all rows, and add a WITH CHECK clause to every update policy. List every policy before and after."
3. The stranger test (3 minutes)
Sign out completely, or use a fresh private window, and open your app. In the Network tab, look again at the requests going to supabase.co. Signed-out visitors should only get public content: your landing page text, public listings, nothing personal.
To go one step further, ask Lovable to show you how a signed-out visitor sees each table. A good prompt:
"For each table in the database, tell me whether a signed-out visitor using the public anon key can read, insert, update or delete rows, based on the current grants and RLS policies. Show it as a table."
If any table with emails, names, phone numbers, orders or messages says "read: yes" for signed-out visitors, fix it before launch.
4. The "make me admin" test (2 minutes)
This one is common in AI-built apps and rarely caught. Many apps store a role or is_admin field on the user's own profile, and also have a rule that says "users can update their own profile". Put those together and every user can make themselves an admin.
Ask Lovable:
"Where is the user's role or admin status stored? Can a user change it themselves through any RLS policy, the profile settings page, or by editing their user metadata? If yes, move roles into a separate user_roles table that only the server or a security definer function can write, and check admin status with a server-side function."
Also check that admin pages don't rely only on hiding a button. Being able to open /admin while signed in as Bob is a red flag, even if the page shows nothing. The data behind it must be protected by the database rules, not by the page.
5. The secret key test (2 minutes)
Anything in your frontend code is downloaded by every visitor. Open your live site, open developer tools, go to the Sources tab (Chrome) or Debugger (Firefox), and use the search across all files (Ctrl+Shift+F, or Cmd+Option+F on Mac). Search for:
sk-andsk-proj-(OpenAI and other AI providers)sk_live(Stripe secret key)service_roleandsb_secret_(Supabase keys that skip all database rules)PRIVATE KEY
Finding your Supabase URL and the anon or publishable key is normal; those are meant to be public. Finding any of the above is not. Rotate the key at the provider first, then:
Paste into Lovable: "Move every call that uses a secret API key into a Supabase Edge Function that reads the key from secrets. The frontend must call the Edge Function instead. Remove the key from all frontend code and confirm no secret remains in the built JavaScript."
6. The paid-feature test (2 minutes)
If your app calls OpenAI or another paid API through an Edge Function, that function is a public web address. Check two things:
- Does it require a real signed-in user? The platform's built-in JWT check is not enough on its own: on many projects the public anon key is itself a valid token, so "JWT verified" can still mean "anyone". The function should look up the user from the request and reject the call if there isn't one.
- Is there a limit? Without a per-user limit, one script can call your function thousands of times and send you the bill.
Paste into Lovable: "In every Edge Function, get the signed-in user with supabase.auth.getUser() using the caller's Authorization header and return 401 if there is none. Use the user id from the token, never from the request body. Add a per-user daily limit to every function that calls a paid API."
If you take payments with Stripe, also ask Lovable to confirm that the webhook function verifies Stripe's signature, and that "paid" status is only ever set by that webhook, never by the browser.
7. The leftover files test (1 minute)
Visit these on your live domain:
https://your-app.com/.envhttps://your-app.com/.git/config
Both should show your app's normal "not found" page or an error. If either shows text with keys or settings, rotate every key in it and remove the file from what you publish.
What to do with the results
- Everything passed: good. Re-run the neighbour and secret key tests every time you add a feature that stores new kinds of data.
- Something failed: fix it with the prompts above, publish, and test again. An AI saying "done" is not the same as the test passing.
- You're not sure what you're looking at: that is normal. Network responses and RLS policies are not written for humans. That's what an outside scanner is for.
Let a scanner run the outside tests for you
Greenlight Scan checks your published Lovable app the way a stranger would, from the outside, without changing anything. The free scan takes about 2 minutes: it looks for secret keys in your JavaScript, exposed .env and .git files, your Supabase setup and missing security headers, and shows you a score, how many problems it found and the title of the most serious one.
After you prove you own the app (a meta tag or DNS record), the deep scan uses your public key to count how many rows of each table a stranger can see, without downloading any of them, and tries your API routes while signed out. The $19 Full Scan unlocks every finding with the evidence, where it is, why it matters and a fix prompt written for Lovable, plus 30 days of re-scans and a PDF. One payment, no subscription. See a sample report first if you like.
What an outside scan can't do is log in as Alice and Bob, so the neighbour test above stays your job. Five minutes of it before launch is worth it.
For a shorter version of this list, see our Lovable security guide. For the database side in depth, read how to check if your Supabase database is exposed.
Check your own app in about 2 minutes.
Scan my app freeThe Friday leak report
One short email a week: the newest ways AI-built apps leak data, and the one-line fix for each. No spam, unsubscribe any time.