Node.js 28 October 2026

Node.js vulnerabilities: the 10 October CVEs, the Brotli RCE, and the EOL problem

Key takeaways:

  • On October 21, 2026, Node.js patched 10 CVEs across its supported lines, and four of them are rated High.
  • The worst, CVE-2026-111497, is a flaw in the Brotli decoder bundled with Node.js that the project says can allow remote code execution.
  • Your app can hit the bug without ever calling Brotli directly, because fetch() and Express 5 decode Brotli data on their own.
  • Fixes landed in Node.js 22.23.4, 24.22.1, and 26.12.1, but there is no code workaround, so updating is the real fix.
  • End-of-life lines like Node.js 18 and 20 get no upstream patches at all, which is the hardest part for many teams.
  • As of late October, no exploitation in the wild has been reported, but working proof-of-concept code already runs against the official build.

Most of the time, Node.js vulnerabilities are something you handle one layer up. Dependabot opens a pull request, npm audit goes quiet, and nobody thinks about the runtime underneath.

That changed on October 21, 2026, when Node.js shipped security releases fixing 10 CVEs in the runtime itself, including a memory bug in a decoder your app may be feeding straight from the internet.

Four of the 10 are rated High.

The one everyone is talking about, CVE-2026-111497, sits in the Brotli decompression code bundled inside Node.js, and the project says it can allow remote code execution.

On the supported lines, the fix is a quick version bump. The problem gets much harder if any of your servers still run an end-of-life version, because those get no patch at all.

This guide walks through all of it in plain language: what these Node.js security vulnerabilities are, how the Brotli bug reaches your process, how serious it really is, and exactly what to do, whether you run the latest version or you are stuck on something old. Treat it as a quick Node.js risk assessment you can act on today.

Node.js October 2026 fixes at a glance

  • Total CVEs fixed: 10, with 4 rated High
  • Headline flaw: CVE-2026-111497, an out-of-bounds write in the bundled Brotli decoder that permits remote code execution
  • Severity: Node.js rates it High; the CVE record from Google carries a CVSS v4.0 score of 9.2
  • Affected lines: 22.x, 24.x, and 26.x before the fix, plus every end-of-life line
  • Fixed versions: Node.js 22.23.4, 24.22.1, and 26.12.1 (Bun 1.4.4 for Bun users)
  • Workaround: none official; only a runtime upgrade removes the flaw
  • Status: no exploitation in the wild reported as of late October 2026, and not in the CISA KEV catalog, but working proof-of-concept code runs against the official build
  • Nicknames: researchers call the Brotli flaw Node2Shell, and because it reaches other languages, HTTP2Shell

What are these Node.js vulnerabilities?

A CVE, short for Common Vulnerabilities and Exposures, is a public ID given to a single security flaw so that everyone can refer to the same bug by the same name.

The October 2026 Node.js release carries 10 of them, which is why this batch of Node.js 10 CVEs has drawn so much attention. These are Node.js software vulnerabilities in the runtime itself, not in the packages your app pulls from npm.

Node.js gave its usual week of warning. On October 14, the project posted a pre-alert saying new 22, 24, and 26 releases would land on or around October 21, with the highest severity rated High. The releases arrived on schedule and fixed all 10 CVEs at once.

Four are rated High. One is the Brotli remote code execution flaw covered in the next section. The other three sit in name handling: two let a TLS certificate pass hostname checks; it should fail, and one lets dns.resolve() cut a hostname short at a NUL byte, so the name your code checked and the name actually queried could differ.

The remaining six range from Medium to Low, including a notable one where crypto.randomUUID() and crypto.randomInt() could produce the same values across processes launched from the same single-file binary.

The same release also refreshes bundled components and updates the trusted certificate list after a certificate-authority key compromise reported that month. In other words, one upgrade covers far more than the headline bug.

The headline bug: CVE-2026-111497 explained simply

