The short version
Most apps built with Lovable, Bolt, v0, or Cursor ship with security holes. A 2026 review of more than 200 vibe-coded apps found 91.5% carried at least one vulnerability. The three that bite first are exposed API keys, Row-Level Security left off, and broken auth. You can check several yourself in an afternoon. A few need a senior engineer. This is the exact checklist we run before we call an AI-built app safe to launch.
You shipped fast. The AI builder turned your idea into a working app over a weekend, the demo went well, and now real users are signing up. Then a quiet thought shows up at 2am. Is this thing actually safe? Could someone read another customer's data? You are right to ask.
Here is the uncomfortable part. The speed that makes AI builders feel like magic is the same speed that skips the boring security work a careful engineer would never skip. The builder writes code that runs. It does not write code that defends itself.
Is vibe coding actually insecure?
Yes, more often than not, and the numbers are not subtle. Depending on the study, between 40% and 62% of AI-generated code contains a security vulnerability. A first-quarter 2026 review of more than 200 vibe-coded applications found 91.5% carried at least one flaw traceable to an AI hallucination (Autonoma).
This is not theory. In January, the vibe-coded app Moltbook was breached three days after launch, exposing 1.5 million API tokens and 35,000 email addresses through a Supabase database with no row-level security (TechGines). A separate scan found roughly 380,000 publicly reachable vibe-coded apps, and more than 2,000 of the corporate ones were leaking sensitive data to the open internet. Your app does not have to be famous to be found. Scanners look for everyone.
What are the most common vibe-coding security holes?
The same gaps show up again and again. Here is the checklist we run on every Lovable, Bolt, v0, Cursor, or Replit app, in the order that matters.
- Exposed API keys. Open your live site, press F12, and search the bundle for your keys. If your Supabase service key or a payment secret is sitting in the browser, anyone else can read it too. Move every secret to the server.
- Row-Level Security turned off. Around 70% of Lovable apps ship with RLS disabled, so the database trusts the browser and any logged-in user can read any row. Turn it on for every table that holds user data, then try to break it from a second account.
- Broken authentication. In one review, 24% of vibe-coded apps had their auth logic inverted, so unauthenticated visitors had full access while real users were locked out. Verify signups, expire sessions, and check the user on the server.
- Wide-open CORS. Prototypes often allow every origin. Lock it down to your own domains so random sites cannot make authenticated calls on your users' behalf.
- No input validation. AI builders trust whatever the form sends. Validate and sanitize every input on the server to shut down injection and junk data.
- No rate limiting. Without a cap, one script can hit your signup or payment endpoint thousands of times a minute and run up a real bill. Cap the endpoints that cost money or send mail.
- Secrets in the repo. Hardcoded database strings and tokens leak into commit history and client bundles. Rotate anything exposed and load secrets from the environment.
- Unpatched dependencies. Generated apps pull in packages and almost never update them. Run an audit and patch the known holes before launch.
- No logging or alerts. If you cannot see a failed-login spike or an error storm, you learn about a breach from your users. Add basic error and access logging from day one.
How do you check if your app is already leaking data?
Three checks take about an hour and tell you most of what you need to know.
Open the live site in your browser, go to the Sources tab, and search for words like "service", "secret", and "key". Anything that looks like a credential in the browser is already public. Next, log in with a normal test account, create a second account, and try to load the first account's data by changing an id in a request. If account two can see account one's records, your RLS is off or wrong. Finally, log out completely and try to open a page that should require login. If it loads, your auth is not being checked on the server.
None of these need a security background. They need ten minutes and the willingness to look.
Which AI builders have these problems?
All of them, because the gap is in the pattern, not one product. Lovable, one of the largest vibe-coding platforms with millions of users, has had three documented security incidents, including a flaw left open for 48 days (The Next Web). Bolt and v0 generate clean frontends but lean on you to wire the backend security. Cursor and Replit hand you more control, which also means more rope. The fix is the same across all of them. Add the guardrails the builder skipped.
What are the best vibe coding security tools?
Seven will find almost everything an AI builder leaves open, and most have a free tier. Run the first five in the order below, because each one catches what the previous cannot see. The last two start mattering when you are a team rather than one person.
1. Your database dashboard, first. Not a tool anyone sells, and still the highest-yield check. Open Supabase or Firebase, list your tables, and look at who can read each one. In Supabase that is the RLS column. If a table holding user data says row level security is disabled, stop reading and fix that. This single check catches the leak that has hit more AI-built apps than every other cause combined.
2. GitGuardian or Gitleaks for leaked keys. AI builders paste API keys into client-side files constantly, and once a key is in git history, deleting the line does not remove it. Gitleaks is free, runs locally, and scans the whole history rather than just the current files. Run it before you make a repository public, not after.
3. Semgrep for the logic holes. Free, fast, and it reads patterns rather than signatures, which matters because AI-generated code tends to fail in idiomatic-looking ways. It catches missing authorisation checks, unsanitised inputs reaching a query, and endpoints that trust whatever the client sends. Point it at your API routes first.
4. npm audit and Snyk for the dependency tree. You already have npm audit. Snyk goes further and tells you which vulnerabilities are actually reachable from your code, which stops you chasing thirty warnings that no attacker could ever trigger.
5. OWASP ZAP against the running app. Everything above reads your code. ZAP attacks the deployed thing, which is the only way to find what your code says is protected but your deployment is not. Run it against staging, never production.
6. Aikido if wiring five tools is the reason you wire none. It folds code scanning, dependency checks, secrets detection and container scanning into one dashboard, with a free tier. You give up some of the depth each specialist tool has. That is a good trade if the honest alternative is running nothing, and a bad one if you already have Semgrep and Snyk reporting somewhere you actually look.
7. Pluto once more than one person is shipping AI-written code. This one is not a scanner. It answers a different question: who inside the company is building with AI, which tools they are using, and what data those tools can reach. A solo founder does not need it, because the answer is you. A team of eight, where two people are shipping Lovable apps nobody reviewed, very much does. Teams tend to run it alongside a scanner rather than instead of one.
What none of them will catch. Tools find missing locks. They cannot tell you that a user of one account should never see another account's invoices, because that rule lives in your head and nowhere in the code. Multi-tenant leaks between paying customers are the most expensive failure in this whole category, and every scanner on this list will pass an app that has one.
You may not need any of this yet. If nobody has signed up, you take no payments and you store no personal data, run the database check and get on with building. The rest becomes worth your time the day a real person trusts you with real information.
Which security tool catches which AI coding mistake?
No single scanner covers AI-generated code. Gitleaks digs through your git history for keys you already committed. Semgrep reads the source for authorisation checks nobody wrote. Dependencies belong to Snyk and npm audit. ZAP ignores all of that and attacks the running app. Three of the nine holes above belong to nobody.
Most roundups review these scanners against code in general. That isn't the question you have. You have one specific app, built fast by a model that optimised for working rather than for defending itself, and you want to know which of the nine holes each tool will actually find. So here is that mapping, run against the checklist above instead of a generic OWASP list.
| The hole | What finds it | Before or after deploy |
|---|---|---|
| Exposed API keys in the bundle | Gitleaks, GitGuardian, and your own browser Sources tab | Before |
| Row-Level Security switched off | Only your database dashboard. No scanner reads your Supabase settings | Before, if you look |
| Broken or inverted authentication | Semgrep on the routes, then ZAP against staging to confirm | Both, and you need both |
| Wide-open CORS | ZAP, or one look at the response headers | After |
| No input validation | Semgrep, where unsanitised input reaches a query | Before |
| No rate limiting | Nothing detects the absence. ZAP demonstrates it by doing it | After |
| Secrets committed to the repo | Gitleaks, scanning the whole history rather than current files | Before |
| Unpatched dependencies | npm audit, then Snyk to tell you which are reachable | Before |
| No logging or alerting | Nothing. Scanners look for bad code, not for missing infrastructure | Neither |
Read the gaps in that table, not the coverage. Rows two, six and nine have no scanner behind them, and they are not edge cases. Row two is the most common cause of data leaks in AI-built apps. That is the uncomfortable shape of this category. The failures a tool can find are the ones an AI builder is least likely to make, because the model writes idiomatic code that passes idiomatic checks.
Three things no tool on any list will catch. First, a multi-tenant leak between paying customers, because the rule that customer A must never see customer B's invoices lives in your head and appears nowhere in the code. Second, a Row-Level Security policy that exists but is written wrong, which every scanner records as RLS enabled and therefore passes. Third, authorisation logic that is present and consistently wrong, where the code checks that you are logged in and never checks that the record belongs to you. All three pass a clean scan. All three are the expensive ones.
This is why we do not open an audit with a scanner. We open it by asking what the app is supposed to prevent, then checking whether it does. Tools come after that, because a tool can only confirm the absence of known patterns, not the presence of your intent.
How do you actually turn on Supabase Row-Level Security?
Row-Level Security is a Postgres feature that decides, row by row, who may read or write. Supabase creates new tables with it switched off. Turning it on takes one statement per table plus a policy that ties each row back to the user who owns it, and then a test from a second account.
Worth being clear about why the builder left it off. It isn't negligence. Switch RLS on with no policy written and the table returns nothing, so the demo looks broken. Leave it off and everything works instantly, so the app looks finished. The model optimised for the thing you asked for, which was a working app. Nobody asked it what should happen when the second user signs up.
Enable it per table, then write the policy. For a table where every row belongs to one user, the whole thing is short.
alter table public.notes enable row level security;
create policy "owner reads own notes"
on public.notes for select
using (auth.uid() = user_id);
create policy "owner writes own notes"
on public.notes for insert
with check (auth.uid() = user_id);The using clause governs which existing rows are visible. The with check clause governs which new rows you are allowed to create. Miss the second one and a user can read only their own rows while happily inserting rows owned by somebody else. That asymmetry catches people constantly.
Now test it properly, because the dashboard will lie to you by omission. The dashboard tells you RLS is enabled. It does not tell you the policy is correct. Create two real accounts. Log in as the first, note the id of a record. Log in as the second, and request that same id directly. If it comes back, your policy is wrong even though every indicator says protected. A policy written as using (true) reports as enabled and protects nothing.
The trap that undoes all of it. The Supabase service-role key bypasses Row-Level Security entirely, by design, because backend jobs need it. So if that key is sitting in your frontend bundle, and on AI-built apps it very often is, then your policies are decorative. Anyone who opens developer tools can read every row in every table regardless of what you wrote. Check for the service key first. Write policies second. In that order, because the reverse order gives you an afternoon of work and no protection.
If you have turned RLS on, written policies, and still have that key in the browser, you are one of the apps this article is about. That is a good moment to have somebody else look, and our free 48-hour audit exists for exactly that.
Can you fix it yourself, or do you need an engineer?
Some of it is genuinely DIY. The rest is where a quiet mistake becomes a public headline. Here is the honest split.
| Fix yourself in an afternoon | Get a senior engineer |
|---|---|
| Search the bundle for leaked keys | Move secrets server-side and reroute the calls |
| Lock CORS to your domains | Write and test Row-Level Security policies |
| Turn on email verification | Harden sessions and server-side auth checks |
| Add basic error logging | Validate inputs and add rate limiting properly |
If the security items make you nervous, that instinct is correct. Data isolation and auth are the two places where getting it wrong stays invisible until it is public. The auth half has its own page now: our guide to Lovable authentication for real users covers the redirect lists, the email limits, roles, two-factor and sessions, and which of them you can leave alone.
How Geminate Solutions handles this
We do this for a living at Geminate Solutions. We take apps built on Lovable, Bolt, v0, Cursor, and Replit and make them safe to put real users and real money through. You keep your codebase, you own everything we write, and you get a plain list of what was broken and how we fixed it. We have shipped 50+ products and we are Top Rated Plus on Upwork at 4.9, so this is the work, not a theory.
If you want a second set of eyes, we run a free 48-hour production-readiness audit. Send us your app URL and a senior engineer comes back with the real fix list, no pitch attached. You can read how we take AI-builder apps to production, follow the deeper Lovable production checklist, or just tell us what you built and we will take a look.
Frequently Asked Questions
Is vibe coding secure?
Not by default. The app works, but the common gaps are exposed keys, a database with Row-Level Security turned off, and auth that is never checked on the server. Fix those three first and you close most of the risk.
Are Lovable apps safe to launch as-is?
Usually not without a security pass. Around 70% ship with RLS off, which lets one user read another user's data. Turn it on, test it from a second account, and move every secret off the browser before you go live.
What is the most common AI-app security mistake?
Row-Level Security left off. It is quiet, easy to miss, and it lets any logged-in user read everyone's data. It is the first thing we check on every audit.








