The headline numbers
112 of the 549 repos, 20.4%, had at least one secrets finding: a hardcoded credential, key, or password committed into public code. That's the most consequential number in the study. A committed secret in a public repo is an open door, and it stays open until somebody rotates the key. 26.8% of repos had at least one critical or high finding of any kind, and 14.9% had at least one critical.
The exposure doesn't end when you spot it. A committed secret stays in git history after you delete the file, so anyone who cloned or forked the repo still has it, and credential scrapers watch the public-repo firehose and reach new pushes within minutes. The rotation clock starts at the push, not at the discovery. Most of these repos belong to someone who built an app over a weekend and has no reason to know any of that.
The most common individual findings were dangerouslySetInnerHTML usage (42.6% of repos), a .gitignore that doesn't cover .env files (35.7%), no .gitignore at all (15.3%), curl-piped-to-shell installs (9.8%), hardcoded passwords (9.3%), and wildcard CORS (11.3%). None of them are subtle. They're the mistakes the most direct working version of the code makes, and the most direct working version is what AI tools generate by default.
One of those six needs a correction we made after publishing. Wildcard CORS counts a config pattern, not vulnerable apps. A reader challenged it, we re-examined all 120 hits, and 0.4% of repos were actually exploitable. The rest were inert or weren't running code at all. The section below shows the working.
Why the median A is misleading: read the mean and the tail
The median repo scored 97, an A, and if we wanted a flattering headline we'd stop there. We don't, because the median is inflated. 85 of the 549 repos have 15 or fewer scannable files: workshop demos, single-page toys, docs-heavy "how to vibecode" repos. A repo that small trivially scores an A because there's almost nothing in it to flag. They are self-described vibe-coded output, so they were counted, but they drag the median up.
The mean and the grade distribution tell it straighter: mean score 89.0, with 353 repos at A, 69 at B, 92 at C, 21 at D, and 14 at F. That's 196 repos with real findings, more than a third of the set, and the lowest score anywhere in it was 15. For repos with substance, the picture is in the per-category hit rates below.
Cut to repos with 15 or more scannable files (n = 467) and the point lands directly. In that group, 23.3% had an exposed-secret finding, roughly 1 in 4. 30.2% had a critical or high finding, 48.8% an injection finding, and 43.0% used dangerouslySetInnerHTML. Take the toy repos out and every rate goes up.
Where the findings concentrate, and what we didn't measure
By category, 54.5% of repos had at least one data-exposure finding, 47.5% injection, 20.6% dependencies and supply chain, 20.4% secrets, 14.0% auth, and 8.7% transport. Findings per repo averaged 5.4 (median 2). Because the engine caps reporting at 10 findings per rule and 300 per repo, the counts for the messiest repos are floors, not totals.
Two limits, plainly. The study ran the heuristic rules engine only. The Claude review that's part of every real quality·vibes scan was off, so anything needing code-reading judgment went uncounted, and scores would likely shift down with it on. And "vibe-coded" means self-described: we took repos at their word rather than verifying provenance. About this study: 549 public GitHub repos self-described as AI- or vibe-coded, data collected July 2026, scanned by the quality·vibes rules engine. Methodology in full on the how-we-benchmarked page.
Share of the 549 repos with at least one finding, by quality·vibes category (rules engine only, July 2026)
| Category | Repos with ≥1 finding | Most common finding inside it |
|---|---|---|
| Data exposure | 54.5% | .gitignore missing .env coverage (35.7% of repos) |
| Injection & unsafe code | 47.5% | dangerouslySetInnerHTML (42.6% of repos) |
| Dependencies & supply chain | 20.6% | curl | sh installs (9.8% of repos) |
| Secrets & credentials | 20.4% | hardcoded passwords (9.3% of repos) |
| Auth & access control | 14.0% | wildcard CORS (11.3% of repos, 0.4% exploitable) |
| Transport & TLS | 8.7% | disabled verification / plain-http calls |
frequently asked
Does this prove vibe-coded apps are insecure?
It proves something narrower and more useful. About one in five self-described vibe-coded repos ships a secrets finding, and about one in four has a critical or high finding, measured by deterministic rules rather than opinion. Most repos scored well. The tail is real, and it's predictable.
Why lead with 20.4% when the median grade is an A?
Because the median is inflated by tiny demo repos. 85 of the 549 have 15 or fewer files and trivially score A. A committed secret is binary and damaging whatever the repo's size, so the hit rate is the headline that survives scrutiny. We show the full grade distribution either way.
Was AI used in the scoring?
No. The study ran the quality·vibes rules engine only, with the Claude review from normal scans switched off, so every number here is reproducible pattern detection. Real scans add an AI pass on top, which typically finds more.
Can I see how my repo compares?
Yes. Paste your public GitHub repo link into quality·vibes and you get the same six-category scan, scored 0 to 100 with a letter grade, in under a minute. The free tier covers two scans, no card.
Published June 11, 2026 · Last updated July 25, 2026