Brotli is a compression format, created by Google, that servers and browsers use to shrink web traffic so pages load faster. Node.js ships its own copy of the Brotli code, and that copy is where the flaw lives.

Unlike many Node.js security flaws that sit in application code, this one is baked into the runtime, so every app on an unpatched build inherits it.

The bug is an out-of-bounds write. When the decoder is handed specially malformed compressed data, it can be tricked into writing past the end of a memory buffer, into memory it was never meant to touch.

That kind of mistake is a classic route to two outcomes: a crash, or, in the worst case, an attacker getting their own code to run inside the process. Node.js rates the flaw High and describes the impact as remote code execution.

Researchers have given it a nickname, Node2Shell, in the style of the recent PHP2Shell disclosure. Within days, it picked up a second name, HTTP2Shell, once researchers found that the same Brotli flaw reaches software written in other languages, not just Node.js, because many tools bundle the same Brotli library.

The fix itself is small. Node.js cherry-picked a one-line change from the upstream Brotli project that makes the decoder detect the invalid input and stop before it writes past the buffer.

The patched runtime simply rejects the data that used to trigger the bug.

How Brotli data reaches your process without asking

The tricky part of this flaw is that your code does not have to call Brotli for the bug to be reachable. Something in your process asks for Brotli decoding on your behalf, often without you noticing. There are three main ways in:

  • Outbound requests: the built-in fetch() automatically decompresses responses that arrive with Content-Encoding: br, and there is no option to switch that off. Popular libraries like axios, node-fetch, and got do the same. So any service that fetches URLs it does not control (a webhook sender, a link-preview worker, a scraper, an AI agent pulling web pages) is on the path.
  • Inbound request bodies: Express 5, through body-parser 2.x, decompresses Brotli request bodies by default. An API using express.json() will decode a Brotli body a client sends it, even though it never asked for one. Express 4 with the older body-parser 1.x does not do this and rejects such bodies.
  • Direct calls: code that calls zlib.brotliDecompress() or createBrotliDecompress() on uploads, archives, or cached data from an untrusted source.

A bare Node.js HTTP server does not decode incoming Brotli bodies just by receiving them, so not every app is equally exposed. The quick rule: anything internet-facing on Express 5, or anything that fetches arbitrary URLs, should be patched first.
NodeJs Vulnerability
All three routes hand data to the same bundled decoder, so the single runtime update fixes every path at once.

All 10 Node.js CVEs in one table

Here is the full list from the October 21, 2026 release, with the severity and the lines each one affects.

CVESeverityWhat it isAffected lines
CVE-2026-111497HighOut-of-bounds write in the bundled Brotli decoder; permits remote code execution26.x, 24.x, 22.x
CVE-2026-106069HighTLS hostname bypass when the host loosely resolves to an IP address26.x, 24.x, 22.x
CVE-2026-105483HighTLS hostname bypass when the IP is written in fullwidth digits26.x, 24.x
CVE-2026-105482Highdns.resolve() truncates names containing a NUL character26.x, 24.x, 22.x
CVE-2026-105481MediumKeep-alive socket processes a response written before the request was sent26.x, 24.x, 22.x
CVE-2026-106072MediumNon-canonical IPv4 hostnames let a certificate authenticate IP endpoints26.x, 24.x, 22.x
CVE-2026-106074MediumrandomUUID() and randomInt() caches saved into startup snapshots and SEAs26.x, 24.x, 22.x
CVE-2026-106070LowZipFile returns attacker-controlled prefix bytes after failed header validation26.x
CVE-2026-106071LowPermission Model filesystem over-grant via wildcard lookup26.x
CVE-2026-106073LowPermission Model bypass through fs.realpathSync26.x, 24.x, 22.x

The releases also refreshed several bundled libraries and, importantly, added a blocklist for compromised certificate-authority keys.

That certificate change is easy to overlook but matters as much as the Brotli fix for many deployments.

Blog Book a call Blog

How serious is it, and is it being exploited?

