Lovable's security scan vs an outside check: what each one sees
Lovable's built-in scans look at your project from the inside: the Quick scan checks database rules, npm dependencies and exposed MCP servers on every publish, and the Deep scan reviews your code on demand. An outside check looks at what your published app hands to any stranger: the live JavaScript bundle, source maps, stray files, security headers, public storage links and whether live routes ask for a login. They answer different questions, so the safest launch uses both.
The short version
- Lovable's scans look from the inside. They read your project: database access rules, npm dependencies and, in the Deep scan, your application code.
- An outside check looks from the street. It reads only what your published app hands to anyone who visits: the JavaScript bundle, files on the server, response headers, public file links and how live routes behave for a logged-out visitor.
- They catch different things, so use both. The inside view can see logic bugs a stranger can't. The outside view sees what actually shipped, including things that never show up in your source code.
What Lovable's scan covers (from Lovable's own docs)
This section follows Lovable's security overview as it read on 19 October 2026. Lovable changes quickly, so check the docs for the current list.
Quick scan. Runs automatically every time you publish and finishes in seconds. It covers:
- Database review: tables without row-level security (RLS), access rules that let everyone through, file storage rules, and leaked-password protection turned off.
- Dependency audit: known vulnerabilities in your npm packages. Only vulnerabilities rated critical become findings.
- MCP server check: an MCP server your app exposes without sign-in.
Deep scan. Runs on demand (it doesn't run automatically as you work) and reviews all your application code. On top of the quick checks, it looks for users who can see or change data that isn't theirs, endpoints anyone can trigger, unsafe input reaching queries or prompts, secrets in your source code or repository, payment logic a customer can bypass, weak sign-in and recovery flows, and error messages that reveal too much.
Extras. Workspaces can connect Wiz for extra code and dependency scanning, or Aikido for an AI penetration test that actively tests the running app using your repository and a test login (Lovable's Aikido docs). There's also an optional Trust center, off by default, where Lovable publishes facts it observes on your live app, such as the HTTPS redirect and security headers. It only lists checks that pass.
Two things worth knowing: Lovable says running the Quick and Deep scans is free, and that these tools "do not replace a thorough security review". That's a fair, honest description, and it's why an outside look is a useful second step rather than a replacement.
What an outside check sees
An outside check uses only what a stranger with a browser gets. No code, no login, no account on your platform. It can see:
- The live JavaScript bundle. The code your app actually ships, including any value baked in at build time. If a secret key is in there, anyone can copy it.
- Source maps.
.mapfiles that turn the minified bundle back into readable source, comments and file names included. - Exposed files. Things like
/.env,/.git/configor a backup zip left in the published folder. - Security headers. Whether the server sends HTTPS-only (HSTS), a Content-Security-Policy, clickjacking protection and the rest.
- Public storage. Whether file links (avatars, invoices, uploads) open for anyone who has the URL, and whether a bucket lets people list every file.
- Auth on live routes. Whether
/admin, dashboards and API routes actually ask for a login, or only hide the button. - Your tables, as a stranger. Whether your database answers a logged-out request that uses the public key already in your page.
What it can't see: your code, logic inside logged-in areas, or anything that needs an account. That's where the Deep scan and a pentest are stronger.
Side by side
| Question | Lovable Quick scan | Lovable Deep scan | Outside check |
|---|---|---|---|
| Are RLS and database rules set? | Yes | Yes | Sees the result: does a table answer a logged-out visitor? |
| Known-vulnerable npm packages? | Yes (critical only) | Yes | No |
| Logic bugs: can users reach data that isn't theirs? | No | Yes, from the code | Only what shows from logged-out pages and routes |
| Secrets in source code or repo? | No | Yes | Only secrets that reached the live HTML or JavaScript |
| What's in the shipped JS bundle? | Not listed | Reads the source it's built from | Yes, the actual shipped file |
| Source maps and stray files on the server? | Not listed | Not listed | Yes |
| Security headers (HSTS, CSP, framing)? | Not listed (the opt-in Trust center reports passing ones) | Not listed | Yes |
| Public storage links and bucket listing? | Storage rules | Storage rules | Whether the links really open for anyone |
| Do live routes ask for a login? | Only unauthenticated MCP servers | Yes, from the code | Yes, by opening them logged out |
"Not listed" means the item isn't in the scan's coverage list in Lovable's docs on 19 October 2026. It doesn't mean Lovable never catches it.
Why the two views disagree
The code and the live app aren't always the same thing. A setting changed in a dashboard, a file uploaded by hand, an old build still being served or a host with its own config can all make the live app differ from what a code scan reads. Code-level findings need the live view too. A vendor study by VibeRaven read the Supabase migration files of 512 public Lovable repos on GitHub in October 2026 and reported that 16.2% had a policy letting signed-out visitors update or delete every row of a table. VibeRaven notes it read code, not live databases, so it can't say which of those tables are open right now (VibeRaven, vendor research). The inside view tells you what the code says; the outside view tells you what a stranger actually gets.
Five outside checks you can do yourself
Do these on your own app only, in a private browser window so you're logged out. All of them just read what the site already sends.
1. Search the live JavaScript for secret keys
Open your app, then DevTools (F12) → Sources (Chrome) or Debugger (Firefox). Search across all files (Ctrl+Shift+F, or Cmd+Option+F on a Mac) for sk_live, sk-, service_role, sb_secret_ and secret. The Supabase URL and publishable or anon key are meant to be public; a secret key isn't. More detail in our API keys in the frontend guide.
2. Look for source maps
In DevTools → Network, reload and click your main .js file. Scroll to the very end: a line like //# sourceMappingURL=index-abc123.js.map means a map is advertised. Also try opening the same file URL with .map added. If it downloads readable source code, your original code is public. Vite's default is no production source maps (Vite docs), so a map usually means someone turned them on.
3. Try a few files that should never be public
Open /.env, /.git/config and /backup.zip on your live domain. Many app hosts return your normal home page for unknown paths, which is fine. Worry only if you see file contents, such as KEY=value lines or [core].
4. Check your security headers
Run our free instant header check on your homepage, or run curl -I https://your-app.com and look for strict-transport-security, content-security-policy, x-frame-options (or frame-ancestors in the CSP) and x-content-type-options. Missing headers rarely leak data on their own, but they're quick wins.
If you host on Netlify or Vercel, our security headers guide has copy-paste configs.
5. Open your private pages, API routes and file links while logged out
Logged in, in a normal window, note the URLs of your admin page, dashboard, one API call from the Network tab, and one private file (an uploaded invoice or avatar). Now paste each one into the private window. A login screen or an error is good. Seeing the page, the JSON data or the file means the login only hides the button. For your database tables, our Supabase anon key guide shows the logged-out test.
A simple routine that uses both
- Before you publish, let the Quick scan run and fix its critical findings.
- Before a real launch, or after big changes to sign-in, data or payments, run the Deep scan from the Security view.
- After publishing, do the five outside checks above on the live URL.
- If you handle sensitive data or payments, consider a pentest or a human review as well.
Our free pre-launch checklist puts these into 14 checks with a prompt for each.
FAQ
Is Lovable's security scan enough before launch?
It's a strong first step, and Lovable itself says its scans don't replace a thorough security review. Run the Quick and Deep scans and fix what they find. Then look at the live app from the outside: what's in the JavaScript bundle, whether source maps or files are reachable, which security headers are set, and whether your pages and API routes ask for a login when you open them logged out.
Does Lovable check security headers?
Headers aren't in the Quick or Deep scan lists in Lovable's security docs. The optional Trust center, which is off by default, reports HTTPS, HSTS and browser-protection headers it observes on your live app, but it only lists checks that pass. You can check headers yourself with any header checker or with curl -I.
Is the Supabase key in my Lovable bundle a leak?
Usually not. Lovable's docs say VITE_ values such as VITE_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY are built into the browser bundle and are meant to be public. What matters is that every table has row-level security with the right policies. A service_role or sb_secret_ key in the bundle is a real leak: rotate it.
What does an Aikido pentest add on top of Lovable's scans?
According to Lovable's docs, an Aikido pentest is dynamic: AI agents interact with your running app, send real payloads and test sign-in and access flows, using your repository and a test login you provide. Lovable recommends running its own scans first, fixing those, then validating with a pentest. It's billed by Aikido.
Can I run these outside checks on someone else's app?
Only on apps you own or have permission to test. Everything in this guide is read-only: opening pages, reading what your browser already downloaded and looking at response headers. Don't try passwords, change data or test someone else's site.
Sources
- Lovable docs: Security overview (Quick scan, Deep scan, Wiz, Aikido, costs)
- Lovable docs: Trust center (checks Lovable observes on the live app)
- Lovable docs: Secrets vs VITE_ environment variables
- Lovable docs: Run AI-powered penetration tests with Aikido
- VibeRaven (vendor research, Oct 2026): We read the Supabase migrations of 512 public Lovable apps
- Vite docs: build.sourcemap (default false)
- Supabase docs: Storage buckets (public vs private)
This guide is general information, not a security audit. Lovable's descriptions are summarised from its public docs as of 19 October 2026; platforms change, so check the linked docs for current details. Spotted something out of date? Email hello@milokits.com.
More guides
- Supabase Security Advisor warnings explained: what to fix first
- Lovable, Bolt, Replit and v0 app security checklist before launch
- Is my API key exposed in my JavaScript? VITE_ and NEXT_PUBLIC_ explained
- Security headers for vibe-coded apps: copy-paste Netlify and Vercel configs
- Firebase security rules mistakes in AI-built apps (and how to fix them)