Flagged on Both Sides: A Paired Before/After Evaluation of Open-Source Static Application Security Testing on Real Vulnerability Fixes

Static application security testing (SAST) tools are scored on synthetic suites, where a vulnerable test case faces an independent safe one. Real vulnerabilities offer a sharper control: the same file after its fix. We build PairCVE, 6,427 before/after file pairs from 4,459 GitHub-reviewed OSV advisories in PyPI, npm, Go, Maven and RubyGems, and score Semgrep CE, CodeQL, Bandit and gosec in seven configurations. A pair counts as detected only when a tool flags the vulnerable file for its weakness class, not the fixed file. Per-file recall ranges from 4.6% to 19.2% (the 19.2% ceiling, gosec, is the least reliable configuration), but for every configuration a majority of the flagged vulnerable files (55-96%) are flagged again after the fix, so paired detection is only 0.9-3.3%. The gap is largest where a rule matches a code pattern the fix does not remove: per-file recall cannot separate a flow-sensitive detection from an intentional pattern match, and the paired view does. Where the fix instead rewrites a sink call (9.9% of pairs), paired detection rises -- Semgrep to 15.6%. Two controls isolate the effect: on the OWASP Benchmark under identical isolation Youden's J exceeds the pairwise J in all 10 tool-suite combinations (sign test p=0.002); whole-repository CodeQL significantly raises recall (recall McNemar p=0.016) but does not change the surviving share (56% and 56%). We argue that per-file recall on real code must be read against its pairwise counterpart, and we release the corpus and code. Files. flagged-on-both-sides.en.pdf (paper, English) · flagged-on-both-sides.fr.pdf (French translation) · flagged-on-both-sides-artifact.zip (reproduction artifact: corpus manifest of 6,427 pairs, scanning and scoring code, pinned tool versions, raw analyzer findings, scores). Reproduce. Unzip the artifact, then run bash flagged-on-both-sides-artifact/experiments/verify_offline.sh. It regenerates every number in the paper from the released scores and fails on any drift (no network, no source files). Source files are not redistributed; the manifest's commit SHAs and SHA-256 hashes let anyone rebuild them from public git history.

Authors

Publication Details

Journal
Zenodo (CERN European Organization for Nuclear Research)
Published
2026-10-13
DOI
https://doi.org/10.5281/zenodo.23354215
Primary Topic
Web Application Security Vulnerabilities
Type
preprint
Controls
|||
ALL TIME
JAN
FEB
MAR
APR
MAY
JUN
JUL
AUG
SEP
OCT
preprint

Flagged on Both Sides: A Paired Before/After Evaluation of Open-Source Static Application Security Testing on Real Vulnerability Fixes

Jean-François Bouchard
Zenodo (CERN European Organization for Nuclear Research)
Web Application Security Vulnerabilities
preprint

Flagged on Both Sides: A Paired Before/After Evaluation of Open-Source Static Application Security Testing on Real Vulnerability Fixes

Jean-François Bouchard
preprint en

Abstract

Static application security testing (SAST) tools are scored on synthetic suites, where a vulnerable test case faces an independent safe one. Real vulnerabilities offer a sharper control: the same file after its fix. We build PairCVE, 6,427 before/after file pairs from 4,459 GitHub-reviewed OSV advisories in PyPI, npm, Go, Maven and RubyGems, and score Semgrep CE, CodeQL, Bandit and gosec in seven configurations. A pair counts as detected only when a tool flags the vulnerable file for its weakness class, not the fixed file. Per-file recall ranges from 4.6% to 19.2% (the 19.2% ceiling, gosec, is the least reliable configuration), but for every configuration a majority of the flagged vulnerable files (55-96%) are flagged again after the fix, so paired detection is only 0.9-3.3%. The gap is largest where a rule matches a code pattern the fix does not remove: per-file recall cannot separate a flow-sensitive detection from an intentional pattern match, and the paired view does. Where the fix instead rewrites a sink call (9.9% of pairs), paired detection rises -- Semgrep to 15.6%. Two controls isolate the effect: on the OWASP Benchmark under identical isolation Youden's J exceeds the pairwise J in all 10 tool-suite combinations (sign test p=0.002); whole-repository CodeQL significantly raises recall (recall McNemar p=0.016) but does not change the surviving share (56% and 56%). We argue that per-file recall on real code must be read against its pairwise counterpart, and we release the corpus and code. Files. flagged-on-both-sides.en.pdf (paper, English) · flagged-on-both-sides.fr.pdf (French translation) · flagged-on-both-sides-artifact.zip (reproduction artifact: corpus manifest of 6,427 pairs, scanning and scoring code, pinned tool versions, raw analyzer findings, scores). Reproduce. Unzip the artifact, then run bash flagged-on-both-sides-artifact/experiments/verify_offline.sh. It regenerates every number in the paper from the released scores and fails on any drift (no network, no source files). Source files are not redistributed; the manifest's commit SHAs and SHA-256 hashes let anyone rebuild them from public git history.

Zenodo (CERN European Organization for Nuclear Research)
Web Application Security Vulnerabilities
AI Navigator

Ask Laika to Summarize, Analyze, and Connect papers live on the map.

Summarize Papers & Methodologies

Extract key findings, datasets, and comparative methods across publications.

Benchmark Rankings & Visual Analytics

Rank top research institutions, authors, funders, topics, and journals by Field-Weighted Citation Impact (FWCI) and paper volume with instant charts.

Connect Distant Disciplines

Bridge topological clusters on the map to find hidden collaborative intersections.