The severity story moved fast, and the first impression was misleading. A public proof of concept appeared on October 22, but it reached code execution only against a deliberately weakened test build.

On a standard build, its author reported just a crash and a limited memory read, which made the bug look like something you could push to next sprint.

The same day, Imperva’s red team published Node2Shell. In fresh containers running the official, unmodified Node.js 24.22.0 image, with no debugger and no special binary, Brotli data delivered as a fetched response or a request body made the application run code supplied with that data.

They reproduced it through fetch() and through Express 5 with its raw() and json() parsers. The patched 24.22.1 rejected the same inputs. It took multiple attempts, and they only tested arm64, so it is not push-button, but it is a long way from lab-only.

There is a scoring nuance worth knowing. Node.js rates the flaw high, one step below critical. The CVE record, published by Google as the maintainer of Brotli, carries a CVSS v4.0 score of 9.2, which lands in the critical band. Both describe the same bug; they just score it on different scales.

As of late October 2026, no exploitation in the wild has been reported, and the CVE is not in the CISA Known Exploited Vulnerabilities catalog.

That is good news, but it is not a reason to wait. Node.js CVE vulnerabilities of this kind sit in a runtime component that handles untrusted network input, public proof-of-concept code exists, and the fix is a routine version bump.

Which Node.js lines get a fix, and which do not

Upstream fixes cover exactly three release lines. Everything older is on its own.

Node.js lineStatusWhere the fix comes from
26.xCurrentNode.js 26.12.1
24.xLong-term supportNode.js 24.22.1
22.xLong-term supportNode.js 22.23.4
20.xEnd of life (April 30, 2026)No upstream fix
18.xEnd of life (April 30, 2025)End of life (April 30, 2025)
16.x and 14.xEnd of life (2023)No upstream fix
12.xEnd of life (April 30, 2022)No upstream fix
Odd-numbered lines (25, 23)End of lifeNo upstream fix

Bun users are affected too. The fix for Bun is version 1.4.4 or newer.

One catch worth repeating: a container image pinned to an old tag, such as node:24.22.0, stays vulnerable until you rebuild it on a patched version.

A package inventory can also miss a runtime bundled inside an image, so check the Node.js version inside each deployed container, not just on the host.

What to do if your version is end of life

Node.js security advisories carry a standing line: end-of-life versions are always considered affected when a security release ships. Since the Brotli fix only went into Node.js on October 21, no end-of-life line gets it from upstream. That leaves a real gap for teams that cannot move off an old version overnight.

The installs that cause trouble are rarely the ones anyone calls a server:

  • A build container pinned to Node 16 because a native addon stopped compiling on anything newer
  • An internal admin tool someone shipped as a single binary years ago
  • A vendor appliance with Node 14 running under its web console
  • A set of production services held on Node 18 by one dependency whose maintainer moved on

Picture a payments team with 40 services on Node 18, reading a remote-code-execution advisory with no patch attached. Nobody is migrating 40 services by Friday.

For that gap, there are two honest paths. You can move to a supported line now, which is the right long-term answer, or you can buy time with extended support that backports the fix to your end-of-life version while you plan the migration on your own schedule.

Whichever route you take, the migration itself still has to happen, because the end-of-life dates are not moving. If you want help planning or carrying out that move, CodeTrade’s Node.js Developers can audit what you run and handle the upgrade safely.

How to patch, restart, and prove it

Applying the Node.js vulnerability fixes is mostly about not missing anything. The steps are simple, but each one has a trap people fall into, and skipping one can leave the Node.js vulnerability remediation incomplete.

  • Inventory first: the list is always longer than expected. Version managers, distribution packages, CI runners, systemd units, and container base images can each point to a different Node binary. Run node –version on hosts and CI runners, and check the version inside each container image too, because a package inventory often misses a runtime bundled in an image.
  • Upgrade to a fixed version: 22.23.4, 24.22.1, or 26.12.1, or a newer patch release of the same line. For Bun, move to 1.4.4 or newer.
  • Rebuild and redeploy images: a Dockerfile pinned to an old tag stays vulnerable no matter how often you rebuild, so move the pin to a patched version first.
  • Restart everything: this is the step that gets skipped. A running Node process keeps the old decoder in memory until it exits, and a container keeps it until it is redeployed from a rebuilt image.

