Blog/Research
ResearchSecurityVibe Coding

We Scanned 50 AI-Built Apps.
Here's What We Found.

A security analysis of 50 production apps built with Lovable, Bolt, Cursor, Replit, and v0. 89% had at least one critical or high-severity issue. Three had full database access exposed to the internet.

VibeScan ResearchMay 20, 20258 min read
50
Apps scanned
89%
Had ≥1 critical issue
94%
Missing CSP header
3
Full DB access exposed

Methodology

All 50 apps were publicly accessible, actively running in production, and built with at least one AI coding tool (Lovable, Bolt, Cursor, Replit, or v0). We identified them by searching for telltale patterns in JavaScript bundles and deployment headers — the same signals attackers use to fingerprint targets.

Scans were conducted between April and May 2025 using VibeScan's production scanning engine. We made no attempts to authenticate, exploit vulnerabilities, or access any data. Where the RLS check returned data, we stopped immediately after confirming the response structure. The three founders with service role key exposure were notified before publication.

Findings: prevalence by issue type

Percentage of the 50 apps affected by each issue

Supabase key in JS bundle
82%
Missing Content-Security-Policy
94%
Missing HSTS header
88%
Wildcard CORS on API routes
76%
Missing X-Frame-Options
78%
RLS signals absent
67%
Open admin route
14%
Service role key exposed
6%

The Supabase problem

82% of apps had a Supabase anon key visible in their JavaScript bundle. This is by design — the anon key is meant to be public, as long as Row Level Security is configured correctly. The problem is that 67% of the apps with an exposed key showed no RLS enforcement signals.

In practice: 34 apps were potentially vulnerable to unauthenticated database queries. A single SELECT * FROM users with the anon key would return all user records.

The worst case

3 apps had their Supabase service role key (not the anon key) in the JavaScript bundle. The service role key bypasses RLS entirely. Anyone who found it had unrestricted read, write, and delete access to the entire database — user data, payments, and everything else.

Critical issues by AI coding tool

Average number of critical-severity issues per app, by tool used

Lovable
2.3 avg
Bolt
2.1 avg
Replit
1.9 avg
v0
1.2 avg
Cursor
0.8 avg

n = 50 apps. Lovable n=18, Bolt n=14, Replit n=9, v0 n=6, Cursor n=3.

Why Cursor apps fared better

Cursor apps averaged 0.8 critical issues vs Lovable's 2.3. The explanation is user profile rather than tool capability: Cursor users tend to be software developers who understand security concepts. Lovable and Bolt users skew toward non-technical founders who rely on the AI to handle everything — including security, which it currently doesn't do well.

Why headers matter more than founders realise

94% of apps had no Content-Security-Policy. CSP is the primary browser defence against cross-site scripting (XSS) — the most common vulnerability class in web applications. Without it, a single XSS injection in any part of your app (an AI-generated input handler, a third-party widget, a comment field) lets an attacker load arbitrary JavaScript, exfiltrate session tokens, and hijack accounts.

None of the AI tools add these headers by default. They're invisible features — nobody knows they're missing until something goes wrong.

Security trends in vibe-coded apps

The RLS gap is the biggest structural risk

Unlike header issues (which are a configuration tweak), missing RLS is a database architecture problem. It's not fixable with a one-line change to next.config.js. Founders need to understand what RLS is and actively implement it.

AI tools don't add security by default

We tested prompting Lovable, Bolt, and Cursor to "build a secure login system." None enabled RLS, none added security headers, none configured a restrictive CORS policy. They did what was asked. Security requires explicit instruction.

Time since launch correlates with more issues

Apps launched more recently (< 30 days) averaged 2.4 critical issues. Apps that had been running for 3+ months averaged 1.1. The pattern suggests either that founders fix issues over time, or that newer apps represent a more naive cohort.

Hosting platform doesn't correlate with security posture

Vercel, Netlify, and Lovable's native hosting showed similar issue rates. The platform isn't the problem — the generated code is.

What to do right now

  1. Enable RLS on every Supabase table. This is the highest-impact action. Go to Table Editor in your Supabase dashboard, enable RLS, and add per-user policies. Use our RLS fix guide →
  2. Add security headers. A 10-line change to next.config.js fixes X-Frame-Options, HSTS, X-Content-Type-Options, and Referrer-Policy. CSP requires more effort but is worth it.
  3. Fix your CORS policy. Replace Access-Control-Allow-Origin: * with your actual domain. Use our CORS fix guide →
  4. Confirm no service role key is in frontend code. Search your codebase for SUPABASE_SERVICE_ROLE_KEY in any NEXT_PUBLIC_* variable.

Methodology note: Responsible disclosure was provided to the 3 founders with exposed service role keys before this post was published. No data was accessed or stored from any scanned application. All findings reflect publicly observable information only.

Is your app in the 89%?

Scan your Lovable, Bolt, Cursor, or Replit app in under 60 seconds. Free, no account required.

Scan my app free →See a sample report