We scanned 107 public GitHub repositories whose code was produced with AI / vibe-coding tools (Cursor, Lovable, bolt.new, v0, Windsurf, Replit Agent) using a deterministic pipeline of 8 scanner tools (4 built-in: secret, auth, config, quality pattern scanners + 4 external via --enhance: gitleaks 150+ rules, semgrep auto + p/secrets 800+ rules, Trivy, OSV-Scanner) and found 19,310 security findings across 98 of 107 repositories. 82% of repositories had at least one critical finding.
The headline: most of the volume is transitive dependency CVEs inherited from the npm ecosystem, not bugs the model wrote. But the authored-code findings that remain are a consistent, repeating pattern — committed .env files, localhost URLs leaking into source, missing RLS policies on Supabase queries, unprotected API routes, and eval/exec calls — and they appear in repo after repo at strikingly similar rates.
01. What we scanned
- 107 public repositories on GitHub, identified via search signals pointing to AI / vibe-coding tools (Cursor, Lovable, bolt.new, v0, Windsurf, Replit Agent).
- 8 scanner tools were run per repo in a deterministic pipeline:
- gitleaks — secret-scanning (committed credentials, API keys)
- Trivy — known-vulnerability database for dependencies
- OSV-Scanner — Google's open-source vulnerability database
- Clira configuration scanner — deterministic patterns for
.envfiles,localhostURLs, hardcoded secrets, dangerous function calls - Clira auth scanner — deterministic patterns for unprotected Express/Flask routes, Supabase queries without RLS verification
- Language distribution of scanned findings: 11,039 JavaScript/TypeScript, 551 Python, 394 Rust, 1 Ruby, 1 Go. JavaScript/TypeScript is the dominant language by an order of magnitude — consistent with the production output of these tools.
The scan is purely static + pattern-based — no dynamic analysis, no taint tracking, no execution. It finds evidence of patterns that look like misconfigurations or vulnerabilities; it does not prove exploitability.
02. The headline
- 98 of 107 repos (91.6%) had at least one finding.
- 88 of 107 repos (82.2%) had at least one critical finding.
- 19,310 total findings across all repos and all tools.
- 4,411 critical findings total.
- By severity: 4,411 critical, 6,577 high, 6,273 medium, 2,048 low, 1 info.
That headline number — "82% of AI-generated repos have critical findings" — is real, but it requires context. Among the 19,310 findings:
- 12,409 (64%) are dependency CVEs — vulnerabilities inside transitive npm packages (postcss, brace-expansion, picomatch, minimatch, js-yaml, lodash) that the generated app pulls in via the default
package.jsonscaffolding. - 6,901 (36%) are authored-code findings — things the model wrote into the repo's own files.
The 82% figure counts both. If you subtract the dependency CVEs and only look at what the model itself produced, the picture is different — and that is the more interesting picture.
03. What the model actually wrote wrong
Of the 6,901 authored-code findings, the top repeating patterns are:
| # | Finding | Count | What it means in plain language |
|---|---|---|---|
| 1 | .env file committed to repository | 3,513 | The repo contains an actual .env file (not .env.example) with what looks like credentials in it. Anyone can clone the repo and read the keys. |
| 2 | localhost URL in source | 931 | A hardcoded http://localhost:... URL is in committed code. This often signals dev-only config that was never changed before deployment — Supabase URLs, Stripe webhooks, OAuth callbacks, etc. |
| 3 | Supabase query without verified RLS policy | 825 | A Supabase query was detected in code without a corresponding RLS-policy check. The model likely assumed RLS was on; whether it actually is requires the deployed schema to confirm. |
| 4 | PHP dangerous function call | 452 | Calls to system(), exec(), shell_exec(), passthru(), popen(), proc_open(), or backtick operators. |
| 5 | Express/Flask API route without verified auth middleware | 353 | An HTTP route handler was detected in a server file with no auth middleware attached in the immediate vicinity. |
| 6 | eval() / exec() detected | 266 | Direct use of dynamic code execution in JavaScript/Python. |
The pattern across these six is more telling than any single number. These are not exotic zero-days. They are the same six mistakes, repeated, in repo after repo.
The top CWEs (Common Weakness Enumeration) reinforce the same shape:
- CWE-798 (Use of Hardcoded Credentials) — 3,771 occurrences
- CWE-639 (Authorization Bypass Through User-Controlled Key) — 829
- CWE-400 (Uncontrolled Resource Consumption) — 504
- CWE-79 (Cross-Site Scripting) — 406
- CWE-1333 (Inefficient Regular Expression Complexity / ReDoS) — 330
- CWE-1321 (Prototype Pollution) — 303
- CWE-95 (Eval Injection) — 266
- CWE-22 (Path Traversal) — 219
- CWE-78 (OS Command Injection) — 189
- CWE-94 (Code Injection) — 153
The credential problem (CWE-798) is dominated by committed .env files and a portion of the 231 secret-category findings (73 of which are flagged as generic-api-key).
04. The dependency tax
The single largest category of findings — 12,409 of 19,310 (64%) — is dependency CVEs pulled in by transitive npm packages. The most-repeated CVE advisories across all 107 repos are:
- postcss — multiple GHSA IDs (r28c-9q8g-f849, 6g55-p6wh-862q, qx2v-qp2m-jg93) — 100 + 95 + 92 = 287 occurrences
- brace-expansion — GHSA-mh99-v99m-4gvg, GHSA-3jxr-9vmj-r5cp, GHSA-f886-m6hf-6m8v — 99 + 98 + 86 = 283 occurrences
- picomatch — GHSA-c2c7-rcm5-vvqj, GHSA-3v7f-55p6-f55p — 91 + 91 = 182 occurrences
- minimatch — GHSA-23c5-xmqv-rm74, GHSA-3ppc-4f35-3m26, GHSA-7r86-cg39-jmmj — 81 + 81 + 81 = 243 occurrences
- js-yaml — GHSA-52cp-r559-cp3m, GHSA-h67p-54hq-rp68 — 82 + 80 = 162 occurrences
- lodash — GHSA-r5fr-rjxr-66jc, GHSA-f23m-r3pf-42rh, GHSA-xxjr-mmjv-4gpg — 73 + 73 + 64 = 210 occurrences
These are not bugs the model wrote. They are inherited from the npm ecosystem that any modern JS/TS project — AI-generated or not — draws from. The honest framing: AI-generated JS/TS apps inherit a large transitive CVE surface as a consequence of the ecosystem the model draws from, not necessarily as a consequence of the model itself. Human-written JS/TS apps on the same stack typically inherit the same surface.
The implication is practical, not moral: shipping AI-generated code with npm install and no audit means shipping these CVEs to production by default.
05. What this does NOT show
A scan like this has limits. We're being explicit about them so the numbers above are read accurately:
- No taint analysis. We flag patterns; we do not trace data flow from a source to a sink.
- No reachability analysis. A vulnerable dependency being present in
package.jsondoes not mean the vulnerable code path is reachable. Many of the 12,409 dependency CVEs are not exploitable in their specific installed version. - No runtime / live-infrastructure test. We do not start the application, fuzz endpoints, or test deployed instances.
- No penetration testing. We don't attempt to exploit anything.
- Evidence excluded by policy. Per-repo secret values, API keys, and credential payloads are filtered out of the aggregated summary. This report contains counts and titles only — no third-party secrets are reproduced.
- JS/TS skew. The 107 repos are heavily concentrated in JavaScript/TypeScript (the dominant output of the targeted AI coding tools). Findings and patterns for Python, Rust, Go, and Ruby are present in much smaller numbers.
- No causal claim about the model. "AI-generated" means the code was produced with the assistance of AI coding tools. Some of these repos were presumably reviewed by humans; some were not. The scan cannot tell the difference, and we are not making claims about which findings a human would have caught.
06. What to do about it
Three concrete recommendations for anyone shipping AI-generated code (or any code, really):
- Never commit
.envfiles. Add.envto.gitignoreon day one, install a pre-commit hook (e.g.gitleaksorpre-commit'sdetect-private-key) that blocks secrets, and use a.env.examplewith placeholder values for documentation. The 3,513 committed.envfiles in this scan are the single most preventable category of finding. - Run a dependency audit before deploy.
npm audit,pip-audit,trivy fs, orosv-scannershould be a default gate in CI. The 12,409 dependency CVEs in this scan are a direct product of skipping that step. Many are unmaintained transitive deps that get force-installed by default scaffolding — a one-linenpm audit fix(or, better, a curated dependency tree) clears most of them. - Verify auth middleware and RLS policies exist on every route / table. This is the structural fix for the 353 unprotected Express/Flask routes and 825 Supabase queries in this scan. For every API route, attach an explicit auth middleware in the route definition — not in a global filter that future routes may bypass. For every Supabase table, enable RLS and add a policy for every operation the app performs. Verify both on the deployed schema, not just in the local code.
These three changes do not require new tools. They are the same checks that should be part of any production-ready codebase — human-written or AI-generated.
07. Methodology footnote
This report is a narrative summary of a structured batch scan. The full structured data is available in:
- AI_GENERATED_CODE_FINDINGS.md — the full per-finding writeup
- batch_results/summary.json — the raw aggregated counts used to produce this report
Scan date: 2026-07-26. Scanner: deterministic Clira pipeline (gitleaks, Trivy, OSV-Scanner, Clira config scanner, Clira auth scanner) + Clira quality scanner. Sample: 107 public GitHub repositories with code produced using AI / vibe-coding tools.
Evidence fields (per-repo secrets, credentials, payloads) are excluded from the aggregated summary by policy and are not reproduced in this report.
This is what a deterministic, pattern-based scan finds across AI-scaffolded code — committed .env files, missing RLS, unprotected routes, inherited dependency CVEs. Want the same lens on your repo? Run the free self-check, or send the repo for a fix-ready report.
Full data and methodology:
docs/AI_GENERATED_CODE_FINDINGS.md · docs/ai_generated_code_summary.json