Zennoxa Shield

Advisory Growth vs. Tooling Coverage: The Capacity Gap Is a Flow, Not Just a Stock

We bucketed every OSV.dev advisory by its record-publication year for 11 package ecosystems and overlaid the count of catalogued open-source security tools per language. Known-vulnerability advisories entering the public record grew 2.3x-6.6x over five years for most ecosystems, and recent years add hundreds to thousands per ecosystem against 2-13 open-source tools — up to 157 new advisories per tool per year for Rust. A reproducible measure of whether tooling capacity keeps pace with advisory inflow.

July 28, 2026By Zennoxa Researchscadependenciesosvvulnerability-managementprioritizationappsecdevsecops

TL;DR — We bucketed every advisory in OSV.dev's public per-ecosystem archives by its record-publication year for 11 package ecosystems, split out malicious-package (MAL-) reports, and overlaid the count of open-source, security-tagged tools per language from the analysis-tools.dev catalog. Two things: known-vulnerability advisories entering the public record grew 2.3×–6.6× over five years for most ecosystems (PHP 6.6×, Java 4.8×, .NET 4.2×, Rust 3.0×, Python 2.3×), while the open-source tool count per language is roughly flat. And the gap is a flow: recent years (2023–2025 average) add hundreds to thousands of new advisories per ecosystem — up to 157 new advisories per open-source tool per year for Rust, 121 for PHP, 112 for Go — against 2–13 tools. ~4,900 new vulnerability advisories land per year across these 11 ecosystems, served by 42 catalogued open-source security tools. Every number is recomputable from the public archives. (Important caveat: OSV published is a record-entry date, so this measures publication velocity, not vulnerability incidence — read the method.)

Why measure this

Defenders have finite triage capacity. Our companion study, The SCA Coverage Gap, measured the stock — total advisories per open-source tool per ecosystem. This one measures the flow: how fast advisories enter the record each year, and whether the pool of open-source tools that covers a language keeps pace. If yearly inflow keeps climbing while tool count stays flat, teams face more signal per tool and per human-hour every year — which is a structural argument for triage (ranking what to fix first) over simply scanning more. We don't assert the direction in advance; we publish the computation and let the curves speak.

Method — and the one caveat that matters

For each ecosystem we download OSV's all.zip, read every advisory's published RFC3339 date, bucket by 4-digit year, and exclude MAL- (malicious-package) advisories so the curve tracks vulnerable-dependency advisories, not malware reports. Tool counts are the open-source, security-tagged tools per mapped language from the catalog (same method as the stock study).

The caveat, stated up front, not buried: OSV's published field is when an advisory entered the record, not when the vulnerability was introduced or even first disclosed. So this measures advisory-publication velocity, not vulnerability incidence. Bulk imports show up as spikes — e.g. a log4j-era Java backfill in 2022, and a large 2026 ingestion across several ecosystems. We therefore lead with complete years (through 2025) and mark 2026 as partial, and we use a 2023–2025 average for the "recent flow" figures rather than any single spiky year.

Growth: advisories entering the record per year

Known-vulnerability advisories (malware excluded), by publication year:

Ecosystem (language) 2020 2021 2022 2023 2024 2025 2026* Growth (2023-25 vs 2019-20)
Packagist (PHP) 156 430 2,326 771 1,063 712 1,255 6.6×
Maven (Java) 151 394 3,009 951 565 711 666 4.8×
NuGet (.NET) 15 103 313 72 106 103 311 4.2×
crates.io (Rust) 168 487 339 260 321 363 649 3.0×
PyPI (Python) 469 1,417 1,878 849 1,020 1,010 5,162 2.3×
RubyGems (Ruby) 57 71 238 91 103 67 159 1.5×
npm (JavaScript) 934 597 669 400 436 632 2,610 0.8×
Go 0 375 927 639 1,961 1,425 3,250 — (DB since 2021)

*2026 is a partial year and is inflated by an OSV ingestion wave; it is shown for transparency, not trend. Pub/Hex/Swift omitted from the growth table (their OSV histories start ~2022 with small counts).

npm is the honest exception: its vulnerability-advisory flow is flat-to-declining (0.8×) — but that's because npm's explosive growth is in malicious-package reports, which we excluded. Counting malware, npm's raw advisory volume dwarfs everything (223,802 total, 96.9% MAL-); counting real vulnerable-dependency advisories, it isn't even growing.

