We Scanned 87 Public Repos Scaffolded by Lovable, v0, Bolt, and Base44. 42% to 76% Had a Critical Finding.
The range depends on the builder — and it moves with project size. The naive count produces a much scarier number, and the scariest thing in that number is a bug in one of our own rules.
“AI-generated code is insecure” is one of the most repeated claims in software right now, and it is almost never said with a number attached. As of this week, there is one. The Vibe Security Index is live: 87 public repositories carrying the scaffold markers of Lovable, v0, Bolt, and Base44, scanned with the same 212 deterministic rules we run for customers, and published as per-builder aggregates with the full methodology and the raw aggregate data.
The headline from Round 2026-07: depending on the builder, between 42% and 76% of scanned repositories carry at least one critical finding in their own application code.
That range is the least interesting thing we found. The interesting part is what we had to subtract before we could publish it honestly — and the filter we refused to run, even though it would have made our own numbers look better.
The numbers
One row per builder, ordered by median project size. The critical rate counts repositories with at least one critical finding in application code — code that is not vendored scaffold, a distinction that gets its own section below.
| Builder | Repos scanned | ≥1 critical (app code) | ≥1 high (app code) | Median files per repo |
|---|---|---|---|---|
| Lovable | 25 | 76% (19 of 25) | 100% (25 of 25) | 160 |
| Base44 | 25 | 60% (15 of 25) | 100% (25 of 25) | 105 |
| v0 | 25 | 56% (14 of 25) | 80% (20 of 25) | 94 |
| Bolt | 12 | 42% (5 of 12) | 100% (12 of 12) | 30.5 |
Before you quote this table
The critical-rate ranking and the project-size ranking are the same ranking. Median scanned files per repository runs from 30.5 (Bolt) to 160 (Lovable) — a roughly fivefold spread — and the critical rate falls in exactly that order. A smaller project has fewer places for a critical finding to occur. We cannot tell you how much of the gap between 42% and 76% is the builder and how much is the size of what its users ship, and neither can anyone else. In particular, do not read Bolt's 42% (5 of 12) as “Bolt is the most secure builder”: its sample is the smallest in the round, its projects are a fraction of the size of everyone else's, and all 12 of its repositories still carried at least one high-severity finding.
These are public repositories carrying each builder's scaffold marker — not the builders' products. The marker proves the project started from that builder. Humans edited these repos afterwards, and some of what we measured is hand-written. The honest reading of a row is “projects that started in this builder and were published publicly look like this,” which is a different sentence from “this builder writes insecure code.”
Static analysis has false positives. A critical finding is something a human should look at, not a proven breach. And at these sample sizes, a few percentage points between builders is noise.
The number we refused to publish
Here is the version of this post you would be reading if we had counted naively. If every file in every repository counted toward its builder, then before a single line of anyone's own application code was considered, at least 88% (22 of 25) of Lovable repositories, 80% (20 of 25) of v0's, and 84% (21 of 25) of Base44's would already have shown a critical finding — from vendored files alone.
Almost all of it traces to two files. These builders scaffold projects with UI primitives copied from shadcn/ui, byte-identical across unrelated repositories: chart.tsx trips an XSS rule and a critical dangerouslySetInnerHTML rule, and sidebar.tsx trips a cookie rule plus two high-entropy string detections. Five findings, near-constant, per repository that ships both files — which is why the median vendored finding count is exactly 5 for Lovable, v0, and Base44 alike.
And the worst of the five is ours. The critical flag on chart.tsx is a false positive in our own rule. That component writes a <style> block assembled from a module-level theme constant. That is CSS-variable theming, not an injection sink, and a rule that flags it is a bug in the rule. The single largest contributor to the scariest available version of these numbers is our bug, and we published that sentence on the index page, next to the numbers it would have inflated.
So the split is mechanical and declared up front: every finding is assigned by path to either application code or vendored scaffold, before any headline number is computed, identically for every builder. Vendored findings are still counted and still published — hiding them would be its own kind of lie — but they never touch a builder's critical rate, grade, or ranking. Every headline figure in the table above comes from application code only.
One asymmetry to name directly, because it is the most misreadable number on the index: Bolt's vendored row is 0% (0 of 12). That is scaffold composition, not security — its template simply does not ship the component-library suite that produces these findings. A 0% vendored rate means the builder vendors less code, not that it generates safer code, and it is one more reason not to read Bolt's row as a security win.
The filter we left off
XploitScan ships an AI false-positive filter — a Claude-based pass that reads each finding in context and drops the ones that are clearly noise. When we scanned 42 public SaaS repos last spring, we ran it, and it removed about a third of the raw matches. For the index, we deliberately turned it off.
The reason is reproducibility — and specifically, reproducibility by someone who is not us. Re-running the filter takes an API key and real money, and it depends on a model snapshot that will eventually be retired. Nobody outside this company can check a filtered number, even in principle. An index that cannot be re-run is an assertion, not a measurement. The deterministic rule set, by contrast, produces the same result for anyone who points it at the same code. The cost is real and it lands on us: the published figures carry a higher false-positive rate than a customer with the filter enabled would see. We would rather publish a rerunnable number with known noise than a cleaner number you have to take on faith. We have written before about why we treat our own flattering numbers with suspicion; this is the same policy applied to a round we knew would be quoted.
Update — July 28, 2026
This section originally said the filter “is not deterministic: a second run can return a different answer.” That was true, and writing it down is what made us go and check why. The answer was that we had never set the sampling temperature at all, so it ran at the API default of 1.0 — the highest-variance setting available, on what is a yes-or-no classification. It is now pinned to 0, in the false-positive filter and in the optional AI analysis that feeds findings into your grade.
That does not make the filter reproducible for a third party, so it does not change the decision to leave it off for this index — the argument above was always the durable one. It does mean scanning unchanged code twice returns the same result, which is what a customer was entitled to assume in the first place. Temperature 0 is not a determinism guarantee from the model vendor, so we ship a harness that measures the actual agreement rate rather than asserting it.
What actually repeats
The per-builder aggregate that matters most for anyone shipping with these tools is not the critical rate — it is which findings recur. When the same finding shows up across a dozen unrelated repositories, it stops being a story about one developer and becomes a story about the workflow that produced them. From the application-code bucket, per builder's sample:
- Lovable: a hardcoded API key or secret (VC001) appears in 17 of 25 repositories — 154 occurrences in the sample. Of everything in this list, this is the finding a human edit after generation most plausibly introduced: a pasted key is a pasted key wherever the scaffold came from.
- v0: an API route missing authentication (VC003) appears in 11 of 25 repositories, and an unprotected Next.js API route (VC065) in 11 of 25.
- Base44: client-side-only authorization (VC010) — access-control checks with no server-side counterpart anywhere in the scanned repository — appears in 19 of 25 repositories. (Enforcement living outside the repo, on the platform's hosted backend, is exactly the kind of thing a repo-scoped scanner cannot see.)
- Bolt: nothing distinctive at its sample size. Its most widespread finding, missing security headers (VC027, all 12 repositories), also hits every repository in the Lovable and Base44 samples, and 12 small projects is too thin a slice to say more — which is itself worth knowing before anyone quotes Bolt's row in either direction.
These are the patterns worth fixing in a prompt, a template, or a review checklist. The index page publishes the top ten recurring rules for each builder.
What this measures — and what it can't
The sample comes from GitHub code search for each builder's scaffold marker: 10,284 public repositories matched Lovable's, 1,372 v0's, 1,312 Bolt's, and 1,248 Base44's. From each pool we took the first eligible repositories in GitHub's own result order — no hand-picking, but not a uniform random draw either. All 87 sampled repositories were scanned, and every one was measured whole; none hit the scanner's file cap.
What it cannot see: anything that never reached public GitHub. Apps deployed straight from a builder without a repo, or pushed privately, are invisible, and there is no reason to assume they resemble the public ones. Attribution is scaffold-level, so human edits are mixed into every measurement. And a finding is a finding, not an exploit. The methodology page lists every limitation we know about, in more detail than anyone will quote.
Re-run it, or tell us where it's wrong
The aggregate data for the round is published as a JSON file — per-builder rates, grade distributions, recurring rules, and anonymized per-repo rows. No repository, owner, or URL appears anywhere in it, and none ever will: a public list of live vulnerabilities in other people's projects is a target list, not research.
If you build one of these platforms and think a number here is wrong, we want to hear it before your users do. Email admin@xploitscan.com and we will re-run the round with your correction and publish the result either way.
Your repo is the row that matters
The same 212 rules that produced this round run on your code in about a minute. Free, no signup, runs locally: npx xploitscan scan .