There is a verification gotcha worth knowing. Node.js cherry-picked the Brotli patch without bumping Brotli’s internal version, so process.versions.brotli looks identical before and after.

On official upstream builds, the reliable check is whether a new zlib constant is present. If your Node came from a Linux distribution package, it may use the system Brotli library instead, in which case you track your distribution’s Brotli security update rather than the Node version alone.

Do not close the ticket on a scanner’s version comparison, because a backported build can still report its original upstream version.

For distribution and backported builds, confirm the Node.js vulnerability patches against the vendor’s advisory, and keep a record of which Node.js security updates each service has actually received.

Node.js security best practices beyond this batch

This release will fade from the headlines, but the habits it rewards apply to every runtime you operate.

Good Node.js application security treats JavaScript runtime security as a first-class concern, not an afterthought, and a few routines keep you ahead of the next advisory.

  • Treat the runtime as a dependency: teams that would never ship a two-year-old library happily run on a Node.js line that stopped getting security fixes. Track your runtime’s end-of-life date the same way you track a critical package.
  • Keep a real inventory: you cannot patch what you do not know you run. Keep a current record of every Node version across hosts, containers, CI, and single-file binaries, since the forgotten ones are where risk hides.
  • Map untrusted input paths: know which services fetch arbitrary URLs or accept compressed request bodies. Those are the ones that go first when a runtime flaw like this lands.
  • Patch on a schedule, not in a panic: the window between a pre-alert and a working exploit keeps shrinking, so a routine for applying security updates quickly is now a core defense.
  • Use edge controls as a bridge: a web application firewall or proxy rule can block a known attack pattern while you roll out the real fix, which matters most in the first hours after disclosure.

The broader lesson from this batch is that a runtime flaw hits differently from a library one. Once nobody is shipping fixes for your runtime, every new core bug stays open for as long as that runtime stays in production. Node.js dependency security has to include the thing your dependencies run on.

Final word

This round of Node.js vulnerabilities is a reminder that the runtime under your code carries its own CVEs and that patching speed now matters more than ever.

The supported-line fix is boring: bump the version, restart, done. The real work is finding every Node install you run, including the end-of-life ones, and getting them onto a safe version before the next advisory arrives. The research here moved from pre-alert to working exploit in days, so the time to plan is short. Patch the supported lines today, bridge the end-of-life ones, and get the migrations on a calendar.

Blog Book a call Blog

FAQs

Node.js 22.23.4, 24.22.1, and 26.12.1, plus any newer patch release of those lines. Older lines like 25.x, 23.x, 20.x, and earlier are end of life and get no upstream fix.
No exploitation in the wild had been reported as of late October 2026, and it is not in the CISA KEV catalog. Researchers did reach code execution on an unmodified Node.js 24.22.0 build in lab conditions.
Yes, if the parser decompresses Brotli request bodies. Express 5 and body-parser 2.x do, so a client can send a crafted Content-Encoding: br request. Upgrading Node.js is the real fix.
The advisory lists none. Rejecting Brotli-encoded requests at the edge reduces inbound exposure, but it does not protect against Brotli responses your app fetches from other servers. Only upgrading removes the flaw.
Yes, versions before 1.4.4 are affected. Bun 1.4.4 includes the fix, so Bun users should upgrade to that release or newer to close the same Brotli bug.
Author
Author

Chand Prakash

Chand Prakash founded CodeTrade India and continues to lead it as CTO, shaping the technical direction of the company since its early days. He has spent his career solving hard engineering problems and building teams that ship reliable software, with a focus on ERP, e-commerce, and custom enterprise platforms.