By raw count, JavaScript's npm ecosystem has the most reviewed security advisories in the GitHub Advisory Database: 7,939 of 37,118 on 23 October 2026. Divide by the number of packages in each registry and the ranking flips. PHP's Composer and Java's Maven lead, and npm drops to last of the eight big ecosystems.
The language itself is rarely the cause. Ecosystem size, age, the kind of software people publish in it, and how much security research it attracts explain most of the gap. This post puts the raw numbers next to three normalised views (per 1,000 packages, per unit of developer share, and per billion downloads), then splits the counts by weakness family. It also explains why C and C++ barely appear in package advisory databases while they dominate memory safety statistics everywhere else, and what a team with several languages in production should measure instead.
Key takeaways
- Raw leader: npm has 7,939 reviewed advisories, ahead of Maven (7,193), pip (6,662) and Composer (6,581), per the GitHub Advisory Database on 23 October 2026.
- Per 1,000 packages the order inverts: Composer 12.55, Maven 9.84, pip 7.06, RubyGems 5.44, Rust 4.41, Go 1.97, NuGet 1.36, npm 1.32.
- Per point of developer share (Stack Overflow 2025), Composer and Go lead and NuGet is lowest. Per download, npm is the lowest we could compute.
- Weakness mix differs more than counts do. Cross site scripting is 31.2% of Composer advisories. Prototype pollution (565) and ReDoS (204) are npm signatures; deserialisation (414) is a Maven one.
- C and C++ have no central registry, so package databases barely see them, yet Chromium reports around 70% of its serious security bugs since 2015 were memory safety problems.
- Volume is surging. GitHub reviewed a record 1,560 advisories in May 2026 and says some reviews took "multiple weeks".
- Counts are not risk. What matters is which advisories hit what you ship, whether the vulnerable code is reachable, and how fast you deploy the fix.
Which language ecosystem has the most reviewed advisories today?
The GitHub Advisory Database is the most widely used open dataset of package level vulnerabilities. It holds two kinds of record. "GitHub reviewed" advisories have been checked by a curator who mapped the issue to a specific package in a supported registry, confirmed affected and fixed version ranges, and validated the classification. "Unreviewed" advisories are mostly imported CVE records that GitHub has not mapped to a package, often because they do not concern a supported package ecosystem at all.
On 23 October 2026 the database listed 37,118 reviewed advisories and 357,187 unreviewed ones. Only reviewed advisories carry reliable package and version data, so every count below uses the reviewed set.
Table 1: Reviewed advisories by ecosystem, raw counts
| Ecosystem (registry) | Main language | Reviewed advisories, 23 Oct 2026 | Share of ecosystem sum |
|---|---|---|---|
| npm | JavaScript, TypeScript | 7,939 | 21.3% |
| Maven (Maven Central) | Java, Kotlin, Scala | 7,193 | 19.3% |
| pip (PyPI) | Python | 6,662 | 17.8% |
| Composer (Packagist) | PHP | 6,581 | 17.6% |
| Go (Go modules) | Go | 5,017 | 13.4% |
| Rust (crates.io) | Rust | 1,603 | 4.3% |
| NuGet | C#, F#, .NET | 1,186 | 3.2% |
| RubyGems | Ruby | 1,162 | 3.1% |
| Swift | Swift | 64 | under 0.2% |
| GitHub Actions | YAML workflows | 56 | under 0.2% |
| Erlang (Hex) | Erlang, Elixir | 122 | 0.3% |
| Pub | Dart | 14 | under 0.1% |
Source: GitHub Advisory Database, ecosystem filter counts read on 23 October 2026. The eight main ecosystems sum to 37,343, which is more than the 37,118 total, because one advisory can affect packages in more than one ecosystem. Shares are of the eight ecosystem sum.
Read at face value, this table says JavaScript is the most vulnerable language, Java and Python close behind, and Ruby and C# comparatively safe. That reading is wrong, or at least unsupported, for reasons the next three sections make concrete.
How do the numbers change once divided by registry size?
The first problem with raw counts is that the registries are wildly different sizes. npm hosts more than six million packages. RubyGems hosts about 213,000. A registry with 28 times more packages will collect more advisories even if each package is no more likely to have one.
We took package counts from ecosyste.ms, an open project that indexes every major registry with one method, on 23 October 2026.
Table 2: Advisories per 1,000 packages
| Ecosystem | Packages (ecosyste.ms, 23 Oct 2026) | Reviewed advisories | Advisories per 1,000 packages | Raw rank | Normalised rank |
|---|---|---|---|---|---|
| Composer | 524,487 | 6,581 | 12.55 | 4 | 1 |
| Maven | 730,975 | 7,193 | 9.84 | 2 | 2 |
| pip | 944,170 | 6,662 | 7.06 | 3 | 3 |
| RubyGems | 213,489 | 1,162 | 5.44 | 8 | 4 |
| Rust | 363,572 | 1,603 | 4.41 | 6 | 5 |
| Go | 2,541,048 | 5,017 | 1.97 | 5 | 6 |
| NuGet | 871,218 | 1,186 | 1.36 | 7 | 7 |
| npm | 6,001,436 | 7,939 | 1.32 | 1 | 8 |
Sources: ecosyste.ms packages and GitHub Advisory Database, both read 23 October 2026.
Three things stand out.
npm drops from first to last. Its registry is enormous and a large fraction of it is tiny, single purpose, abandoned or experimental packages that nobody audits and nobody reports bugs against. The denominator inflates faster than the numerator.
RubyGems jumps from eighth to fourth. It is a small, mature registry where much of the published code is web framework infrastructure that has been studied for two decades.
Composer and Maven lead on both views. Both ecosystems are dominated by server side web and enterprise software, which is exactly the code that researchers, bug bounty hunters and scanners spend the most time on.
The denominator is not settled either
Registry sizes disagree depending on who counts. On the same day, packagist.org's own statistics page reported 475,338 registered packages, while ecosyste.ms counted 524,487 for Packagist. crates.io's own API reported 359,402 crates against 363,572 on ecosyste.ms. The differences come from whether removed, abandoned or spam packages are included and when the index last refreshed.
Using Packagist's own figure, Composer's ratio rises from 12.55 to 13.84 advisories per 1,000 packages. The rank does not change, but any precise "per package" number you publish should name its denominator source and date.
Go is the hardest case. Go has no central registry. ecosyste.ms counts module paths seen by the Go module proxy, which includes forks and personal repositories that would never be published as packages in npm or PyPI. That likely understates Go's per package ratio compared with the others.
Advisories per vulnerable package: concentration
A second normalisation looks inward rather than at the whole registry. GitHub's June 2025 "by the numbers" post listed, for each ecosystem, both the number of advisories and the number of distinct packages those advisories affected. Dividing one by the other shows how concentrated each ecosystem's advisories are.
| Ecosystem | Advisories (GitHub table, 2025) | Vulnerable packages | Advisories per vulnerable package |
|---|---|---|---|
| Maven | 5,171 | 955 | 5.41 |
| Composer | 4,238 | 812 | 5.22 |
| pip | 3,378 | 1,044 | 3.24 |
| Go | 2,011 | 865 | 2.32 |
| RubyGems | 840 | 371 | 2.26 |
| Rust | 857 | 553 | 1.55 |
| npm | 3,653 | 2,652 | 1.38 |
| NuGet | 651 | 489 | 1.33 |
Source: GitHub blog, GitHub Advisory Database by the numbers, published 27 June 2025 and updated 4 February 2026.
Maven and Composer advisories cluster in a relatively small set of large, heavily used packages: frameworks, content management systems, application servers. npm's advisories are spread across many packages with one or two advisories each. That difference matters more to a security programme than the totals do. If your Java estate pulls in one of the heavily advised frameworks, you will see a steady stream of advisories against that one dependency. Our earlier note on how a few packages carry most advisories covers this concentration in more detail.
How do they change once weighted by how many developers use the language?
Registry size measures supply. Developer share measures demand: how many people write and ship code in that language, and therefore how many applications pull in its packages. There is no perfect measure of developer share. We used two.
Weighting by the Stack Overflow 2025 survey
The Stack Overflow 2025 Developer Survey asked which languages respondents had used extensively in the past year; 31,771 people answered. We mapped each ecosystem to its main language and divided reviewed advisories by the percentage of respondents using it.
| Ecosystem | Language used for weighting | Respondents using it (2025) | Advisories per percentage point of use |
|---|---|---|---|
| Composer | PHP | 18.9% | 348.2 |
| Go | Go | 16.4% | 305.9 |
| Maven | Java | 29.4% | 244.7 |
| RubyGems | Ruby | 6.4% | 181.6 |
| npm | JavaScript | 66.0% | 120.3 |
| pip | Python | 57.9% | 115.1 |
| Rust | Rust | 14.8% | 108.3 |
| NuGet | C# | 27.8% | 42.7 |
Sources: Stack Overflow 2025 Developer Survey, technology section (all respondents) and the GitHub Advisory Database counts above.
PHP and Go carry the most advisories relative to how many developers use them. JavaScript and Python, the two most used languages, fall to the middle. C# carries remarkably few for a language used by more than a quarter of respondents. The caveats are large:
- Maven also serves Kotlin and Scala. Adding Kotlin's 10.8% to Java's 29.4% drops Maven's figure from 244.7 to 178.9, below RubyGems.
- npm also serves TypeScript (43.6% of respondents), but most TypeScript users also use JavaScript, so the two cannot simply be added.
- Much .NET development relies on libraries shipped with the framework. Their vulnerabilities are platform CVEs, not NuGet advisories.
- Survey respondents are self selected.
Weighting by GitHub contributors
GitHub's Octoverse 2025 report, published 28 October 2025, gives exact monthly contributor counts for only a few languages. In August 2025 TypeScript had 2,636,006 monthly contributors on GitHub, up 66.63% year on year. Python had about 2.6 million and JavaScript about 2.15 million.
That is enough for one comparison. npm serves both TypeScript and JavaScript, roughly 4.8 million monthly contributors before removing overlap, against 7,939 advisories: about 1.7 advisories per 1,000 contributors. PyPI serves Python's 2.6 million contributors with 6,662 advisories: about 2.6 per 1,000. On this measure Python carries more advisories per active developer than JavaScript does, the reverse of the raw count. Octoverse does not publish comparable contributor figures for Go, PHP, Rust or Ruby, so we could not extend the comparison.
Per download: how much of the world's install traffic carries an advisory?
A third normalisation is consumption. Download statistics are the least consistent data in this post, because each registry publishes a different window and some publish nothing.
| Ecosystem | Download figure | Window | Reviewed advisories | Advisories per billion downloads |
|---|---|---|---|---|
| npm | 7,346,470,248,287 | 19 Oct 2025 to 18 Oct 2026 | 7,939 | 1.08 (annual) |
| NuGet | 45,147,255,521 in 6 weeks, about 391 billion annualised | 7 Sep to 19 Oct 2026 | 1,186 | 3.03 (annualised) |
| Rust (crates.io) | 506,164,233,979 | lifetime | 1,603 | 3.17 (lifetime) |
| RubyGems | 272,455,979,572 | lifetime | 1,162 | 4.26 (lifetime) |
| Composer (Packagist) | 207,628,936,283 | lifetime, since 13 Apr 2012 | 6,581 | 31.70 (lifetime) |
| pip, Maven, Go | not published in a comparable form | n/a | n/a | not computed |
Sources: npm downloads API, NuGet statistics, crates.io summary API, RubyGems.org, Packagist statistics, all read 23 October 2026.
Do not rank across windows: annual and lifetime figures are not comparable, and lifetime figures favour old registries. Within each window the direction matches the per package view. npm sits at the bottom because its install volume is enormous; Composer sits at the top. Every figure includes CI systems, mirrors and caches re-fetching the same package, so none is a count of real users.
The ranked view: one table, four orderings
The point of normalising is not to find the "true" ranking. It is to show that the ranking depends entirely on the question you ask.
Ranked: advisories per 1,000 packages, 23 October 2026
| Rank | Ecosystem | Per 1,000 packages | Bar |
|---|---|---|---|
| 1 | Composer (PHP) | 12.55 | ████████████▌ |
| 2 | Maven (Java) | 9.84 | ██████████ |
| 3 | pip (Python) | 7.06 | ███████ |
| 4 | RubyGems (Ruby) | 5.44 | █████▌ |
| 5 | Rust (crates.io) | 4.41 | ████▌ |
| 6 | Go | 1.97 | ██ |
| 7 | NuGet (.NET) | 1.36 | █▌ |
| 8 | npm (JavaScript) | 1.32 | █▌ |
How each ecosystem moves across the four views
| Ecosystem | Raw count rank | Per 1,000 packages | Per developer share point | Advisories per vulnerable package (2025) |
|---|---|---|---|---|
| npm | 1 | 8 | 5 | 7 |
| Maven | 2 | 2 | 3 | 1 |
| pip | 3 | 3 | 6 | 3 |
| Composer | 4 | 1 | 1 | 2 |
| Go | 5 | 6 | 2 | 4 |
| Rust | 6 | 5 | 7 | 6 |
| NuGet | 7 | 7 | 8 | 8 |
| RubyGems | 8 | 4 | 4 | 5 |
Only Composer and Maven stay near the top under every view, and only NuGet stays near the bottom. Everything else moves by three to seven places depending on the denominator. Anyone who quotes a single "most vulnerable language" figure without its denominator is quoting their method, not a fact about the language.
Which weakness families dominate per language?
Counts hide the more useful signal: what kind of bug each ecosystem tends to produce. The GitHub Advisory Database tags most reviewed advisories with one or more CWE identifiers, and its search supports filtering by ecosystem and CWE together. We ran those searches on 23 October 2026.
Table 3: Signature weakness families by ecosystem
| Ecosystem | Weakness (CWE) | Reviewed advisories | Share of that ecosystem's advisories |
|---|---|---|---|
| Composer | Cross site scripting (CWE-79) | 2,056 | 31.2% |
| Composer | SQL injection (CWE-89) | 365 | 5.5% |
| Maven | Cross site scripting (CWE-79) | 972 | 13.5% |
| Maven | Deserialisation of untrusted data (CWE-502) | 414 | 5.8% |
| npm | Cross site scripting (CWE-79) | 938 | 11.8% |
| npm | Prototype pollution (CWE-1321) | 565 | 7.1% |
| npm | Inefficient regular expression, ReDoS (CWE-1333) | 204 | 2.6% |
| pip | Path traversal (CWE-22) | 536 | 8.0% |
| pip | Out of bounds write (CWE-787) | 141 | 2.1% |
| Go | Uncontrolled resource consumption (CWE-400) | 276 | 5.5% |
| Rust | Use after free (CWE-416) | 72 | 4.5% |
| Rust | Out of bounds write (CWE-787) | 60 | 3.7% |
Source: GitHub Advisory Database searches such as type:reviewed ecosystem:npm cwe:1321, 23 October 2026. One advisory can carry several CWEs, so shares do not add up to 100%.
An independent analysis of the reviewed set by Aquia, which cloned the advisory database and counted CWEs per ecosystem, found a similar shape at an earlier date. Its top three per ecosystem were XSS, deserialisation and CSRF for Maven; XSS, sensitive information exposure and SQL injection for Packagist; input validation, XSS and out of bounds read for PyPI; race condition, out of bounds write and use after free for crates.io; and out of bounds write, buffer overflow and input validation for NuGet.
What the weakness mix says about each language
PHP (Composer): output encoding. Nearly a third of Composer advisories are cross site scripting, consistent with an ecosystem full of content systems, admin panels and web applications. The common shorthand "PHP means SQL injection" is only partly true: SQL injection is 5.5%, about one sixth of the XSS volume.
Java (Maven): deserialisation and frameworks. Java's native serialisation and the libraries that rebuild object graphs from untrusted XML, YAML or polymorphic JSON created a whole class of gadget chain bugs (414 advisories). Aquia also found Maven had more advisories on the CISA Known Exploited Vulnerabilities list (39 in its snapshot) than any other ecosystem, a better proxy for real harm than raw counts.
JavaScript (npm): language semantics leak into bug classes. Prototype pollution exists because of how JavaScript objects inherit properties. ReDoS is common because npm code parses untrusted strings with regular expressions on a single threaded event loop, where one slow match blocks the process. These are the clearest cases where the language's design shapes the weakness mix.
Python (pip): file handling and native code. Path traversal leads the weaknesses we checked (536), reflecting the volume of tools that extract archives or build paths from input. The 141 out of bounds write advisories show how much of PyPI is a thin layer over C and C++ extensions.
Go: resource exhaustion. Uncontrolled resource consumption (276) leads in our check and in Aquia's. Go runs many network services and parsers where unbounded allocation is the common failure. Memory corruption is rare outside unsafe and cgo.
Rust: memory bugs in unsafe code. Rust's use after free (72) and out of bounds write (60) advisories come almost entirely from unsafe blocks, foreign function interfaces or soundness bugs. RustSec files advisories for soundness issues that may never be exploitable, which inflates the count.
.NET (NuGet): native wrappers. Aquia found out of bounds write and buffer overflow at the top of NuGet's list. Our reading, not verified package by package, is that these come from packages that bundle native C and C++ libraries.
For plain language explanations of these weaknesses, see our 2025 CWE Top 25 guide; for the same breakdown from OSV data, see top weaknesses in OSV advisories by ecosystem.
Why do C and C++ look small in package databases yet dominate memory safety CVEs?
C and C++ do not appear in Table 1 at all. That is not because the code is safe. The GitHub Advisory Database is organised around package registries, and C and C++ have no dominant central registry. Libraries arrive through operating system packages, vendored source, git submodules, Conan, vcpkg, or as native code inside packages from other ecosystems.
So C and C++ vulnerabilities show up elsewhere:
- As unreviewed CVE records. Many of the 357,187 unreviewed advisories are CVEs GitHub could not map to a registry package.
- As Linux distribution advisories from Debian, Ubuntu, Red Hat, Alpine and others, many aggregated by OSV.
- As git range advisories. OSV.dev lists "Git (including C/C++)" as a covered ecosystem and imports OSS-Fuzz results.
- Inside other ecosystems, as the out of bounds bugs in PyPI and NuGet show.
In data not organised by registry, memory safety dominates. Chromium's security team reports that around 70% of the 912 high or critical security bugs affecting its stable channel since 2015 were memory safety problems: "Around 70% of our high severity security bugs are memory unsafety problems." MITRE's 2025 CWE Top 25, built from 39,080 CVE records published between June 2024 and June 2025, ranks out of bounds write fifth. CISA and the NSA published joint guidance on 24 June 2025, "Memory Safe Languages: Reducing Vulnerabilities in Modern Software Development", on moving new code to memory safe languages.
The practical lesson: if your estate includes C or C++, directly, in containers or as native extensions, a package advisory database will undercount your exposure. Scan container images and match operating system packages against distribution and CVE feeds too.
How did advisory volume change between the 2025 snapshot and October 2026?
GitHub's "by the numbers" post says the database ended 2024 with 20,607 reviewed advisories; its per ecosystem table sums to 20,894, so it reflects a point in the first half of 2025. On 23 October 2026 the total was 37,118.
| Ecosystem | GitHub table (2025) | 23 Oct 2026 | Growth |
|---|---|---|---|
| Go | 2,011 | 5,017 | +149% |
| npm | 3,653 | 7,939 | +117% |
| pip | 3,378 | 6,662 | +97% |
| Rust | 857 | 1,603 | +87% |
| NuGet | 651 | 1,186 | +82% |
| Composer | 4,238 | 6,581 | +55% |
| Maven | 5,171 | 7,193 | +39% |
| RubyGems | 840 | 1,162 | +38% |
Sources: GitHub blog table (2025) and GitHub Advisory Database (23 Oct 2026).
In the 2025 table Maven was first, Composer second and npm third. By October 2026 npm was first and pip had overtaken Composer. "Java has the most vulnerabilities" and "JavaScript has the most vulnerabilities" were both true within two years of each other, so check the date on any such claim. The fastest growth is in Go, npm and pip, which also attract the most new code and the most new research tooling. More reported advisories is at least as likely to mean more people looking as worse code.
Why did GitHub's reviewed advisory pipeline hit a record in May 2026?
On 29 June 2026 GitHub's curation team described what happened when inbound volume broke records:
- In May 2026 GitHub reviewed 1,560 advisories, the highest monthly total in the database's history. Two years earlier it published about 270 a month.
- Private vulnerability reports rose from about 550 a week in January to more than 3,000 a week for most of May; repository advisories from about 650 to more than 5,000 a week.
- As a CVE Numbering Authority, GitHub received almost 4,000 CVE requests in May, nearly ten times the year earlier figure.
- Since mid April it has not consistently met its internal publication goals. Processing stretched to about a week, then to "multiple weeks" for a meaningful share of advisories.
Help Net Security's 30 June 2026 coverage reported the same figures and noted that GitHub linked the surge to a broader move toward open disclosure. GitHub presented AI assisted research tooling as a response to the backlog, with curators still making every decision.
What a review backlog does to the statistics
It lags counts. An issue published upstream in September may not reach the reviewed set until November, and the busiest ecosystems are undercounted most.
It changes the mix. GitHub now prioritises repository advisories by project impact and severity, so during a backlog the reviewed set over represents high impact, well documented issues.
It moves close rankings. Between a mid October snapshot in our research notes and 23 October, npm rose by 32 and pip by 26 while Maven, Composer and Go did not change.
So do not rely on one curated database, and do not treat "no advisory" as "no vulnerability". Our advisory data quality scorecard and the post on unrated advisories look at these gaps.
Does a high count mean an unsafe language or a well reported ecosystem?
Mostly the second. Five factors drive counts more than the language does.
Age. Maven and Packagist have hosted production web software for well over a decade, and long lived frameworks accumulate advisories.
What gets published. Composer and Maven host frameworks and whole applications; npm hosts millions of tiny utilities.
Reporting culture. RustSec, the PyPA advisory database and the Go vulnerability database all feed GitHub's reviewed set, and GitHub notes that such ecosystem specific sources produce advisories that mostly get reviewed.
Researcher attention. Bug bounties, scanners and AI assisted research concentrate on popular, high value targets.
Where platform fixes live. .NET and Java ship large standard libraries tracked as platform CVEs; JavaScript's small standard library pushes basic functionality into npm, where it is counted.
The language matters at the margins. Memory safe languages remove whole bug classes, and JavaScript's prototype semantics and PHP's templating history shape their weakness mix. But a raw count ranking measures attention and size first and language design a distant second.
What should a team with a multi language estate measure instead?
Your risk is not the ecosystem's total. It is the subset of advisories that hits what you ship, filtered by whether you can actually be attacked through it, weighted by how long you stay exposed.
Decision table: the right metric for the question
| Question you are asked | Bad metric | Better metric |
|---|---|---|
| "Is language X less secure than language Y?" | Raw advisory count per ecosystem | Weakness families per ecosystem, plus memory safety; and a statement that counts reflect reporting |
| "How exposed are we?" | Total advisories in the ecosystems we use | Advisories matching components and versions in our SBOMs |
| "What do we fix first?" | CVSS alone | Reachable, known exploited (CISA KEV), high EPSS, internet facing |
| "Are we getting better?" | Number of open findings | Median and 90th percentile time from fix available to fix deployed, per ecosystem |
| "Which ecosystem needs more tooling?" | Advisories per ecosystem | Your component count per ecosystem times advisories per 1,000 packages, plus scanner coverage for that ecosystem |
| "Should we ban a language?" | Industry raw counts | Your own incident and finding history, and the cost of the weakness families that language brings |
A metric set that works across languages
- Exposure: count of distinct vulnerable component versions in production SBOMs, per ecosystem.
- Reachability adjusted exposure: the same count limited to findings where the vulnerable function is reachable from your code.
- Exploit weighted exposure: reachable findings that are on CISA KEV or above an EPSS threshold you choose.
- Fix latency: time from a fixed version being published to that version running in production, by ecosystem.
- Fixless exposure: findings where no fixed version exists, and how long each has been open.
- Native code share: for Python, .NET, Ruby and Node estates, the number of packages that ship compiled native code, because their memory safety bugs will not look like the rest of the ecosystem.
Step by step: reproduce the numbers yourself
Everything in this post can be reproduced from public data. These commands work on macOS or Linux with git, curl and jq installed.
1. Clone the reviewed advisory set. The GitHub Advisory Database is a public repository of OSV format JSON files.
git clone --depth 1 https://github.com/github/advisory-database.git
cd advisory-database
ls advisories/github-reviewed | head
2. Count non withdrawn reviewed advisories per ecosystem. Each file lists affected packages with their ecosystem. Count each advisory once per ecosystem.
find advisories/github-reviewed -name 'GHSA-*.json' -print0 \
| xargs -0 jq -r 'select(.withdrawn == null)
| [.affected[].package.ecosystem] | unique[]' \
| sort | uniq -c | sort -rn
Expect small differences from the website counts, which are computed by GitHub's search index rather than by file.
3. Count CWEs per ecosystem.
find advisories/github-reviewed -name 'GHSA-*.json' -print0 \
| xargs -0 jq -r 'select(.withdrawn == null)
| . as $a
| ([.affected[].package.ecosystem] | unique[]) as $eco
| ($a.database_specific.cwe_ids // [])[]
| "\($eco)\t\(.)"' \
| sort | uniq -c | sort -rn | head -40
4. Pull denominators. Package counts per registry from ecosyste.ms, and download totals from the registries that publish them.
# Registry package counts (inspect field names first with: jq '.[0] | keys')
curl -s https://packages.ecosyste.ms/api/v1/registries \
| jq -r '.[] | [.name, .packages_count] | @tsv'
# npm downloads for the last year
curl -s https://api.npmjs.org/downloads/point/last-year | jq
# crates.io lifetime downloads and crate count
curl -s -A "your-name-research" https://crates.io/api/v1/summary \
| jq '{num_downloads, num_crates}'
5. Check one package against OSV. OSV aggregates GitHub, PyPA, RustSec, Go, OSS-Fuzz and distribution feeds, so it is a good cross check.
curl -s -X POST https://api.osv.dev/v1/query \
-d '{"package":{"name":"lodash","ecosystem":"npm"}}' \
| jq '.vulns | length'
6. Measure your own exposure instead of the ecosystem's. Generate an SBOM and match it against vulnerability data for each repository or image you ship. With the Safeguard CLI:
safeguard scan --dir . # a repository
safeguard scan --image myapp:latest # a container image, including OS packages
safeguard scan --sbom sbom.cdx.json # an existing SBOM file
Results are written as JSON under ./output, so you can count findings per ecosystem with the same jq approach as above and compare your profile with the industry tables in this post.
7. Stop known vulnerable versions from coming back. Add a CI gate. A minimal GitHub Actions workflow using the free Gold scan action:
name: dependency-gate
on: [pull_request]
jobs:
gold-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# pin to a released tag of the action
- uses: safeguard-sh/gold-scan-action@main
Check the action's README for the input that sets whether the build fails on known exploited vulnerabilities only, on any known vulnerability, or never, and pin the version you adopt.
How we measured
Advisory counts. Reviewed totals per ecosystem from the ecosystem filter on github.com/advisories on 23 October 2026: 37,118 reviewed and 357,187 unreviewed. Per ecosystem counts sum to more than the total because some advisories span ecosystems. Unreviewed records were excluded because they lack reliable package mapping.
CWE counts. Result counts of searches combining type:reviewed, an ecosystem and a CWE, run on 23 October 2026. We checked twelve pairs chosen to test the weakness families commonly linked to each language, not every pair. Advisories can carry several CWEs or none, so shares are lower bounds.
Package counts. From packages.ecosyste.ms on 23 October 2026, one method across registries. Go figures are module paths seen by the Go module proxy and are not directly comparable.
Developer share. All respondents in the Stack Overflow 2025 survey, one language per ecosystem (JavaScript to npm, Java to Maven, Python to pip, PHP to Composer, C# to NuGet, and Go, Rust and Ruby to their own registries). Contributor counts from Octoverse 2025 exist for only three languages.
Downloads. npm from its API for 19 October 2025 to 18 October 2026; NuGet from six weekly totals annualised by 52/6; crates.io, RubyGems and Packagist lifetime totals. PyPI, Maven Central and Go publish no comparable total, so we did not estimate them.
History. GitHub's 2025 "by the numbers" table (post dated 27 June 2025, updated 4 February 2026). CramHacks' 24 June 2024 analysis (3,507 npm, 4,971 Maven, 3,958 Composer, and a queue of over 220,000 unreviewed advisories) is a third reference point that shows the same trend.
C and C++. Not computed from GitHub data. We used Chromium's published analysis and MITRE's 2025 CWE Top 25 dataset description. We could not retrieve a current NVD total or per CWE NVD count, so we quote none.
Not done. No severity weighting, no deduplication of advisories that cover one CVE in several packages, no removal of packages bundling native code, no backlog adjustment. Each would move individual numbers; none would put npm back on top of the per package ranking.
Where datasets disagree. Packagist package count (475,338 on packagist.org against 524,487 on ecosyste.ms); crates.io (359,402 against 363,572); website counts against counts from parsing the repository, which both CramHacks and Aquia found differ by a few hundred; and the raw ranking itself, which changed between 2025 and 2026.
Common mistakes
Quoting a raw count as a safety ranking. "npm has the most vulnerabilities" is true and nearly useless without a denominator.
Putting C and C++ on the same axis as package ecosystems. They are missing from package databases for structural reasons.
Mixing download windows. Lifetime and annual downloads produce nonsense ratios.
Assuming a reviewed database is complete and current. Use more than one source and match on CVE and GHSA identifiers.
Ignoring native code inside managed ecosystems. Python, .NET and Ruby services can carry C library memory bugs. Scan images, not only manifests.
Prioritising by count instead of reachability. Most advisories in a tree hit code you never call. Fix the reachable, exploited ones first.
Defending a language choice with industry averages. Boards and auditors are better served by your own exposure and fix latency.
Fix it without waiting for upstream
Whichever language your estate leans on, the numbers above share one feature: most advisories arrive with a fixed version, and the real exposure is the time between that fix existing and it running in your builds. For the minority with no fix yet, the wait is longer still.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
FAQ
Which programming language has the most vulnerabilities?
By raw count of reviewed package advisories, JavaScript's npm ecosystem has the most: 7,939 on 23 October 2026. Normalised by registry size, PHP's Composer (12.55 per 1,000 packages) and Java's Maven (9.84) lead and npm is last of the eight big ecosystems. C and C++ are not in package advisory databases at all, yet dominate memory safety vulnerabilities in projects like Chromium. There is no single honest answer without stating the denominator.
Is JavaScript the least secure programming language?
No. npm leads raw counts because it is by far the largest registry, with more than six million packages. Per package and per download it has the lowest advisory rate of the ecosystems we measured. Its distinctive weaknesses, prototype pollution and ReDoS, do come from JavaScript's design, so the language shapes which bugs appear more than how many.
Is PHP more vulnerable than other languages?
PHP's Composer ecosystem has the highest rate per 1,000 packages and per point of developer share in our data, and 31.2% of its reviewed advisories are cross site scripting. That reflects the kind of software published on Packagist (web applications and content systems) and two decades of research attention as much as the language. Modern PHP frameworks with auto escaping templates avoid most of that class.
Why does C and C++ not appear in the GitHub Advisory Database?
Because the reviewed database is organised by package registry, and C and C++ have no dominant central registry. C and C++ vulnerabilities appear as unreviewed CVE records, in Linux distribution advisories, as git range entries in OSV, or inside native extensions shipped by PyPI, NuGet and RubyGems packages.
Why is Java's vulnerability count so high?
Maven hosts a long lived set of large enterprise frameworks and application servers, and its advisories cluster in them: 5.41 advisories per vulnerable package in GitHub's 2025 table, the highest of any ecosystem. Java also carries a distinctive deserialisation class (414 reviewed advisories) and, in one independent analysis, the most advisories on CISA's Known Exploited Vulnerabilities list.
How fast is the number of vulnerabilities growing?
Reviewed advisories grew from 20,607 at the end of 2024 to 37,118 on 23 October 2026. Go (up 149% since GitHub's 2025 table), npm (117%) and pip (97%) grew fastest. GitHub reviewed a record 1,560 advisories in May 2026, and the CVE program had published more than 30,000 records in 2026 by late June, according to GitHub.
Does the GitHub Advisory Database include every vulnerability?
No. It reviews advisories for supported package ecosystems only, and on 23 October 2026 it held 357,187 unreviewed records against 37,118 reviewed ones. During the 2026 surge GitHub said some reviews took multiple weeks. Cross check with OSV, distribution feeds and vendor advisories.
Should we choose a language based on vulnerability statistics?
Not on raw counts. Memory safety is a legitimate selection criterion, and CISA and the NSA published joint guidance in June 2025 on adopting memory safe languages. Beyond that, ecosystem maturity, dependency hygiene and your ability to patch quickly matter more than which language has the most advisories.
See how Safeguard would help
The tables above describe whole ecosystems. The demos below show how the same questions get answered for your own code: which advisories affect what you ship, and how the fix gets made.
This demo is a real CLI session. Someone asks the Safeguard CLI to "fix the lodash CVE in this repo"; it reads the finding and the advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, prints a summary and pushes nothing. The same flow applies to a prototype pollution or ReDoS finding in your npm tree, or an equivalent upgrade in Maven or pip.
Click through it at your own pace, or open it full screen.
This demo shows setting up the Safeguard runner on your own machine, approving it with its device code, and then scanning from the terminal. That is how you produce the per ecosystem exposure numbers from the "How we measured" approach for your own repositories rather than the industry.
Click through it at your own pace, or open it full screen.
This demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. Once connected, you can ask questions like "which of our projects have deserialisation findings in Maven dependencies" in plain language against your own data.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard or read the CLI documentation. For more on how the CLI works, see the Safeguard CLI as a security aware coding assistant. Before choosing any scanner, check your ecosystems against OSV coverage, and for the plain per ecosystem counts see our reviewed advisories by ecosystem data note.
Quick check
npm has the most reviewed advisories. Where does it rank per 1,000 packages among the eight largest ecosystems?
Last. With more than six million packages, npm works out to about 1.32 reviewed advisories per 1,000 packages on 23 October 2026, below Composer (12.55), Maven (9.84), pip (7.06), RubyGems, Rust, Go and NuGet.
Why do C and C++ barely appear in package advisory databases?
Because those databases are organised by package registry, and C and C++ have no dominant central registry. Their vulnerabilities show up as CVE records, distribution advisories, git range entries in OSV, and native code inside other ecosystems' packages.
Sources
- GitHub Advisory Database (ecosystem and CWE filtered counts, read 23 October 2026)
- GitHub blog: GitHub Advisory Database by the numbers
- GitHub blog: Inside the Advisory Database and what happens when vulnerability volume breaks records
- Help Net Security: GitHub Advisory Database review, 30 June 2026
- ecosyste.ms packages
- Stack Overflow 2025 Developer Survey: technology
- GitHub Octoverse 2025
- npm downloads API, last year
- NuGet statistics
- crates.io summary API
- RubyGems.org
- Packagist statistics
- OSV.dev data sources
- Chromium: memory safety
- CISA and NSA: Memory Safe Languages, Reducing Vulnerabilities in Modern Software Development
- MITRE: 2025 CWE Top 25
- Aquia: Exploring the GitHub Advisory Database for fun and (no) profit
- CramHacks: GitHub Security Advisory analysis
Last reviewed: 23 October 2026. Advisory counts change daily; re-read the linked pages for current figures.