Node.js Vulnerabilities in 2026: Every CVE, the npm Worms and What to Patch
By Assim ElHammouti, Founder and Lead Engineer, NordbeamPublished Updated
Which Node.js vulnerabilities matter right now?
The most serious Node.js vulnerability of 2026 is CVE-2026-111497, an out-of-bounds write in the bundled Brotli decoder that can lead to remote code execution. It was fixed on 21 October 2026. Run Node.js 22.23.4, 24.22.1 or 26.12.1 or later; Node 20 is end-of-life and gets none of these fixes. Compiled by Nordbeam, a development studio in Gothenburg and Malmö.
- Patch to
- 22.23.4 · 24.22.1 · 26.12.1
- Latest security release
- 21 October 2026
- No longer patched
- Node 20, Node 25 and older
Node.js has shipped five security releases in 2026: in January, March, June, July and October. Between them they fix around 50 vulnerabilities in Node.js core. The latest, on 21 October, fixes a decoder bug that the project's own advisory says can lead to remote code execution.
That was not the hardest part of the year for Node.js teams, though. Over the same months, the npm registry saw three large supply-chain attacks: a hijacked axios release in March, a worm that went through TanStack's own release pipeline in May, and ChainDrop in August, which Microsoft says reached more than 400 packages.
This article covers both: what changed in Node.js core, what the npm attacks had in common, and the exact versions and settings to use today. It is written for teams running Node.js in production, and every version number links back to its source. If you also run Bun, PHP or Ruby, we have written the same roundup for Bun, PHP and Ruby and Rails.
What is the most serious Node.js vulnerability right now?
CVE-2026-111497, a flaw in the Brotli decoder that ships inside Node.js, nicknamed "Node2Shell". It affects Node 22, 24 and 26, and the fix is in 22.23.4, 24.22.1 and 26.12.1, released on 21 October 2026.
The official advisory explains the mechanism. An invalid block switch in the compressed stream was reported as "need more input" instead of as a format error. The streaming decoder therefore kept appending bytes to an eight-byte internal buffer, past its end. Anyone who can make your application decompress Brotli data with node:zlib can corrupt process memory, "which can lead to a crash, disclosure of process memory, or remote code execution."
The bug is in Google's Brotli library itself, versions 1.0.3 to 1.2.0, so it is not specific to Node.js. It also hit Bun and the Python brotli package. Node.js rates it High. Google, which assigned the CVE, rates it Critical, CVSS v4.0 9.2 (NVD record), and Singapore's Cyber Security Agency scores it 9.8 in its alert.
You are exposed if any code path inflates Brotli data that came from outside, for example:
- Request bodies sent with
Content-Encoding: brthat your server or middleware decompresses. - Uploaded or downloaded
.brfiles processed withzlib.brotliDecompressorcreateBrotliDecompress. - Outgoing HTTP calls. Node's built-in
fetch()(undici) decompressesbrresponses withzlib.createBrotliDecompress, so an HTTP request to a server you do not control reaches the decoder.
The last point makes this broader than it looks. Webhooks, link previews, scrapers and any "fetch this URL for me" feature are all in scope. There is no configuration flag that removes the risk; the fix is the upgrade.
10
Vulnerabilities in the Node.js security release of 21 October 2026
- 4
- rated High, including the Brotli decoder RCE (CVE-2026-111497)
- 3
- patched lines: 22.23.4, 24.22.1 and 26.12.1
- 0
- fixes for Node 20, which reached end-of-life on 30 April 2026
Everything in the October 2026 release
| CVE | Severity | What it is | Lines |
|---|---|---|---|
| CVE-2026-111497 | High | Brotli decoder out-of-bounds write; possible RCE | 22, 24, 26 |
| CVE-2026-105482 | High | dns.resolve*() truncates names at a NUL byte, so attacker.example\0.trusted.example resolves as the attacker's domain | 22, 24, 26 |
| CVE-2026-105483 | High | TLS hostname check bypass when an IP is written with fullwidth digits | 24, 26 |
| CVE-2026-106069 | High | TLS hostname check bypass when a host loosely resolves to an IP (for example a leading-zero IPv4 read as octal) | 22, 24, 26 |
| CVE-2026-105481 | Medium | A keep-alive socket accepts a response written before the request was sent | 22, 24, 26 |
| CVE-2026-106072 | Medium | Non-canonical IPv4 hostnames (127.1, 0x7f.0.0.1) can be authenticated by a DNS SAN | 22, 24, 26 |
| CVE-2026-106074 | Medium | crypto.randomUUID() and randomInt() caches are saved into startup snapshots and single executable apps, so every process repeats the same values | 22, 24, 26 |
| CVE-2026-106073 | Low | Permission Model bypass through fs.realpathSync | 22, 24, 26 |
| CVE-2026-106070 | Low | ZipFile returns attacker-controlled bytes after a failed header check | 26 |
| CVE-2026-106071 | Low | Permission Model over-grant through wildcard paths | 26 |
The same release updates c-ares, OpenSSL (22 and 24), SQLite (22), undici and the bundled CA certificates. That last update follows an intermediate CA compromise at eMudhra.
What did each Node.js security release in 2026 fix?
Every release this year followed the same pattern: a small number of High-severity bugs in network-facing code, a long tail of Medium and Low issues, and dependency updates. Here are the five side by side. The counts are taken from each official post.
| Release | Fixed versions | Issues (High) | Headline bugs |
|---|---|---|---|
| 21 Oct 2026 | 22.23.4, 24.22.1, 26.12.1 | 10 (4) | Brotli decoder RCE, TLS hostname bypasses, DNS NUL truncation |
| 29 Jul 2026 | 22.23.2, 24.18.1, 26.5.1 | 11 (3) | HTTP/2 use-after-free (CVE-2026-56848), HTTP/2 memory exhaustion, Permission Model over-grant |
| 18 Jun 2026 | 22.23.0, 24.17.0, 26.3.1 | 12 (2) | WebCrypto AES integer overflow, TLS wildcard bypass via Unicode dots |
| 24 Mar 2026 | 20.20.2, 22.22.2, 24.14.1, 25.8.2 | 9 (2) | __proto__ header crash (CVE-2026-21710), SNI callback crash, V8 HashDoS |
| 13 Jan 2026 | 20.20.0, 22.22.0, 24.13.0, 25.3.0 | 8 (3) | Uninitialised memory via vm timeouts, symlink Permission Model bypass, HTTP/2 HEADERS crash |
Two things stand out. First, several October fixes are repairs of June fixes: CVE-2026-105482 is an incomplete fix of the June DNS bug, and CVE-2026-105483 is a regression after the June TLS fix. Patching once is not enough; you have to keep up.
Second, March was the last release for Node 20. Every Node 20 server running today has missed the June, July and October fixes.
Where do Node.js vulnerabilities come from?
Most core CVEs in 2026 sit in protocol handling and in the native libraries that Node.js bundles, not in JavaScript APIs that you call directly. That matters, because there is nothing you can configure around a bug in the HTTP/2 or Brotli layer. You can only upgrade.
Routes, auth, input validation
Your code and your configuration
Frameworks and transitive packages
Next.js RCEs (October), the axios, TanStack and ChainDrop compromises
http, http2, tls, dns, zlib, crypto, Permission Model
TLS and DNS identity bugs, HTTP/2 crashes, 14 Permission Model bypasses
Brotli, nghttp2, llhttp, OpenSSL, c-ares, undici
The Brotli out-of-bounds write, the nghttp2 use-after-free
Four patterns cover nearly everything in this year's releases.
1. TLS and DNS disagree about what a name is. NUL bytes, Unicode dots, fullwidth digits, octal IPv4 addresses, SNI case and session reuse: in each case the certificate checker and the resolver read the same hostname differently. An attacker who controls a name can then get a certificate accepted for a host it was not issued for. If you connect to internal services by IP, or pin certificates to hostnames, these bugs are aimed at you.
2. HTTP/2 and the HTTP parser keep producing crashes. Almost every release has an HTTP/2 denial of service, and July added a use-after-free (CVE-2026-56848) and a header-count bug (CVE-2026-58044). The latter lets a forwarding proxy disagree with the backend about where a request ends, which is the setup for request smuggling.
3. Memory-safety bugs in bundled C code. The Brotli decoder, nghttp2 and the WebCrypto AES path are all native code. These are the bugs that move from "crash" to "remote code execution".
4. The Permission Model is bypassed in every release. That is the subject of the next section.
Is the Node.js Permission Model a security sandbox?
No. The Node.js documentation calls it a "seat belt" that stops trusted code from accidentally touching files or resources. It states plainly that it "does not provide security guarantees in the presence of malicious code."
The 2026 releases bear that out. Counting all five posts, we found 14 Permission Model bypasses. They came through process.report, FileHandle.utimes(), chmod() and chown(), realpathSync, trace_events, symlinks, Unix domain sockets and wildcard paths. Several were incomplete fixes of earlier ones.
Use --permission to catch mistakes in code you trust. To run code you do not trust, use operating-system isolation: a container with a read-only filesystem, a separate user, seccomp or AppArmor profiles.
Which Node.js versions are still supported?
Node.js 22, 24 and 26. Node 20 reached end-of-life on 30 April 2026, and the odd-numbered Node 25 followed on 1 June. The project's own wording is that end-of-life versions "are always affected when a security release occurs."
- EOL Apr 2026
Node 20
- Unsupported; last release 20.20.2
- Missed the June, July and October fixes
- EOL Apr 2027
Node 22
- Maintenance LTS
- Patch to 22.23.4
- EOL Apr 2028
Node 24
- Maintenance LTS since 20 Oct 2026
- Patch to 24.22.1
- EOL Apr 2029
Node 26
- Active LTS from 28 Oct 2026
- Patch to 26.12.1
| Line | Status on 24 Oct 2026 | End of life | Version to run |
|---|---|---|---|
| Node 26 | Current, becomes Active LTS on 28 Oct 2026 | 30 Apr 2029 | 26.12.1 or later |
| Node 24 | Maintenance LTS since 20 Oct 2026 | 30 Apr 2028 | 24.22.1 or later |
| Node 22 | Maintenance LTS | 30 Apr 2027 | 22.23.4 or later |
| Node 25 | End-of-life | 1 Jun 2026 | Move to 26 |
| Node 20 | End-of-life | 30 Apr 2026 | Move to 24 or 26 |
Dates are from the Node.js release schedule. For new production work we would start on Node 24, or on 26 once it becomes LTS on 28 October. Node 22 is still patched, but it has six months left, which is less than most upgrade projects take to plan.
How did the 2026 npm supply-chain attacks work?
The same way each time: steal a publishing credential, ship a release with a script that runs on install, and use whatever that script steals to publish more. The three big incidents differed only in how they got the first credential.
axios, 31 March 2026. A maintainer account was compromised and two releases, axios@1.14.1 and axios@0.30.4, were published with a new dependency, plain-crypto-js@4.2.1. That package's postinstall script dropped a cross-platform remote access trojan that went after .ssh and .aws. The bad versions were live for about three hours, according to Orca Security's analysis. Projects that installed axios in that window, without a lockfile pinning an older version, pulled the trojan.
TanStack and "Mini Shai-Hulud", May 2026. This one did not need a stolen password. Orca reports that the attacker chained GitHub Actions weaknesses: a pull_request_target workflow poisoned the Actions cache, and the release workflow then leaked OIDC tokens. The malicious versions, 373 of them across 169 npm package names, were published through the legitimate pipeline. They therefore carried valid npm provenance. The payload stole GitHub, npm, cloud, Kubernetes and Vault credentials and spread from one package to the next, like the original Shai-Hulud worm of 2025.
ChainDrop, August 2026. Microsoft's write-up describes more than 400 compromised packages from unrelated publishers, including keyv, flat-cache and cache-manager.
- Install hook. A
preinstallhook ransetup.mjs, which launched an obfuscated, Bun-based payload. - Theft. It harvested npm, GitHub and cloud credentials, and used them to read AWS, Kubernetes and Vault secrets.
- Spread. For every package a stolen token could publish, it downloaded the latest tarball, inserted itself, bumped the patch version and republished.
- Persistence in repositories. It also wrote
.claude/settings.jsonand.vscode/tasks.jsonfiles into repositories, to spread from developer to developer.
Publishing token stolen
Phished, leaked, or lifted from a CI runner
Patch release with a preinstall hook
Often no matching commit or tag
npm install runs the hook
On laptops and CI runners
Steals tokens, republishes
Every package the victim can publish
Install scripts off by default, and a cooldown before any new version is installed
- ✓ lockfile committed; npm ci in CI
- ✓ trusted publishing with short-lived tokens for your own packages
- ✓ provenance checked, but not treated as proof of safety
How do you protect a Node.js project from npm supply-chain attacks?
Make new releases wait, stop install scripts from running by default, and make your own publishing pipeline hard to borrow. In order of effort:
- Commit the lockfile and install with
npm ciin CI and in Docker builds. A lockfile means a new malicious patch release only reaches you when someone updates it on purpose. - Add a release-age cooldown. Microsoft's ChainDrop guidance is to upgrade to npm CLI v12 and use its
min-release-agesetting. pnpm hasminimumReleaseAge, and so does Bun, inbunfig.toml(see our Bun article). The malicious axios versions were live for about three hours, so a cooldown of a few days would have kept them out entirely. - Turn off lifecycle scripts by default with
ignore-scripts=truein.npmrc. Then run the few build steps you actually need, such as native modules, explicitly. The axios trojan ran from apostinstallscript, and ChainDrop from apreinstallhook. - Treat provenance as a signal, not a guarantee. The TanStack versions had valid provenance because the attacker used the real pipeline.
- Harden your own release workflow if you publish packages. Use trusted publishing (OIDC) instead of long-lived tokens. Never run untrusted pull-request code in a
pull_request_targetworkflow, and do not share caches between untrusted jobs and release jobs. - Run
npm auditin CI, but know its limits. It reports known advisories against your installed versions; it does not catch a malicious release in its first hours.
Attention
If you installed a compromised version
Rotate credentials from a clean machine, not the infected one. Purge npm and yarn caches on developer machines and shared CI runners, and rebuild images from a known-good baseline. Microsoft also lists Math_Symbol.js and Math_init.js as ChainDrop artifacts to look for.
Which npm package vulnerabilities should you check in 2026?
Next.js is the urgent one. On 20 October 2026, two unauthenticated remote code execution flaws were published, both CVSS v4.0 9.5, per Singapore's CSA alert:
- GHSA-673q-mjm6-r5xr affects App Router applications using Cache Components, when a
"use cache"function returns multiple typed arrays. No CVE ID had been issued at publication. - CVE-2026-96889 comes from a memory bug in an upstream library used for Image Optimisation, on glibc-based Linux.
Both affect 16.x before 16.4.1 and 10.x to 15.x before 15.5.28. Upgrade to those versions or later.
Beyond Next.js, the most important "package vulnerability" of 2026 was not a bug but the compromised releases above. Check your lockfiles for axios@1.14.1, axios@0.30.4 and plain-crypto-js, and for any ChainDrop-era versions of keyv, flat-cache or cache-manager. Use the version lists in Microsoft's and your security vendor's advisories.
What should you patch first?
- Upgrade Node.js to 22.23.4, 24.22.1 or 26.12.1, and rebuild container images, because a
node:22base image you pulled last month still has the old binary. Check withnode -vin the running container, not on your laptop. - Move off Node 20 and 25. They will not get the Brotli fix.
- Upgrade Next.js to 16.4.1 or 15.5.28 or later if you run it.
- Search your lockfiles for the compromised axios and ChainDrop versions.
- Add a cooldown and turn off install scripts for every project and CI pipeline.
- Stop relying on
--permissionas isolation for untrusted code.
Nordbeam builds production systems on TypeScript and Node.js. If you have an end-of-life Node line or a dependency tree you are no longer sure about, our software development team can scope the upgrade with you.
What is CVE-2026-111497?
Does the Brotli vulnerability affect fetch() in Node.js?
Is Node.js 20 still safe to use?
Which Node.js version should I use in production?
How do I check npm packages for vulnerabilities?
What is the Shai-Hulud npm worm?
Is the Node.js Permission Model enough to run untrusted code?
Does this Node.js vulnerability affect Bun or Deno?
Stuck on an old Node.js line?
Tell us what you run and where it is deployed. We will tell you what an upgrade to a supported Node.js version involves, and what it costs to stop doing it by hand.
Start the Conversation →Get in Touch
Which workflow should AI improve first?
- hello@nordbeam.io
- Locations
- Gothenburg & Malmö, Sweden
- Response time
- Within 24 hours