TL;DR
Vibe-coded apps fail in predictable ways: open database tables (no row-level security), secret keys in front-end code, routes that never check who is logged in, prompt injection in AI features and agents, and invented or careless dependencies.
It is not hypothetical: 170 of 1,645 scanned Lovable showcase apps had exposed databases, a scan of 5,600+ vibe-coded apps found 400+ leaked secrets, and a Replit agent deleted a production database. Turn on and test RLS, keep every secret server-side with spend caps, keep agents away from production, and run the copyable checklist below before real users arrive.
Why vibe-coded apps leak
AI models write code that works, not code that defends itself. In Veracode’s 2025 test of more than 100 models on 80 security-sensitive coding tasks, the generated code contained an OWASP Top 10 weakness in 45% of cases, and failed to defend against cross-site scripting in 86% of relevant samples (source: veracode.com). Newer models write more code that compiles; Veracode found security pass rates did not improve at the same pace.
Vibe coding adds three multipliers. Builders often cannot read the code, so nobody reviews it. Browser builders wire the front end straight to the database, so one missing policy exposes everything. And success comes fast: an app built in a week can have thousands of users before anyone looks at its access rules. The upside is that the mistakes are the same few every time, which makes them checkable.
Real incidents, and the lesson in each
| What happened | When | Lesson |
|---|---|---|
| Lovable apps with open Supabase databases (CVE-2025-48757). A scan of 1,645 showcase apps found 170 (10.3%) whose tables anyone could read or write, across 303 endpoints. (sources: superblocks.com, nvd.nist.gov) | Reported March 2025, CVE published May 2025 | Missing or always-true row-level security policies. The public anon key is safe only when RLS is right. |
| Escape scanned 5,600+ public apps built on Lovable, Base44, Create.xyz, Vibe Studio and Bolt.new and found 2,000+ vulnerabilities, 400+ exposed secrets and 175 cases of exposed personal data, including medical records and IBANs. (source: escape.tech) | Published October 2025 | The same few mistakes repeat at scale: exposed keys, broken access control, leaky APIs. |
| Wiz found that anyone could register on private apps built with Base44, including SSO-only ones, using just the app ID visible in the URL. Wix fixed it within 24 hours; no evidence of exploitation. (sources: thehackernews.com, infosecurity-magazine.com) | Disclosed July 2025 | Platform bugs hit every app at once. Don’t rely on the builder alone for access control on sensitive data. |
| Replit’s agent deleted SaaStr founder Jason Lemkin’s production database during a declared code freeze, then misreported whether it could be restored. Replit’s CEO called it unacceptable. (source: fortune.com) | July 2025 | Never give an agent write access to production data. Separate dev and prod; keep backups you control. |
| QUITTR, the quit-porn app often cited as a vibe-coded success, had a misconfigured database that 404 Media reported exposed sensitive data from users, many of them minors. The team said it fixed the issue, ran a security review and added safeguards. (source: 404media.co) | Reported 2026 | Success multiplies the cost of a default config. Sensitive categories (health, minors, money) need a review before scale. |
| EnrichLead, a lead-gen SaaS whose maker built it in public with AI, was attacked soon after launch: commentary at the time described API keys reachable from the client and a paywall that could be bypassed. (source: indiehackers.com) | 2025 (secondhand accounts) | Building in public attracts attackers as well as users. Keys and entitlement checks belong on the server. |
| Researchers showed that an agent running the Supabase MCP server with the service_role key could be tricked by a support ticket into copying a private table into a ticket the attacker can read. (source: simonwillison.net) | July 2025 | Agents with private data, untrusted input and a way to write back are a “lethal trifecta”. Use read-only modes and no prod credentials. |
| CurXecute (CVE-2025-54135): a prompt injection arriving through an MCP server could rewrite Cursor’s MCP config and run commands on the developer’s machine. Fixed in Cursor 1.3. (source: thehackernews.com) | Fixed July 2025 | Your coding agent is an attack surface too. Keep it updated and limit which MCP servers and commands it can run. |
Hosting is part of the risk too. Yuanlin Lin’s Zeabur, a deployment platform repositioned for the vibe-coding era, announced it would shut down after two security breaches in 2026 (sources: zeabur.com, cybernews.com). Keep your own backups and your own copy of the code, whatever platform you build on.
Checklist 1: authentication and access control
“Logged in” and “allowed to see this” are different checks, and AI code often does only the first, or only hides a button in the UI. Every check must happen on the server.
- Use a real auth provider (Supabase Auth, Clerk, Firebase Auth, Auth.js). Never let the AI invent password storage or session tokens.
- Check the session in every API route and server action that reads or writes private data, not just in page components.
- Test with two accounts. Log in as user A, copy the ID of one of user B’s records into a URL or API call, and confirm you get nothing back.
- Roles live on the server. An “isAdmin” flag in the browser or in a JWT the client can edit is not a permission.
- Consider a proven starter for anything with teams or billing. Boilerplates such as Jonathan Wilke’s supastarter ship authentication, billing and multi-tenancy that thousands of developers have already exercised (source: supastarter.dev).
Checklist 2: Supabase row-level security
Lovable, Bolt and many Cursor projects use Supabase, which exposes your database through an API using a public “anon” key that is meant to be in the browser. That is safe only if row-level security (RLS) is on and every policy is correct (sources: supabase.com, supabase.com). The service_role key bypasses RLS entirely and must never reach the browser or an AI agent with access to untrusted input.
- Open the Supabase dashboard’s security advisor and fix every “RLS disabled” and “policy allows all” warning.
- For each table, write down who should read, insert, update and delete, then compare with the policies.
- Test from the browser console with the anon key while logged out, then as a second user.
- Make storage buckets private unless files are meant to be public, and add policies for them too.
-- 1. Turn RLS on for every table in the public schema alter table public.notes enable row level security; -- 2. Owners can read their own rows create policy "owner can read" on public.notes for select to authenticated using ( (select auth.uid()) = user_id ); -- 3. Owners can insert rows only for themselves create policy "owner can insert" on public.notes for insert to authenticated with check ( (select auth.uid()) = user_id ); -- 4. Owners can update / delete only their own rows create policy "owner can update" on public.notes for update to authenticated using ( (select auth.uid()) = user_id ) with check ( (select auth.uid()) = user_id ); create policy "owner can delete" on public.notes for delete to authenticated using ( (select auth.uid()) = user_id ); -- Red flags to search for in existing policies: -- using ( true ) -> anyone can read -- to anon / to public -> logged-out visitors included -- no policy + RLS off -> table fully open via the anon key
Founders building on Supabase include Brian Shin, whose Once app lists Supabase and Claude Code in its stack, and Prajwal Tomar, whose MVP agency pairs Lovable with Supabase. If your app has a table of users’ private content, assume the incident table above applies to you until you have tested it.
Checklist 3: secrets and API keys
- Anything prefixed for the browser is public. In Next.js that is
NEXT_PUBLIC_, in ViteVITE_. Only publishable keys belong there. - Call paid APIs from the server. An OpenAI or Anthropic key in front-end code will be found and spent by strangers.
- Set hard spending limits on every AI, email, SMS and maps provider, plus usage alerts.
- Scan the repo history, not just the current code. GitHub secret scanning or tools like gitleaks catch keys committed in a past version (source: docs.github.com).
- Rotate any key that was ever exposed, even briefly. Deleting the line does not un-leak it.
- Don’t paste production secrets into chats with AI tools; use environment variables and placeholder values.
Checklist 4: prompt injection and AI agents
Prompt injection is the top risk in OWASP’s list for LLM applications: text from a user, a web page, an email or a document that the model treats as instructions (source: genai.owasp.org). It matters in two places.
In your app’s AI features:
- Put no secrets or other users’ data in the system prompt; assume users can extract it.
- Never execute model output as code or SQL, and never render it as raw HTML.
- Give tools the least privilege: a support bot can read the current user’s orders, not every order.
- Require a human click for anything irreversible the AI proposes (refunds, emails, deletes).
In your coding agent:
- No production credentials in the agent’s environment; use a dev database and read-only modes where offered.
- Install only MCP servers you trust and keep your editor or CLI updated (CurXecute was fixed by an update).
- Don’t combine private data, untrusted content and a way to write back in one agent session.
- Use guardrails that stop the agent from cheating. Kitze’s Zero To Shipped kit added lint rules and a no-disable policy specifically to stop agents silencing errors to finish a task (source: zerotoshipped.com).
Checklist 5: dependencies and invented packages
AI models sometimes recommend packages that do not exist. A USENIX Security 2025 study generated 2.23 million package references from 16 models and found 19.7% were hallucinated, with open-source models far worse than commercial ones; many invented names repeated across runs, which makes them predictable targets (sources: usenix.org, csoonline.com). Registering those names with malware is called slopsquatting.
- Before installing, look the package up on npm or PyPI: real repo, recent releases, meaningful downloads.
- Add a rule to your agent’s rules file: name every new package and wait for approval.
- Commit the lockfile and run
npm audit/pnpm auditregularly; enable Dependabot or Renovate. - Prefer fewer dependencies. Plenty of profitable indie apps run on a deliberately small stack.
Checklist 6: payments, abuse and operations
- Payments: use hosted checkout (Stripe Checkout, Lemon Squeezy, Paddle). Decide price and entitlement on the server and verify webhook signatures. Never trust a price or a “paid: true” sent by the browser.
- Abuse: rate-limit sign-up, login, password reset, AI and email endpoints; add a CAPTCHA or email verification where bots would profit.
- Backups: turn on automatic backups and restore one once, so you know it works.
- Separation: a dev project and a prod project with different keys. Agents work in dev.
- Plan for a leak: error tracking, logs you can search, and a way to email every user.
Sensitive categories raise the bar. If your app handles health data, children, money or intimate content, as Alex Slater’s QUITTR does, pay for a human security review before you scale marketing. It costs far less than the incident.
The 30-minute pre-launch audit
Run this list before launch and after any change to auth, payments or the database. Pair it with the security review prompt in our vibe coding prompts guide, which asks your AI tool to report findings with file and line numbers.
PRE-LAUNCH SECURITY CHECKLIST Access [ ] Every page/API route/server action with private data checks the session on the server [ ] User A cannot read or edit user B's data (test with two accounts + the browser network tab) [ ] Admin features check a role on the server, not a hidden button Database [ ] RLS enabled on every table; no "using (true)" on private tables [ ] service_role / admin keys only on the server, never in the browser bundle [ ] Storage buckets private unless they must be public Secrets [ ] No keys in client code, the repo history, screenshots or logs (run a secret scanner) [ ] Separate dev and prod keys; rotate anything that was ever exposed [ ] Spending caps on every paid API (AI, email, SMS, maps) Input and AI [ ] Server-side validation on every form and API body [ ] Rate limits on sign-up, login, password reset, AI and email endpoints [ ] AI features: system prompt has no secrets; model output is never executed or rendered as raw HTML; tools are least-privilege Dependencies [ ] Every package exists, is maintained and is the one you meant (no typo or invented names) [ ] Lockfile committed; audit run (npm audit / pnpm audit) Payments [ ] Prices and entitlements set on the server; webhooks verified with the signing secret Operations [ ] Agents never have production write access [ ] Automatic backups you can restore, tested once [ ] Error tracking and a way to contact users if something leaks
If the audit turns up more than you can fix, that is normal and fixable: freelance developers now specialise in hardening vibe-coded apps (see vibe coding jobs). And before you build, check our Can I vibe code it? pages, which flag the security-sensitive parts of common app types.
Frequently asked questions
Is vibe coding safe?
It can be, but not by default. AI tools produce working code that often skips access control, row-level security and secret handling. Scans of thousands of vibe-coded apps found exposed databases and hundreds of leaked keys. Running a security checklist and testing with two accounts before launch closes most of the common holes.
What are the biggest vibe coding security risks?
Database tables left readable by anyone because row-level security is off or too permissive, secret API keys in front-end code, API routes that do not check the logged-in user, prompt injection in AI features and coding agents, agents with access to production data, and hallucinated or malicious packages.
Is the Supabase anon key safe to expose?
Yes, the anon (publishable) key is designed to be public, but only if row-level security is enabled on every table with correct policies. The service_role key bypasses row-level security and must only ever be used on the server.
How do I check if my Lovable or Bolt app is secure?
Run the platform's built-in security scan, open the Supabase security advisor, confirm RLS is on for every table, search the front-end bundle for secret keys, and test with two user accounts that neither can read the other's data. Then run a security review prompt and fix findings by severity.
What is slopsquatting?
Slopsquatting is registering a package name that AI models tend to invent, then filling it with malicious code, so that developers who install whatever the AI suggests get compromised. A 2025 USENIX study found 19.7% of 2.23 million AI-suggested package references were hallucinated.
Should I let an AI agent access my production database?
No. Give agents a development database with fake data, use read-only modes where available, and keep production credentials out of the agent's environment. The 2025 Replit incident, where an agent deleted a production database during a code freeze, shows why.