TL;DR
Vibe-coded apps are not insecure in interesting ways. They are insecure in the same eight ways, nearly every time, because the model that wrote them was optimising for “it works when I click it”, and none of these eight stop it from working when you click it: secrets shipped to the browser, database rules switched off, permission checks that live only in the UI, no rate limits on login and reset, public storage buckets, error messages that describe your internals, dependencies nobody pinned or scanned, and an AI agent that still has write access to production.
You can check all eight in about an hour without being an engineer, and roughly half can be fixed by asking the same tool that built the app. The other half need a person. Which half you are in decides whether you fix the app or rebuild the core before the first real customer, and this post ends with that decision.
Why AI-built apps fail security in the same places
Vibe coding tools (Lovable, Bolt, v0, Replit, Cursor and the rest, covered in vibe coding an MVP) generate code from a description of what the app should do. The model is rewarded for producing something that runs and looks right. Security is the set of things the app should *not* do, and nothing in “make a dashboard where users see their invoices” tells the model that user A must not be able to see user B’s invoices by changing a number in the URL.
So the model does the obvious thing. It puts the API key where the code that needs it lives, which is often the browser. It turns off the database’s row-level permissions because they were blocking the demo. It hides the admin button instead of checking on the server whether the user is an admin. It returns the full error so the developer (the model) can debug. Each of these makes the app work faster, and each is a hole.
Two things make it worse than a junior developer doing the same. The model does it consistently across every endpoint, so the pattern is everywhere by the time you notice. And the founder cannot read the code, so nobody notices until a user does, or a scanner does, or a prospect’s security team does.
This is not a reason not to vibe-code an MVP. It is a reason to run the hour below before anyone real touches it.
The eight holes, what each looks like, and how to check it
| # | The hole | What it looks like from your side | How to check in minutes | Fix yourself or engineer? |
|---|---|---|---|---|
| 1 | Secrets in the browser | API keys, database credentials or signing secrets in the front-end code | Open the deployed site, view page source or the network tab, search for key, secret, sk_, service_role |
Engineer, usually: the key has to move to a server and the client rewired |
| 2 | Database rules off | Supabase RLS disabled, Firebase rules set to allow read, write |
In the database console, look at the policies or rules on every table; “public” or “true” on a table with user data is the hole | Yourself for simple tables, engineer for anything multi-tenant |
| 3 | Permissions only in the UI | Admin pages hidden by the front end; the API does not check | Log in as a normal user, take an admin-only request from the network tab, replay it | Engineer: every endpoint needs a server-side check |
| 4 | No rate limiting | Login, password reset, OTP, invite and sign-up endpoints accept unlimited attempts | Try the wrong password thirty times; if nothing slows or locks, there is no limit | Often yourself: most hosting and auth providers have a switch |
| 5 | Public storage | Uploaded files, exports or backups readable by anyone with the link, or listable | Take a file URL, open it in a private window; try the bucket root | Yourself for the bucket setting, engineer if the app depends on public links |
| 6 | Verbose errors and debug mode | Stack traces, table names, internal hostnames in error responses; debug flags on in production | Trigger an error (a bad ID, a malformed form); read the response | Yourself: production config, error handling switch |
| 7 | Unpinned, unscanned dependencies | Packages at “latest”, no lockfile, no scanner, known vulnerabilities in what shipped | Look for a lockfile in the repo; turn on the free dependency scanner in the code host | Yourself to switch on scanning; engineer to fix what it finds |
| 8 | The agent has production access | The AI tool that built the app can still run commands against the live database | Check what credentials the tool holds and what environment they point at | Yourself, today: separate environments, revoke production access |
The eighth one deserves its own sentence. In 2025 a well-known SaaS founder’s AI coding agent deleted a production database during a declared code freeze, then reported that it had done so. The tool was not malicious; it had write access to production and an instruction it interpreted badly. If the thing that built your app can still touch your live data, that is the first hole to close, and it takes ten minutes.
The one-hour audit, in order
Do these in this order, because the first three close the doors that are open right now, and the rest tell you what kind of app you have.
- Revoke the builder’s production access (ten minutes). Rotate any key the AI tool holds. Create a staging environment and point the tool at that. If the tool and production are the same thing, you have no production yet; treat it as a draft.
- Look for secrets in the front end (ten minutes). View source on the live site. Search for
key,secret,token,sk_,service_role,password. Anything that is not a deliberately public key (Stripe publishable keys and Supabase anon keys are designed to be public; service-role keys and Stripe secret keys are not) is hole number one. Rotate it now; move it later. - Read your database rules (ten minutes). In Supabase, every table with user data should have RLS enabled and policies that reference the current user. In Firebase, rules that say
allow read, write: if trueon anything but genuinely public data are the hole. Supabase MVP and Firebase MVP cover what good defaults look like for each. - Replay an admin request as a normal user (ten minutes). Log in as a basic account, find an admin-only action in your own UI (or use the network tab from an admin session), and send it from the basic account. If it succeeds, permissions live in the UI only, and every endpoint is suspect.
- Hammer the login (five minutes). Thirty wrong passwords. If nothing slows down, locks or challenges, turn on rate limiting at your auth provider or hosting layer.
- Open a file URL in a private window (five minutes). Uploaded files should not open without a session, and the bucket root should not list.
- Break something and read the error (five minutes). A malformed ID, an empty form, a wrong type. If the response names tables, hosts or stack frames, switch debug off and put a generic error handler in front.
- Switch on dependency scanning (five minutes). Every code host has a free scanner. Turn it on; read the criticals. Confirm a lockfile exists so what you deploy is what you tested.
Write down which of the eight were open. That list is the input to the next decision.
What a pen test finds on a vibe-coded app
If you are heading for an enterprise customer or a SOC 2 window, someone will eventually pay a professional to look. On a vibe-coded app the report is predictable: it is the eight holes above, plus whatever the specific product added (an integration with an over-broad token, a webhook with no signature check, a search endpoint that accepts raw queries). The tester will find the same authorisation gap on fifty endpoints because the model wrote all fifty the same way.
That is the argument for running the hour first. A pen test on an app with the eight holes open is a specialist being paid to confirm what a checklist would have shown; a pen test after the hour is a specialist finding the things the checklist cannot. Penetration testing vs vulnerability scanning covers when a startup needs each and what a first test costs. Do not buy one until the hour is done and the “engineer” column is settled.
Fix it or rebuild the core: the decision
Here is the honest split, and it follows from which row of the figure your open holes are in.
If everything open was in the top row (rate limits, storage, errors, agent access): fix it this afternoon, with the same tool if you like, and carry on. You have a draft with a few settings wrong, which is normal.
If holes 1, 2 or 3 are open (secrets in the client, rules off, permissions in the UI): these are structural. They are not one fix; they are the same fix repeated across every endpoint and every table, and they usually mean the client was built to talk directly to the database or to third-party APIs with credentials it should never have had. An engineer can sometimes retrofit this in a week or two on a small app. On anything with more than a handful of tables and roles, the retrofit is most of a rebuild of the data layer, and the question becomes whether to rebuild the core properly and keep the vibe-coded front end as the design. When to rebuild your MVP has the general test; the security-specific version is: if you cannot name an endpoint that checks ownership on the server, rebuild the layer that should.
If hole 7 is open and the criticals are in something central (the auth library, the database client): the upgrade may break the app in ways the model cannot diagnose, which is a version of the same structural problem.
The uncomfortable part is that the app keeps working the whole time. Nothing in the eight holes breaks a demo. They break when a real user changes a number in a URL, when a competitor’s intern finds your service-role key in a bundle, or when a prospect’s security team sends a questionnaire. The vibe-coded MVP’s ceiling is usually described as scale or maintainability; in practice it is reached first here.
Before your first paying customer, and before your first questionnaire
Two moments make this urgent rather than theoretical.
The first paying customer puts real data in the app. Every hole in the table becomes a liability the moment that happens, and some of them (health data, payment data, children’s data) carry legal consequences that do not care how the app was built. HIPAA compliant MVP is the health version; the general principle is that the hour above is the minimum before real data.
The first enterprise security questionnaire asks, in writing, whether you encrypt at rest, enforce MFA, scan for vulnerabilities, restrict access by role, and have had a third-party test. A vibe-coded app with the eight holes open answers “no” to most of those, and the founder either says so or does not. SOC 2 for an MVP lists the week-one decisions that make those answers “yes” cheaply; the point here is that they are the same decisions that close holes 1, 2 and 3, which is why they are structural.
What to do with the AI tool afterwards
Keep it, with boundaries. The vibe coding tools are excellent at the front end, at iterating on screens, at the draft. The pattern that works is: the tool owns the interface and points at an API and data layer that an engineer built with server-side authorisation, managed identity, secrets in a vault and rules on every table. The tool never holds production credentials. Every change goes through a branch and a reviewed deploy, not straight to live. No-code MVP and MVP for non-technical founders cover the same boundary from the other direction; MVP tech stack covers what a stack that supports it looks like.
Conclusion
Vibe-coded MVPs fail security in eight predictable places: secrets in the browser, database rules off, permissions only in the UI, no rate limits, public storage, verbose errors, unscanned dependencies, and an AI agent with production access. An hour with the checklist above finds which are open. Four are settings you can fix today. Four are structure, and if those are open on anything bigger than a small app, the honest answer is to rebuild the data and API layer properly and keep the front end you like.
None of this means the draft was a mistake. It means the draft was a draft. The founders who get hurt are the ones who put customers on it without running the hour.
If you have a vibe-coded MVP that works and are not sure it is safe to put customers on, that is a conversation we have more and more often as an MVP development company: usually the answer is a few settings, sometimes it is a proper core under the front end you already have. Start it here.
Related guides
- Vibe coding an MVP
- Penetration testing vs vulnerability scanning
- Production-ready MVP
- When to rebuild your MVP
- SOC 2 for an MVP
- MVP technical debt
- Supabase MVP
- Scale your MVP
Frequently Asked Questions
Is vibe coding secure?
Not by default. AI app builders optimise for code that runs and looks right, and security is the set of things the app should not do, which nothing in a feature description specifies. The result is the same eight holes in almost every vibe-coded app: secrets in the browser, database rules off, permissions only in the UI, no rate limits, public storage, verbose errors, unscanned dependencies and an agent with production access. All eight can be checked in about an hour.
What are the biggest vibe coding security risks?
Three are structural: API keys or service credentials shipped to the browser, database row-level rules disabled so any user can read any row, and permission checks that exist only in the interface so the API accepts requests it should refuse. Those three are what let one user read another’s data, and they are repeated across every endpoint because the model wrote them all the same way.
How do I check if my vibe-coded app is secure?
Run the one-hour audit: revoke the AI tool’s production access, search the live site’s source for secrets, read your database rules table by table, replay an admin request as a normal user, try thirty wrong passwords, open a file URL in a private window, trigger an error and read it, and turn on dependency scanning. Write down which of the eight holes are open.
Can I fix vibe coding security issues with the same AI tool?
For the settings-type holes, usually: rate limiting, storage permissions, error handling, environment separation. For the structural ones (secrets in the client, rules off, permissions in the UI) the tool tends to fix one endpoint and leave forty-nine, or move the secret somewhere equally wrong. Those need an engineer who can change the architecture, not the code.
Why are Supabase RLS and Firebase rules such a common problem in vibe-coded apps?
Because the front end talks to the database directly in most AI-built apps, the database rules are the only thing standing between users, and the model switches them off when they block a feature during the build. The fix is to enable RLS or restrictive rules on every table with user data, with policies that reference the current user, and to stop the client using privileged keys.
Should I get a penetration test on a vibe-coded MVP?
Not before the one-hour audit and the structural fixes; the report would be a specialist confirming a checklist. After that, yes when a customer or a SOC 2 window requires it. Penetration testing vs vulnerability scanning on this site covers when a startup needs one and what it costs.
Should I rebuild my vibe-coded app or fix it?
If only settings were open, fix and keep it. If secrets in the client, rules off or UI-only permissions were open on a small app, an engineer can retrofit in one to two weeks. On a larger app those three usually mean the client was built to talk directly to the database with credentials it should not have, and the honest fix is to rebuild the data and API layer properly and keep the front end as the design.
Is it safe to launch a vibe-coded MVP to real users?
Only after the eight holes have been checked and the structural ones closed. The app will run either way, which is the trap; it breaks when a user changes an ID in a URL, when someone finds a key in the bundle, or when a prospect’s security team sends a questionnaire. Real user data, and especially health, payment or children’s data, raises the stakes from embarrassment to liability.
Can an AI coding agent delete my production database?
Yes, if it holds credentials that reach production. In 2025 a widely reported incident involved an AI agent deleting a live database during a code freeze. The fix takes ten minutes: separate environments, revoke the tool’s production access, and route every change through a branch and a reviewed deploy.
Do I need an engineer to make a vibe-coded app secure?
For the four settings-type holes, no. For the four structural ones, yes, and the amount of engineering ranges from a fortnight on a small app to a rebuild of the core on a larger one. The vibe-coded front end is usually worth keeping either way.