The flow gap: new advisories per open-source tool, per year

Recent-years (2023–2025) average new advisories per year, against catalogued open-source tools:

Ecosystem (language) New advisories / yr (2023-25 avg) Open-source tools New advisories / tool / yr
crates.io (Rust) 315 2 157
Packagist (PHP) 849 7 121
Go 1,342 12 112
Maven (Java) 742 10 74
PyPI (Python) 960 13 74
npm (JavaScript) 489 10 49
NuGet (.NET) 94 7 13
RubyGems (Ruby) 87 8 11
Pub (Dart) 3 0 no OSS tool
Hex (Elixir) 8 0 no OSS tool

Across the 11 ecosystems, ~4,900 new vulnerability advisories enter the record per year, against 42 catalogued open-source security tools.

What the numbers say

  • Advisory publication grew multi-fold for most ecosystems over five years — 6.6× (PHP), 4.8× (Java), 4.2× (.NET), 3.0× (Rust), 2.3× (Python). The record is getting denser, not sparser.
  • Tool count per language is flat — it's a property of the catalog, not a curve that rises with advisory volume — so the inflow per tool rises with the advisory curve.
  • The thinnest-covered ecosystems face the steepest flow: Rust adds ~157 new advisories per open-source tool per year, PHP ~121, Go ~112 — the same ecosystems the stock study flagged as deserts.
  • Malware vs. vulnerabilities are different stories: npm's real-vulnerability flow is flat once MAL- reports are excluded, even though its raw total is the largest by far.

How this ties to prioritization (category-level, honest)

Neutral, public backdrop — not a product claim. But it's the evidence for a precondition: when the volume of security signal grows faster than the capacity to act on it, the scalable response is prioritization — ranking by exploitation likelihood (EPSS, CISA KEV) and reachability — rather than adding raw scan volume. The reader draws that conclusion from the public curves; it isn't baked into the data. And it's the same reproducibility discipline we hold ourselves to: this whole computation reruns from a pinned OSV snapshot and catalog commit, the way every Shield number reruns from a benchmark.json.

Limitations & honest caveats

  • Publication velocity ≠ incidence. OSV published is a record-entry date; bulk imports create spikes (2022 Java, 2026 across several ecosystems). We lead with complete years and a 2023–2025 average for exactly this reason.
  • Tool counts reflect catalog coverage, not capability — recall or precision of any tool is out of scope, and commercial tools aren't counted (this measures catalogued open-source capacity).
  • MAL- split is OSV's own prefix; we exclude malware reports from the vulnerability curves and say so.
  • OSV all.zip archives can lag the per-object listing (OSV issue #2575), but the large gaps are in OS/distro ecosystems, which this study excludes; the language package ecosystems reconcile cleanly.

Reproduce it yourself

for eco in npm PyPI Maven Go RubyGems crates.io NuGet Packagist Pub Hex SwiftURL; do
  curl -s "https://osv-vulnerabilities.storage.googleapis.com/$eco/all.zip" -o e.zip
  echo "== $eco (vulnerability advisories by year, MAL- excluded) =="
  unzip -p e.zip -x '*MAL-*' | grep -aoE '"published"[[:space:]]*:[[:space:]]*"[0-9]{4}' \
    | grep -oE '[0-9]{4}$' | sort | uniq -c
  rm e.zip
done

OSV data is public (per-source CC-BY-4.0 / CC0 / MIT / Apache-2.0 — attribution to OSV.dev and the underlying advisory databases); the analysis-tools.dev catalog is MIT. No scanner is named or scored — the tool axis is an aggregate per-language count.

FAQ

Is vulnerability incidence actually rising, or just OSV's coverage? This measures the record — advisories entering OSV per year. Growing coverage is part of the signal (more of the ecosystem is now catalogued), and that's exactly what a defender's triage queue sees. We flag the distinction rather than claim underlying incidence.

Why is npm's curve flat when everyone says npm is the most dangerous? npm's raw OSV total is huge, but 96.9% are malicious-package (MAL-) reports. Its real vulnerable-dependency advisory flow, which this study isolates, is flat-to-declining.

Where does Shield fit? It doesn't drive the study — the point is category-level: advisory inflow outpaces catalogued open-source tooling per language, which is the case for prioritizing by exploitability over scanning more.

Advisory Growth vs. Tooling Coverage: The Capacity Gap Is a Flow, Not Just a Stock — Zennoxa Shield