What every founder needs to know in 60 seconds
Vibe-coded apps are shipping with critical vulnerabilities at scale. Of the 127 apps we scanned between March and June 2026, 71% — 90 applications — had at least one P0 finding: a vulnerability severe enough to cause a full data breach, account takeover, or regulatory incident. The average app carried 2.3 critical findings and 4.7 high-severity findings. These are not theoretical risks; they are exploitable in minutes by automated scanners.
The gap is structural, not incidental. AI coding tools are optimized to produce working software fast. They are not optimized for security posture. The three most common vulnerability classes — missing rate limiting on auth endpoints (68% of apps), Supabase Row Level Security disabled (47%), and missing HTTP security headers (84%) — are not edge cases. They are the default output of every major vibe coding platform in our dataset. The tools do not fail occasionally. They omit security systematically.
Only 12% of apps are genuinely launch-ready. A score of 80/100 or above — our threshold for production readiness — was reached by just 15 apps. A third of all apps (34%) scored below 50, placing them in the critical risk bracket: systems that should not be handling real user data. No platform's average score clears 65/100. The best performer, Bolt, averages 61/100 — still in the medium-risk band.
This report exists because the conversation about vibe coding has stayed at the surface: speed, product-market fit, fundraising, aesthetics. Security has been treated as a post-launch problem. Our data shows it is a pre-launch emergency for the majority of teams shipping AI-generated software today.
How we collected and validated this data
Based on 127 URL-based scans run through launchreadycode.com between March and June 2026. All scans are non-invasive — no code access required. We analyze the deployed application's behavior, headers, authentication patterns, and API responses against the OWASP Top 10 and CWE Top 25 frameworks. Findings are scored using CVSS v3.1. No personally identifiable information is collected or retained.
Platform classification (Lovable, Bolt, Cursor, Replit, Other) is inferred from HTTP response headers, client-side JavaScript signatures, CDN fingerprints, and meta-tag patterns. Classification confidence threshold is 0.85 — apps below this threshold are placed in the "Other" category. Each scan covers all four dimensions: Security, Reliability, Performance, and Monitoring. This report focuses exclusively on security findings. Performance and reliability data will be published in the Q3 2026 follow-on report.
Launch Readiness Score across 127 apps
The distribution is heavily left-skewed. The 50–59 band is the single largest cohort, containing 29% of all apps — applications that have addressed the most obvious surface-level issues but still carry multiple unresolved high-severity findings. These apps often have HTTPS enabled and basic input validation in place, which creates a false sense of security. Below the waterline, auth controls and data access policies remain broken.
The 34% of apps scoring below 50 represent the highest-urgency cohort: systems that are fundamentally unsafe for real user data at any scale. These are not edge cases — they are a third of the market we scanned. The 12% scoring above 80 all shared one common factor: manual security review at some point prior to our scan, either by a fractional CTO, a technical co-founder, or a code review process that specifically targeted the findings classes we measure.
What we found, ranked by frequency
| # | Vulnerability Class | Frequency | CVSS Avg | Severity |
|---|---|---|---|---|
| 1 | Missing HTTP Security Headers | 84% | 5.3 | P0 |
| 2 | No Rate Limiting on Auth Endpoints | 68% | 8.1 | P0 |
| 3 | Supabase RLS Disabled on ≥1 Table | 47% | 8.8 | P0 |
| 4 | CORS Misconfiguration | 31% | 7.4 | P1 |
| 5 | Exposed API Keys in Client-Side Code | 23% | 9.1 | P0 |
| 6 | Missing Error Boundary / Verbose Stack Traces | 41% | 5.8 | P1 |
| 7 | No Error Tracking Integration | 63% | — | P1 |
| 8 | Missing Database Query Parameterization | 18% | 9.3 | P0 |
| 9 | Insecure Direct Object References (IDOR) | 14% | 8.2 | P0 |
| 10 | Sensitive Data in Browser Local Storage | 29% | 6.1 | P1 |
On missing HTTP security headers (84%): This is the most structurally predictable finding in our dataset. Every platform we scanned produces deployments that omit at minimum Content-Security-Policy, X-Frame-Options, and Strict-Transport-Security. These headers are not enforced by hosting providers by default. They require explicit configuration. AI coding tools do not generate this configuration. The result is that 84% of apps in production are missing the first layer of browser-side defense against XSS, clickjacking, and protocol downgrade attacks. A CVSS base score of 5.3 understates the risk in production contexts — when combined with a JavaScript injection vector, the attack surface expands to full session hijack without any additional attacker capability required. We classify this as P0 in production because the absence of CSP in a public application is a known exploit prerequisite, not a theoretical concern.
On exposed API keys in client-side code (23%): This finding — present in 23% of scanned apps — carries the highest CVSS score in our dataset at 9.1. The typical vector is a Supabase anon key or Stripe publishable key embedded in a React or Next.js bundle, alongside a private API secret that should never have left the server environment. AI tools generate frontend and backend code in the same session, and the boundary between what belongs in NEXT_PUBLIC_ environment variables and what must stay server-side is a nuanced operational decision that models consistently get wrong. We detected keys for Supabase, Stripe, OpenAI, Twilio, and SendGrid in client-side bundles across this cohort.
On CORS misconfiguration (31%): A third of apps in our dataset allow cross-origin requests from * (wildcard) origins on API routes that return user data or accept authenticated write operations. In several cases, Access-Control-Allow-Credentials: true was combined with a wildcard origin — a configuration that modern browsers reject per spec, but which represents a broken implementation that will silently fail for legitimate users while the underlying logic remains dangerous on any browser that does not enforce the spec correctly.
Security posture by vibe coding platform
| Platform | Avg Score | Most Common Finding | Frequency |
|---|---|---|---|
| Replit | 52/100 | Exposed secrets in client bundle | 38% |
| Lovable | 54/100 | Supabase RLS disabled | 61% |
| Cursor | 59/100 | No auth rate limiting | 73% |
| Bolt | 61/100 | Missing HTTP security headers | 79% |
| Other | 63/100 | CORS misconfiguration | 27% |
Replit's exposed secrets problem (38%): Replit's development environment collapses the distinction between server and client context in ways that affect how developers think about environment variables. Secrets are frequently set in the Replit Secrets pane and then referenced directly in frontend code, because the Replit IDE does not enforce the server/client boundary that a Next.js or Remix project structure would. The result is the highest rate of client-side secret exposure in our dataset. At 52/100, Replit-deployed apps carry the lowest average score.
Lovable's Supabase RLS failure rate (61%): Lovable's tight Supabase integration — one of its core product differentiators — creates a specific failure pattern. The tool generates Supabase schema and client code that works correctly in the prototype context, but does not scaffold Row Level Security policies by default. Users who move from prototype to production without explicitly enabling RLS on each table are shipping a database that any authenticated user can query in full. Our data shows this affects 61% of Lovable apps with Supabase integrations — the highest platform-specific concentration of any single vulnerability class in this report.
Why Bolt and Cursor score higher: Neither Bolt nor Cursor generates application infrastructure — they generate code that is then deployed by the developer. This extra step creates a natural intervention point. Developers who configure their own deployment pipelines (Vercel, Railway, Render) are more likely to encounter and set security headers through platform-level configuration than developers using fully-managed deployment flows. Cursor's higher score also reflects its user base: developers who are already proficient enough to use an IDE-integrated AI assistant tend to have stronger baseline security habits than zero-code users.
The three critical findings that repeat across every platform
What it is: An authentication endpoint — typically /api/auth/login, /api/auth/signup, or a Supabase Auth direct call — that accepts an unlimited number of requests per IP address, per account, or per session window. Without rate limiting, an attacker can attempt passwords, enumerate valid email addresses, trigger email-based OTPs in bulk, or execute credential-stuffing attacks using breached password databases.
Why vibe coders miss it: AI coding tools generate functional auth flows — they produce code that correctly validates credentials and issues tokens. Rate limiting is an infrastructure layer, not a code layer. It lives in a reverse proxy configuration (nginx, Cloudflare, Vercel Edge Middleware) that the AI tool never touches. A developer who tests their login form in development will never encounter a rate-limiting failure, because the threat does not manifest until an attacker targets a production endpoint at scale. The consequence is that 68% of the apps we scanned have fully working login pages with zero brute-force protection.
The real risk: A credential-stuffing attack using a dataset of 1 million breached credentials against an unprotected endpoint can run in under 4 hours on a $5/month cloud instance. For Supabase apps without RLS (a common co-occurrence in our data), a successful account takeover gives the attacker read access to every row in the database. CVSS 8.1 is the score for the authentication bypass vector alone — the composite risk when combined with absent RLS approaches 9.8.
Fix path: Cloudflare's free tier includes rate limiting rules that can be applied to /auth/* paths in under 10 minutes. Vercel Edge Middleware can enforce IP-based limits on Next.js auth routes. Supabase's built-in email OTP has configurable send limits — these are off by default. See /api-rate-limit-checker to verify your current exposure.
What it is: Supabase's Row Level Security (RLS) is a PostgreSQL feature that restricts which rows a query can access based on the identity of the requesting user. When RLS is disabled on a table, any authenticated user with a valid Supabase anon key — which is public — can query every row in that table directly via the Supabase client, bypassing any application-level access controls entirely.
Why vibe coders miss it: Supabase ships with RLS disabled by default on new tables. The Supabase dashboard displays a yellow warning when RLS is off, but the warning is non-blocking — the application works correctly without it. AI tools that generate Supabase schema and client code produce functional applications that never surface this failure because the failure only becomes visible when a user attempts to access data that isn't theirs. In a development environment with a single test account, this scenario never arises. In production with multiple real users, every user's data is readable by every other user.
The real risk: An attacker with a valid Supabase anon key (which is typically embedded in the client bundle — see the 23% exposed secrets finding) and knowledge of a single valid table name can retrieve every row in that table with a single API call. For SaaS applications — which represent the majority of our scan cohort — this means full multi-tenant data exposure. User records, payment metadata, private messages, and uploaded files are all reachable. CVSS 8.8 reflects the direct data exposure vector. The score does not account for the reputational and regulatory exposure of a confirmed multi-tenant breach.
Fix path: Enable RLS for every table in the Supabase dashboard, then write explicit policies for each access pattern. A minimum viable RLS policy for a user-scoped table is two lines of SQL. See /supabase-rls-checker to audit your tables without code access.
What it is: HTTP response headers that instruct browsers how to handle the application's content, how to enforce HTTPS, and what external resources are trusted. The critical set includes Content-Security-Policy (CSP), Strict-Transport-Security (HSTS), X-Frame-Options, X-Content-Type-Options, and Referrer-Policy. The absence of these headers does not cause an immediate failure — the application continues to function — but it removes the browser-level defense layer that prevents a range of injection, framing, and protocol downgrade attacks.
Why vibe coders miss it: Security headers are configured at the server or CDN layer, not in application code. A Next.js developer configures them in next.config.js. A Vite app needs a hosting platform configuration. None of the AI coding tools in our scan cohort generate this configuration by default, and none of the hosting platforms in common use among vibe coders (Vercel, Netlify, Railway, Render) enforce it without explicit developer action. The result is that 84% of production apps ship without the headers that every major browser security guideline requires.
Why we classify it P0 despite a CVSS of 5.3: The base CVSS score of 5.3 reflects the standalone header absence. In practice, missing CSP is exploitable only when combined with a JavaScript injection vector — and 23% of apps in our dataset have exposed API keys in their client bundle, which is itself an injection entry point. Missing HSTS is exploitable via a protocol downgrade attack in any network environment where an attacker can intercept traffic. We classify missing security headers as P0 in production because the attack surface amplification effect is severe and the fix cost is under one hour of engineering time.
Fix path: Add the five critical response headers to your deployment configuration. On Vercel, this is a headers() block in next.config.js. On Cloudflare, it's a Transform Rule. The implementation is a copy-paste from the Mozilla Observatory recommendations. Run a free scan at launchreadycode.com to confirm current header status for your deployment.
How vibe-coded apps compare to the broader market
According to OWASP's 2023 Top 10, injection and authentication failures remain the top two vulnerability classes globally. In our dataset, these map directly to Supabase RLS failures and missing rate limiting — appearing at rates 2–3x higher than in enterprise security audits. The OWASP benchmark draws from applications built and maintained by teams with dedicated security review processes. Vibe-coded applications have no equivalent baseline.
The comparison is instructive but not complete. Enterprise applications are typically larger, have longer development cycles, and carry more legacy surface area. Vibe-coded apps are smaller and newer — factors that typically reduce vulnerability count. The fact that they still significantly exceed enterprise failure rates on the most fundamental controls (auth, access, headers) isolates the causal factor: the absence of security-aware scaffolding in the toolchain, not the scale or complexity of the application.
The 34% of apps scoring below 50/100 in our dataset would fail a basic penetration test. That category does not meaningfully exist in the enterprise audit cohort that OWASP draws from — enterprise security programs exist specifically to eliminate it before production. For vibe-coded apps, there is no equivalent gate. The gate is the founder's awareness that one is needed.
Specific actions, not general advice
The following is not a framework. It is a checklist derived directly from the failure patterns in this dataset. If any of these conditions apply to your application, you have an open vulnerability.
-
If your app uses Supabase and you haven't explicitly enabled RLS on every table, assume it's disabled. Go to your Supabase dashboard now. Table Editor → select each table → check the RLS toggle. If it's grey, your data is accessible to any authenticated user. Enable it and write a policy before your next user signs up. Use /supabase-rls-checker to audit without writing SQL.
-
If your login or signup route accepts more than 10 requests per minute from a single IP without a lockout, you have no brute-force protection. Add Cloudflare rate limiting (free tier) today. For Vercel deployments, add a rate limit middleware to your
/api/auth/routes. See /api-rate-limit-checker to verify your current limit configuration. -
If you used a Replit-hosted development environment at any point, assume your secrets may be in your client bundle. Open your browser devtools on your production URL, go to Sources, and search for strings that match your API key prefixes (e.g.,
sk-for OpenAI,SUPABASE_SERVICE_ROLE,stripe_secret). If you find any, rotate every affected key immediately — treat the previous key as compromised. -
Check your HTTP headers before your next marketing push. Run your URL through launchreadycode.com or Mozilla Observatory. If you're missing CSP, HSTS, and X-Frame-Options, add them to your hosting configuration before you drive traffic to the domain. The attack surface multiplies with user volume.
-
If you don't have error tracking wired up, you won't know when you've been breached. Sentry's free tier takes under 30 minutes to integrate and covers the monitoring gap that 63% of apps in our dataset have open. An attacker who exploits RLS disabled will query your database without triggering any application-level error. Error tracking on auth failures and API errors is the minimum viable incident detection layer.
-
Run a formal audit before your first paying enterprise customer, your first press mention, or your first security questionnaire. The reputational cost of a breach at scale — even a small one — is disproportionate to the cost of prevention. A Launch Readiness Audit at /pricing costs $499 and delivers a prioritized, CVSS-scored finding roadmap with time estimates per issue in under 2 minutes.
The hardest truth in this data: None of the vulnerabilities in this report are exotic. They do not require advanced attacker capability. They require a motivated person with a browser, a working knowledge of REST APIs, and a few hours. The barrier to exploitation is lower than at any point in the history of web security. The tools that create vibe-coded apps have made building faster — they have also made attacking those apps easier, because the same patterns that AI produces are the patterns that automated scanners are trained to find.
Frequently asked questions
SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';Any row where
rowsecurity = false is exposed without access controls — any authenticated user with your anon key can read every row. You can also run a non-invasive check using the free tool at launchreadycode.com/supabase-rls-checker, which requires only your app's URL.