Detection Benchmark

We publish the raw numbers on how well our scanner performs against a labeled corpus of vulnerable and clean code samples. Checked daily and rerun when rules or fixtures change (at least weekly); updates go live with the next deploy.

Last run: Nov 4, 2026 · Corpus size: 649 fixtures (357 vulnerable, 292 clean)

Updated Nov 3, 2026: we now count reviewed false positives on clean test files. Earlier versions of this page showed 100% precision.

Precision
86.3% (Nov 3, 2026 hand review, updated Nov 4)
Precision counts reviewed false positives on clean fixtures; F1 uses that precision.
Recall
97.2%
findings / known vulns
Reviewed F1
91.5% (precision from Nov 3, 2026 hand review, updated Nov 4)
Precision counts reviewed false positives on clean fixtures; F1 uses that precision.
Counts
626 / 0 / 18
TP / forbidden-rule hits / FN

The numbers above are for all 223 rules (paid plans). On the free plan's 30 rules, the same corpus scores recall 24.8% (TP 160 / forbidden-rule hits 0 / FN 484). Published precision is the reviewed figure above. Most fixtures target vulnerabilities only the paid rules detect.

Trend over time

90 days · since Jun 15, 2026

Recall from the last benchmark run of each day. The corpus grows over time, so a flat or rising line means detection kept pace as new fixtures were added.

Recall97.2%-1.5 pts

Updated Nov 3, 2026: we now count reviewed false positives on clean test files. Earlier versions of this page showed 100% precision.

Corpus: 232 → 649 fixtures. Deterministic scanner only (excludes the optional AI false-positive filter).

How we score

Every fixture in packages/cli/test-fixtures/ is labeled with expectedFindings (rules that must fire, with file and line range) and mustNotFire (rules that must not fire anywhere in the fixture). The runner scans each fixture and counts:

  • True positive (TP) — a finding whose rule, file, and line fall inside an expected entry.
  • False negative (FN) — an expected entry with no matching finding.
  • Forbidden-rule hit — a finding for a rule explicitly listed as mustNotFire. The per-rule column counts these. It is not the precision figure above.

We reviewed by hand, on Nov 3, 2026, each finding on a clean fixture that its label does not expect. Of 396 such findings then, 132 were real false positives. The Nov 4 rule fixes removed 33 of those and did not add any, leaving 99. Of the 339 unexpected findings on the clean fixtures as of Nov 4, 2026, those 99 are the reviewed false positives, which gives 86.3% precision. False positives are counted on clean fixtures only. Recall is computed on every benchmark run.

The runner lives at scripts/benchmark.js in the repository.

About this baseline. The corpus is 649 fixtures, and growing it is ongoing work. These scores are not a claim that the scanner catches everything; they are the floor below which we will not regress. We will keep adding harder cases, and over time the score will become a more demanding indicator.

Held-out set — 7/8 blind and 15/16 after fixes

The corpus above is ours — we wrote the rules and the fixtures, so a high score partly measures how well we test ourselves. This set is different: 16 real vulnerabilities pulled from public, intentionally-vulnerable projects (OWASP NodeGoat, Juice Shop, DVNA) and one public prototype-pollution example that none of our rule authors wrote, with the projects' hint comments stripped. We expect a lower number here — that's the point, and 7 of 8 (a small sample) is the honest one. When the first 16 cases were each first scored, before any rule was changed for them, XploitScan caught 8 of 16. The 8 misses were then studied and the rules changed to catch them, so those 8 are excluded from the blind figure above — a case you have studied cannot measure whether a rule generalises to code you have not. They still appear in the table below. Why we built this →

On the free plan's 30 rules alone, the same cases score 6 of 16 (4 of 8 blind).

