What every founder needs to know in 60 seconds?
Vibe-coded apps are shipping with critical vulnerabilities at scale. The majority of apps we've audited have at least one P0 finding: a vulnerability severe enough to cause a full data breach, account takeover, or regulatory incident. Most apps carry multiple critical and 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, disabled Supabase Row Level Security, and missing HTTP security headers — are not edge cases. They are the default output of every major vibe coding platform. The tools do not fail occasionally. They omit security systematically.
Most apps require significant security work before production. A minority of apps achieve a score threshold that indicates production readiness. Many apps score in the critical risk bracket and should not be handling real user data without substantial remediation. No vibe coding platform consistently produces launch-ready code without manual security review and hardening by the development team.
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 a sample of the 700+ apps we've audited through launchreadycode.com. 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. Each scan covers all four dimensions: Security, Reliability, Performance, and Monitoring. This report focuses exclusively on security findings, which reveal consistent patterns across vibe coding platforms.
What should you know about Launch Readiness Score across 127 apps?
The distribution of Launch Readiness Scores across vibe-coded apps shows that most require significant security remediation. Many apps have addressed surface-level issues but still carry unresolved high-severity findings. These apps often have HTTPS enabled and basic input validation in place, which can create a false sense of security. Below the waterline, auth controls and data access policies frequently remain broken.
A substantial portion of apps score in critical or moderate risk bands, indicating they should not handle real user data without significant remediation. The apps with the strongest security postures tend to share one common factor: they have received manual security review by someone with security expertise — a fractional CTO, a technical co-founder, or a dedicated security review process.
What we found, ranked by frequency?
| # | Vulnerability Class | Frequency | CVSS Avg | Severity |
|---|---|---|---|---|
| 1 | Missing HTTP Security Headers | Most | 5.3 | P0 |
| 2 | No Rate Limiting on Auth Endpoints | Common | 8.1 | P0 |
| 3 | Supabase RLS Disabled on ≥1 Table | Frequent | 8.8 | P0 |
| 4 | CORS Misconfiguration | Frequent | 7.4 | P1 |
| 5 | Exposed API Keys in Client-Side Code | Common | 9.1 | P0 |
| 6 | Missing Error Boundary / Verbose Stack Traces | Frequent | 5.8 | P1 |
| 7 | No Error Tracking Integration | Common | — | P1 |
| 8 | Missing Database Query Parameterization | Occasional | 9.3 | P0 |
| 9 | Insecure Direct Object References (IDOR) | Occasional | 8.2 | P0 |
| 10 | Sensitive Data in Browser Local Storage | Frequent | 6.1 | P1 |
On missing HTTP security headers: This is the most structurally predictable finding in vibe-coded apps. Every platform we audit 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 most 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: This finding is frequently present in vibe-coded apps and carries a high CVSS score of 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 detect keys for Supabase, Stripe, OpenAI, Twilio, and SendGrid in client-side bundles regularly.
On CORS misconfiguration: A significant portion of vibe-coded apps allow cross-origin requests from * (wildcard) origins on API routes that return user data or accept authenticated write operations. In some cases, Access-Control-Allow-Credentials: true is 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.
What should you know about Security posture by vibe coding platform?
| Platform | Avg Score | Most Common Finding | Frequency |
|---|---|---|---|
| Replit | Low | Exposed secrets in client bundle | Common |
| Lovable | Low | Supabase RLS disabled | Frequent |
| Cursor | Medium | No auth rate limiting | Frequent |
| Bolt | Medium | Missing HTTP security headers | Most |
| Other | Medium | CORS misconfiguration | Frequent |
Replit's exposed secrets problem: 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 a consistently high rate of client-side secret exposure in Replit-deployed apps.
Lovable's Supabase RLS failure pattern: 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. This is a frequently recurring pattern in Lovable apps with Supabase integrations.
Why Bolt and Cursor patterns differ: 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 user base also reflects developers who are already proficient enough to use an IDE-integrated AI assistant, who tend to have stronger baseline security habits than zero-code users.
What is 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.
What should you know about 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, is engineer-verified, and delivers a prioritized, CVSS-scored finding roadmap with time estimates per issue within 48 hours.
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.
Do faster AI tools produce less secure code?
A common hypothesis is that tools that generate code faster produce less secure code — that speed-to-deploy pressure trades off against security quality. Our data does not support a simple speed-vs-security relationship. The primary predictor of finding count is not generation speed, but scaffolding defaults: specifically, whether the tool’s default output includes security-relevant configuration (headers, RLS, rate limiting) or omits it.
| Tool | Typical build time | Avg P0/P1 findings | Most common gap | Scaffolds security config? |
|---|---|---|---|---|
| Lovable | 1–3 hrs | 4.2 | Supabase RLS disabled by default | No |
| Bolt.new | 30–90 min | 3.8 | Missing HTTP security headers, no rate limiting | No |
| Cursor (vibe mode) | 2–8 hrs | 3.1 | Auth middleware absent on new routes | Partial (depends on prompt) |
| Windsurf / Codeium | 2–6 hrs | 3.0 | Rate limiting absent, missing error tracking | Partial (depends on prompt) |
| Replit | 1–4 hrs | 3.6 | Secret exposure in client bundle, open endpoints | No |
| Claude Code | 4–16 hrs | 2.4 | Missing monitoring setup, absent security headers | Partial (depends on prompt) |
| v0.dev | 30–120 min | 2.9 | Frontend-only focus; backend security absent | No (frontend only) |
The pattern: the tools that generate the most security gaps (Lovable, Bolt, Replit) are those with opinionated, fully-managed scaffolding that optimises for time-to-demo. The tools with fewer gaps per app (Claude Code, Cursor) allow more explicit security specification but require the developer to know to ask for it.
The depth-vs-speed trade-off is real, but it operates differently than expected: the risk is not in how fast the code is written — it is in whether the tool’s defaults include any security scaffolding at all. A Bolt app built in 45 minutes and a Bolt app built in 3 hours have the same missing headers, because Bolt does not generate headers at any generation speed.
The practical implication: the tool category predicts the gap type, and the gap type predicts the fix. A pre-launch scan identifies which gaps are present regardless of which tool was used.
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.