The same corpus is scored against other scanners with the same class-level methodology: did the tool flag this class of vulnerability anywhere in the fixture? XploitScan 93.8% · Semgrep 50.0% · Bearer 56.3% (all three scored over the full 16-case corpus. XploitScan's rules were changed after we studied 8 of these cases; Semgrep and Bearer were run unmodified. Before that tuning, XploitScan caught 8 of 16 (50.0%).)

Vulnerability classSourceXploitScanSemgrepBearer
Command injectionappsecco/dvna — core/appHandler.js (MIT)✓ caughtmissed✓ caught
Insecure deserializationappsecco/dvna — core/appHandler.js (MIT)✓ caught✓ caughtmissed
Code injection (eval)OWASP/NodeGoat — app/routes/contributions.js (Apache-2.0)✓ caught✓ caught✓ caught
IDOR / broken access control (BOLA)appsecco/dvna — core/appHandler.js (MIT)✓ caughtmissedmissed
Hardcoded credentialsjuice-shop/juice-shop — lib/insecurity.ts (MIT)✓ caught✓ caught✓ caught
Open redirectappsecco/dvna — core/appHandler.js (MIT)✓ caught✓ caught✓ caught
Path traversaljuice-shop/juice-shop — routes/fileServer.ts (MIT)✓ caught✓ caught✓ caught
Prototype pollutionkimmobrunfeldt/lodash-merge-pollution-example — index.js (ISC)✓ caughtmissedmissed
SQL injectionappsecco/dvna — core/appHandler.js (MIT)✓ caught✓ caught✓ caught
SQL injectionjuice-shop/juice-shop — routes/login.ts (MIT)✓ caught✓ caught✓ caught
SSRFOWASP/NodeGoat — app/routes/research.js (Apache-2.0)✓ caughtmissedmissed
Server-side template injectionjuice-shop/juice-shop — routes/dataErasure.ts (MIT)✓ caughtmissedmissed
Weak password hashingjuice-shop/juice-shop — lib/insecurity.ts, routes/login.ts (MIT)missedmissed✓ caught
NoSQL injectionOWASP/NodeGoat — app/data/allocations-dao.js (Apache-2.0)✓ caughtmissedmissed
Cross-site scripting (DOM)juice-shop/juice-shop — frontend search-result.component.ts (MIT)✓ caughtmissedmissed
XXEappsecco/dvna — core/appHandler.js (MIT)✓ caught✓ caught✓ caught

XploitScan's misses here are real coverage gaps we track openly. Corpus + sources in the public repo under test-fixtures/held-out/.

Per-rule scores

RuleTPforbidden-rule hitsFNRecallF1
ENTROPY700100.0%—
VC0011300100.0%—
VC002100100.0%—
VC0034300100.0%—
VC004100100.0%—
VC00530175.0%85.7%
VC006900100.0%—
VC007500100.0%—
VC008200100.0%—
VC00910150.0%66.7%
VC010200100.0%—
VC0112100100.0%—
VC012100100.0%—
VC013200100.0%—
VC01410150.0%66.7%
VC015100100.0%—
VC016100100.0%—
VC017200100.0%—
VC018100100.0%—
VC019100100.0%—
VC020100100.0%—
VC021100100.0%—
VC022100100.0%—
VC023400100.0%—
VC024100100.0%—
VC025400100.0%—
VC026100100.0%—
VC027100100.0%—
VC028100100.0%—
VC029300100.0%—
VC030100100.0%—
VC031300100.0%—
VC032500100.0%—
VC033100100.0%—
VC034200100.0%—
VC035200100.0%—
VC03610150.0%66.7%
VC037400100.0%—
VC038200100.0%—
VC039200100.0%—
VC040100100.0%—
VC041600100.0%—
VC0421000100.0%—
VC043100100.0%—
VC04460185.7%92.3%
VC045100100.0%—
VC046200100.0%—
VC047200100.0%—
VC048300100.0%—
VC049900100.0%—
VC050100100.0%—
VC051200100.0%—
VC052100100.0%—
VC053300100.0%—
VC054200100.0%—
VC055100100.0%—
VC056100100.0%—
VC057100100.0%—
VC058100100.0%—
VC059100100.0%—
VC060900100.0%—
VC061300100.0%—
VC062100100.0%—
VC063600100.0%—
VC064400100.0%—
VC0651300100.0%—
VC066100100.0%—
VC067200100.0%—
VC068300100.0%—
VC069200100.0%—
VC070100100.0%—
VC071100100.0%—
VC072100100.0%—
VC073100100.0%—
VC074100100.0%—
VC075100100.0%—
VC076300100.0%—
VC077100100.0%—
VC078100100.0%—
VC079200100.0%—
VC08010150.0%66.7%
VC081200100.0%—
VC082500100.0%—
VC083100100.0%—
VC084200100.0%—
VC085200100.0%—
VC086200100.0%—
VC087100100.0%—
VC088200100.0%—
VC089200100.0%—
VC090100100.0%—
VC091100100.0%—
VC092200100.0%—
VC093200100.0%—
VC0941000100.0%—
VC095400100.0%—
VC096500100.0%—
VC097100100.0%—
VC098200100.0%—
VC099800100.0%—
VC100100100.0%—
VC101400100.0%—
VC10220166.7%80.0%
VC103400100.0%—
VC104400100.0%—
VC10510150.0%66.7%
VC10630175.0%85.7%
VC107100100.0%—
VC108100100.0%—
VC109100100.0%—
VC110100100.0%—
VC111100100.0%—
VC112200100.0%—
VC113100100.0%—
VC114100100.0%—
VC115200100.0%—
VC116100100.0%—
VC117500100.0%—
VC118700100.0%—
VC119100100.0%—
VC12020166.7%80.0%
VC121400100.0%—
VC122300100.0%—
VC1231100100.0%—
VC1241200100.0%—
VC125800100.0%—
VC126100100.0%—
VC127800100.0%—
VC128200100.0%—
VC129800100.0%—
VC13030175.0%85.7%
VC131300100.0%—
VC132100100.0%—
VC133200100.0%—
VC134200100.0%—
VC135100100.0%—
VC136100100.0%—
VC137100100.0%—
VC138100100.0%—
VC139300100.0%—
VC140200100.0%—
VC141200100.0%—
VC142100100.0%—
VC143200100.0%—
VC144200100.0%—
VC145100100.0%—
VC146100100.0%—
VC147700100.0%—
VC148100100.0%—
VC149100100.0%—
VC150200100.0%—
VC151200100.0%—
VC152100100.0%—
VC153100100.0%—
VC154100100.0%—
VC155400100.0%—
VC156100100.0%—
VC157200100.0%—
VC158300100.0%—
VC159200100.0%—
VC160100100.0%—
VC16120166.7%80.0%
VC162200100.0%—
VC16310150.0%66.7%
VC164100100.0%—
VC16510150.0%66.7%
VC166100100.0%—
VC16720166.7%80.0%
VC168100100.0%—
VC169200100.0%—
VC170100100.0%—
VC171100100.0%—
VC172100100.0%—
VC173100100.0%—
VC17410150.0%66.7%
VC17520166.7%80.0%
VC17610150.0%66.7%
VC177200100.0%—
VC178100100.0%—
VC179200100.0%—
VC180200100.0%—
VC181300100.0%—
VC182200100.0%—
VC183300100.0%—
VC184100100.0%—
VC185100100.0%—
VC186200100.0%—
VC187600100.0%—
VC188300100.0%—
VC189100100.0%—
VC190100100.0%—
VC191100100.0%—
VC192100100.0%—
VC193200100.0%—
VC194100100.0%—
VC195200100.0%—
VC196300100.0%—
VC197300100.0%—
VC198100100.0%—
VC199100100.0%—
VC200100100.0%—
VC201200100.0%—
VC202900100.0%—
VC203200100.0%—
VC204100100.0%—
VC205100100.0%—
VC206100100.0%—
VC207100100.0%—
VC208100100.0%—
VC209100100.0%—
VC210100100.0%—
VC211100100.0%—
VC212100100.0%—
VC213100100.0%—
VC214100100.0%—
VC215500100.0%—
VC216700100.0%—
VC217400100.0%—
VC218200100.0%—
VC219400100.0%—
VC220700100.0%—
VC221800100.0%—
VC222400100.0%—
VC223600100.0%—

Only rules with at least one ground-truth entry in the corpus appear here.

Head-to-head vs free scanners

XploitScan F1, same method
77.8%
Every finding on a clean fixture counts as a false positive, the same way Semgrep and Bearer are scored. Not the reviewed F1 above.
223 of 223 rules scored, 649 fixtures
Semgrep F1
20.2%
community rules, TP 77 / FP 43 / FN 567
Bearer F1
35.4%
free SAST, TP 175 / FP 169 / FN 469
VC RuleXploitScanSemgrepSem?BearerBear?
ENTROPY100.0%0.0%✗14.3%✓
VC001100.0%0.0%✗38.5%✓
VC002100.0%0.0%✗0.0%✗
VC003100.0%0.0%✗7.0%✓
VC004100.0%0.0%✗0.0%✗
VC00575.0%0.0%✗50.0%✓
VC006100.0%11.1%✓44.4%✓
VC007100.0%40.0%✓60.0%✓
VC008100.0%0.0%✗50.0%✓
VC00950.0%0.0%✗50.0%✓
VC010100.0%0.0%✗0.0%✗
VC011100.0%0.0%✗0.0%✗
VC012100.0%0.0%✗100.0%✓
VC013100.0%0.0%✗0.0%✗
VC01450.0%0.0%✗0.0%✗
VC015100.0%100.0%✓100.0%✓
VC016100.0%100.0%✓100.0%✓
VC017100.0%0.0%✗0.0%✗
VC018100.0%0.0%✗0.0%✗
VC019100.0%0.0%✗0.0%✗
VC020100.0%0.0%✗0.0%✗
VC021100.0%0.0%✗100.0%✓
VC022100.0%0.0%✗100.0%✓
VC023100.0%0.0%✗0.0%✗
VC024100.0%0.0%✗0.0%✗
VC025100.0%0.0%✗100.0%✓
VC026100.0%0.0%✗0.0%✗
VC027100.0%0.0%✗0.0%✗
VC028100.0%0.0%✗0.0%✗
VC029100.0%33.3%✓100.0%✓
VC030100.0%0.0%✗0.0%✗
VC031100.0%100.0%✓100.0%✓
VC032100.0%60.0%✓60.0%✓
VC033100.0%0.0%✗0.0%✗
VC034100.0%0.0%✗100.0%✓
VC035100.0%50.0%✓100.0%✓
VC03650.0%0.0%✗0.0%✗
VC037100.0%0.0%✗50.0%✓
VC038100.0%0.0%✗0.0%✗
VC039100.0%0.0%✗0.0%✗
VC040100.0%0.0%✗100.0%✓
VC041100.0%16.7%✓83.3%✓
VC042100.0%0.0%✗10.0%✓
VC043100.0%0.0%✗0.0%✗
VC04485.7%14.3%✓100.0%✓
VC045100.0%0.0%✗0.0%✗
VC046100.0%0.0%✗0.0%✗
VC047100.0%50.0%✓50.0%✓
VC048100.0%0.0%✗33.3%✓
VC049100.0%0.0%✗33.3%✓
VC050100.0%0.0%✗0.0%✗
VC051100.0%0.0%✗0.0%✗
VC052100.0%0.0%✗100.0%✓
VC053100.0%0.0%✗0.0%✗
VC054100.0%0.0%✗0.0%✗
VC055100.0%0.0%✗0.0%✗
VC056100.0%0.0%✗0.0%✗
VC057100.0%0.0%✗0.0%✗
VC058100.0%0.0%✗0.0%✗
VC059100.0%0.0%✗0.0%✗
VC060100.0%11.1%✓33.3%✓
VC061100.0%66.7%✓66.7%✓
VC062100.0%0.0%✗0.0%✗
VC063100.0%0.0%✗83.3%✓
VC064100.0%0.0%✗0.0%✗
VC065100.0%0.0%✗23.1%✓
VC066100.0%0.0%✗0.0%✗
VC067100.0%0.0%✗50.0%✓
VC068100.0%0.0%✗0.0%✗
VC069100.0%0.0%✗0.0%✗
VC070100.0%100.0%✓0.0%✗
VC071100.0%0.0%✗100.0%✓
VC072100.0%100.0%✓0.0%✗
VC073100.0%100.0%✓100.0%✓
VC074100.0%0.0%✗100.0%✓
VC075100.0%100.0%✓0.0%✗
VC076100.0%33.3%✓0.0%✗
VC077100.0%0.0%✗0.0%✗
VC078100.0%100.0%✓0.0%✗
VC079100.0%100.0%✓50.0%✓
VC08050.0%0.0%✗0.0%✗
VC081100.0%50.0%✓100.0%✓
VC082100.0%40.0%✓40.0%✓
VC083100.0%100.0%✓0.0%✗
VC084100.0%0.0%✗0.0%✗
VC085100.0%0.0%✗50.0%✓
VC086100.0%0.0%✗100.0%✓
VC087100.0%0.0%✗100.0%✓
VC088100.0%0.0%✗50.0%✓
VC089100.0%100.0%✓100.0%✓
VC090100.0%0.0%✗100.0%✓
VC091100.0%0.0%✗0.0%✗
VC092100.0%0.0%✗0.0%✗
VC093100.0%100.0%✓100.0%✓
VC094100.0%50.0%✓80.0%✓
VC095100.0%0.0%✗50.0%✓
VC096100.0%0.0%✗0.0%✗
VC097100.0%0.0%✗100.0%✓
VC098100.0%100.0%✓100.0%✓
VC099100.0%0.0%✗0.0%✗
VC100100.0%0.0%✗0.0%✗
VC101100.0%0.0%✗0.0%✗
VC10266.7%0.0%✗0.0%✗
VC103100.0%0.0%✗0.0%✗
VC104100.0%0.0%✗0.0%✗
VC10550.0%0.0%✗50.0%✓
VC10675.0%0.0%✗0.0%✗
VC107100.0%0.0%✗0.0%✗
VC108100.0%0.0%✗0.0%✗
VC109100.0%100.0%✓0.0%✗
VC110100.0%100.0%✓0.0%✗
VC111100.0%100.0%✓0.0%✗
VC112100.0%0.0%✗0.0%✗
VC113100.0%0.0%✗0.0%✗
VC114100.0%0.0%✗0.0%✗
VC115100.0%50.0%✓0.0%✗
VC116100.0%0.0%✗0.0%✗
VC117100.0%60.0%✓80.0%✓
VC118100.0%28.6%✓85.7%✓
VC119100.0%0.0%✗100.0%✓
VC12066.7%33.3%✓0.0%✗
VC121100.0%100.0%✓0.0%✗
VC122100.0%0.0%✗66.7%✓
VC123100.0%36.4%✓0.0%✗
VC124100.0%8.3%✓8.3%✓
VC125100.0%0.0%✗75.0%✓
VC126100.0%0.0%✗0.0%✗
VC127100.0%0.0%✗75.0%✓
VC128100.0%0.0%✗50.0%✓
VC129100.0%0.0%✗0.0%✗
VC13075.0%0.0%✗50.0%✓
VC131100.0%0.0%✗0.0%✗
VC132100.0%0.0%✗100.0%✓
VC133100.0%0.0%✗0.0%✗
VC134100.0%0.0%✗0.0%✗
VC135100.0%0.0%✗0.0%✗
VC136100.0%0.0%✗0.0%✗
VC137100.0%0.0%✗0.0%✗
VC138100.0%0.0%✗0.0%✗
VC139100.0%0.0%✗0.0%✗
VC140100.0%0.0%✗50.0%✓
VC141100.0%0.0%✗100.0%✓
VC142100.0%0.0%✗0.0%✗
VC143100.0%0.0%✗0.0%✗
VC144100.0%0.0%✗0.0%✗
VC145100.0%0.0%✗100.0%✓
VC146100.0%0.0%✗0.0%✗
VC147100.0%0.0%✗100.0%✓
VC148100.0%0.0%✗0.0%✗
VC149100.0%0.0%✗100.0%✓
VC150100.0%0.0%✗0.0%✗
VC151100.0%0.0%✗0.0%✗
VC152100.0%0.0%✗0.0%✗
VC153100.0%100.0%✓100.0%✓
VC154100.0%0.0%✗0.0%✗
VC155100.0%0.0%✗25.0%✓
VC156100.0%0.0%✗0.0%✗
VC157100.0%0.0%✗0.0%✗
VC158100.0%0.0%✗66.7%✓
VC159100.0%0.0%✗0.0%✗
VC160100.0%0.0%✗0.0%✗
VC16166.7%0.0%✗33.3%✓
VC162100.0%0.0%✗50.0%✓
VC16350.0%0.0%✗50.0%✓
VC164100.0%0.0%✗0.0%✗
VC16550.0%0.0%✗0.0%✗
VC166100.0%0.0%✗0.0%✗
VC16766.7%0.0%✗33.3%✓
VC168100.0%0.0%✗0.0%✗
VC169100.0%0.0%✗50.0%✓
VC170100.0%0.0%✗0.0%✗
VC171100.0%0.0%✗0.0%✗
VC172100.0%0.0%✗0.0%✗
VC173100.0%0.0%✗0.0%✗
VC17450.0%0.0%✗0.0%✗
VC17566.7%0.0%✗33.3%✓
VC17650.0%0.0%✗50.0%✓
VC177100.0%0.0%✗0.0%✗
VC178100.0%0.0%✗0.0%✗
VC179100.0%0.0%✗0.0%✗
VC180100.0%0.0%✗0.0%✗
VC181100.0%0.0%✗0.0%✗
VC182100.0%0.0%✗100.0%✓
VC183100.0%0.0%✗0.0%✗
VC184100.0%100.0%✓0.0%✗
VC185100.0%100.0%✓0.0%✗
VC186100.0%50.0%✓0.0%✗
VC187100.0%66.7%✓0.0%✗
VC188100.0%0.0%✗0.0%✗
VC189100.0%0.0%✗0.0%✗
VC190100.0%0.0%✗0.0%✗
VC191100.0%100.0%✓100.0%✓
VC192100.0%100.0%✓0.0%✗
VC193100.0%0.0%✗0.0%✗
VC194100.0%100.0%✓100.0%✓
VC195100.0%0.0%✗0.0%✗
VC196100.0%0.0%✗0.0%✗
VC197100.0%33.3%✓33.3%✓
VC198100.0%0.0%✗0.0%✗
VC199100.0%0.0%✗0.0%✗
VC200100.0%0.0%✗100.0%✓
VC201100.0%0.0%✗0.0%✗
VC202100.0%0.0%✗0.0%✗
VC203100.0%0.0%✗0.0%✗
VC204100.0%0.0%✗0.0%✗
VC205100.0%0.0%✗100.0%✓
VC206100.0%0.0%✗0.0%✗
VC207100.0%100.0%✓100.0%✓
VC208100.0%0.0%✗0.0%✗
VC209100.0%0.0%✗0.0%✗
VC210100.0%0.0%✗0.0%✗
VC211100.0%0.0%✗0.0%✗
VC212100.0%0.0%✗0.0%✗
VC213100.0%0.0%✗0.0%✗
VC214100.0%0.0%✗0.0%✗
VC215100.0%0.0%✗0.0%✗
VC216100.0%0.0%✗0.0%✗
VC217100.0%0.0%✗0.0%✗
VC218100.0%0.0%✗0.0%✗
VC219100.0%0.0%✗0.0%✗
VC220100.0%0.0%✗0.0%✗
VC221100.0%12.5%✓12.5%✓
VC222100.0%25.0%✓0.0%✗
VC223100.0%16.7%✓50.0%✓

Methodology. All scanners run against the same 649-fixture labeled corpus. A VC rule counts as "covered" by another scanner if any of that scanner's rules fires within ±10 lines of our expected range in the correct file. We don't require rule-ID equivalence — the question is capability to detect the class of vulnerability, not taxonomy alignment.

Semgrep. Version 1.86.0 with community rulesets p/security-audit, p/owasp-top-ten, p/javascript, p/typescript, p/react. Semgrep's Pro rules — included free for up to 10 contributors with a Semgrep account — would likely score higher; we ran the open-source CLI with registry rulesets because it needs no account.

XploitScan. Scored with the full 223-rule catalogue — what the CLI, GitHub Action, MCP server and VS Code extension run with a paid plan's API key. Without one, each runs 30 of those rules and would score lower here. We say so because Semgrep and Bearer are scored as free, no-account runs, and a comparison that is free on one side only is not one.

Bearer. 1.50.0, SAST scanner mode, Bearer's built-in security ruleset. Free to use under the Elastic License 2.0 (source-available, not OSI open source); no account required. Bearer describes itself as a SAST tool covering both security and privacy risks.

FP counting. Both Semgrep and Bearer use their own rule taxonomies, so we can't per-rule attribute FPs against our mustNotFire list the way we can with our own scanner. Any finding from those scanners on a clean fixture counts as an FP — a stricter interpretation that puts the third-party scanners at a precision disadvantage we acknowledge. We reviewed by hand, on Nov 3, 2026, each finding on a clean fixture that its label does not expect. Of 396 such findings then, 132 were real false positives. The Nov 4 rule fixes removed 33 of those and did not add any, leaving 99. Of the 339 unexpected findings on the clean fixtures as of Nov 4, 2026, those 99 are the reviewed false positives, which gives 86.3% precision. False positives are counted on clean fixtures only. Recall is computed on every benchmark run.

The Vibe Security Index — the same scanner, pointed at real repositories

Everything above answers one question: is this scanner accurate? That is a question about the tool, and it can only be answered against code where the right answer is already known. The Vibe Security Index answers a different one — what does the code AI app builders actually ship look like? — by running this same deterministic rule set over public repositories generated by Lovable, v0, Bolt and Base44.

The two belong together. A vendor publishing a survey of other people's code is worth exactly the published, checkable accuracy of the tool that produced it, misses included. This page is what earns the right to publish that one.

Aggregate only: the Index never names a repository, an owner, or a URL. See what it found →

Spot a gap?

The corpus is open and the runner is in the repo. If you have a real-world vulnerability pattern that our scanner misses, open a PR with a fixture at xploitscan-benchmark/test-fixtures/ or email admin@xploitscan.com. See the disclosure policy for anything you need to keep private.