Creuto is now an OpenAI Select Partner Read More
Learn about the Node.js Brotli vulnerability, its potential security risks, affected versions, and practical steps to protect your applications and production infrastructure.

The Node.js security release October 2026 landed on 21 October, fixing ten CVEs across the 22.x, 24.x and 26.x lines: upgrade to 22.23.4, 24.22.1 or 26.12.1. Four are rated High, including a Brotli decoder out-of-bounds write that permits remote code execution. The harder problem is proving the patch actually took.
That second part is where most of this week's advice stops. "Redeploy and verify" is sound guidance and almost no one writes down what verifying means — and for several fixes in this release, a correct version string on a correct binary still leaves the flaw live in a running process.
Ten CVEs: four High, three Medium, three Low, per the Node.js advisory of 21 October 2026. The four High-severity entries are the ones that set the timetable.
| CVE | What it is | Lines affected |
|---|---|---|
| CVE-2026-111497 | Brotli decoder out-of-bounds write permits remote code execution | 26.x, 24.x, 22.x |
| CVE-2026-105482 | dns.resolve truncates names containing a NUL character | 26.x, 24.x, 22.x |
| CVE-2026-106069 | TLS hostname bypass when the host loosely resolves to an IP address | 26.x, 24.x, 22.x |
| CVE-2026-105483 | TLS hostname bypass when the IP is written in fullwidth digits | 26.x, 24.x |
Below those, three Medium issues: a keep-alive socket that processes a response written before its request was sent (CVE-2026-105481), non-canonical IPv4 hostnames letting DNS SANs authenticate IP endpoints (CVE-2026-106072), and crypto.randomUUID() and randomInt() entropy caches being saved into startup snapshots and single-executable applications, so every process repeats the same values (CVE-2026-106074). Three Low issues cover a ZipFile prefix-byte leak, a Permission Model filesystem over-grant via wildcard radix lookup, and a Permission Model bypass with fs.realpathSync (CVE-2026-106073).
Now read what the advisory does not contain, because it shapes your triage. There is no CVSS score for any of the ten — only the labels High, Medium and Low. There are no affected version ranges, just which release lines are involved. And there is no workaround or mitigation text for any of them. Each entry names the reporter and the fixer and stops.
The release also refreshes bundled dependencies: c-ares and Undici on all three lines, the CA certificate store on all three (the eMudhra intermediate CA compromise), OpenSSL on 24.x and 22.x, and SQLite on 22.x. Those are not in the CVE count, and one of them has a verification trap we come back to below.
As of 23 October 2026, nodejs.org lists 24.22.1 as Latest LTS and 26.12.1 as Current, and nothing newer than the 21 October trio has shipped on any line. So the upgrade target is unambiguous — but the line you upgrade onto is a decision that changed three days before the advisory.
The official release schedule puts the dates in an awkward cluster.
| Line | Patched version | Status | End of life |
|---|---|---|---|
| 26.x | 26.12.1 | Current — Active LTS from 28 October 2026 | 30 April 2029 |
| 24.x | 24.22.1 | Maintenance LTS since 20 October 2026 | 30 April 2028 |
| 22.x | 22.23.4 | Maintenance LTS | 30 April 2027 |
Node.js 24 entered Maintenance LTS on 20 October — the day before this release — and 26.x becomes Active LTS on 28 October, five days from now. If a team is standardising a line this quarter, it is making that call at the exact moment the labels flipped, and "upgrade to the latest LTS" now points at a line in maintenance. Patch onto your current line today; decide the target line separately, with 22.x's April 2027 end date in front of you rather than behind the patch.
Here is the argument, and it is the reason this release deserves more than a version bump in a change log. Four distinct things survive a correct upgrade, and each one has its own check.
Before any of them, one inventory problem. A host rarely has one Node.js. There is the system package, whatever a version manager installed, the copy inside each container image, and the runtime bundled into build tooling — and node -v on a shell path tells you about exactly one of them. TuxCare's inventory loop walks every node on PATH and prints each one's version:
type -ap node | while read -r n; do echo "$n $("$n" -v)"; doneRun that before you conclude a host is clean. Mixed fleets are where this release gets expensive, because the triage question is per-binary and the version table is per-line.
Startup snapshots and single-executable applications. CVE-2026-106074 bakes the entropy cache into the artefact. Upgrading the runtime that builds your snapshot or SEA fixes nothing until you rebuild the artefact itself, because the duplicate values are already baked in — the mechanism we covered when Node randomUUID started returning duplicate values from startup snapshots. If you ship an SEA, the patched runtime is step one of two.
Resumed TLS sessions. The CA refresh is a compiled-in blocklist of eMudhra intermediates, and TuxCare notes that TLS sessions resumed from before the upgrade are not re-verified until they time out. A long-lived connection pool keeps trusting what you just distrusted. This is the same cutoff that drove Chrome's eMudhra root removal on 27 October, and the blocklist does not apply to end-of-life lines at all.
Distro-packaged builds may link system Brotli. If your Node binary links the operating system's Brotli library rather than the bundled copy, the Brotli fix arrives through your package manager, not your runtime upgrade. TuxCare's checks are ldd "$(command -v node)" | grep -i brotli on Linux and otool -L "$(command -v node)" | grep -i brotli on macOS. The fixed upstream Brotli releases are 1.2.1, 1.1.1 and 1.0.10.
Processes that were never restarted. A patched binary on disk is not a patched process in memory. TuxCare's one-liner for confirming every Node process started after the update:
ps -eo pid,lstart,args | grep -E '[n]ode( |$)'And for confirming the fixed decoder is actually present in the running interpreter, rather than inferring it from a version string:
node -p "'BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH' in require('zlib').constants"TuxCare is explicit that this one is reliable only for official upstream builds, which is the caveat that makes the ldd check worth running alongside it. Treat these as evidence to attach to the ticket, not a formality — this is exactly the gap between "patched" and "verified" that we design deployment and verification pipelines to close, because the alternative is a change log that records remediation nobody confirmed.
With no mitigation text in the advisory, the available stopgaps are all application-side or proxy-side, and TuxCare is careful to label them as not fixes: setting inflate: false on body parsers, disabling decompression in HTTP clients such as axios or got, and rejecting Content-Encoding: br at the reverse proxy. Each closes the inbound half of the Brotli exposure and buys a scheduling window.
None of them closes the outbound half, because fetch() has no off switch for Brotli. A response from a hostile or compromised upstream reaches your process without anyone sending you a request, and Astra's write-up adds websocket frames with Brotli compression to the same attack surface. If a stopgap is the plan for this week, write down which half it covers, because a change log that records it as remediation is wrong.
One scheduling note worth carrying into the next cycle. TuxCare counts seven days from the Node.js project's pre-alert on 14 October to the release on 21 October. That pre-alert window is the realistic amount of warning you get for a release of this size, and it is enough time to stage an upgrade path — but only for a team that already knows which binaries and images it runs.
As of 22 October, Astra Security's write-up states that "No in-the-wild exploitation has been reported yet, but the Brotli RCE and TLS bypasses make the window short". We have not been able to confirm from a primary source whether CVE-2026-111497 has been added to CISA's Known Exploited Vulnerabilities catalogue, so we are not going to claim either way.
The public proof-of-concept picture is genuinely unsettled, and the two accounts of it do not agree — we worked through that divergence separately in what the node2shell Brotli RCE actually proves. The short version: nobody has published a reliable exploit against a stock build, which makes this a patch-now bug rather than a drop-everything bug.
One concrete reason to read the primary source yourself. Astra's page credits CVE-2026-111497 as "Reported by mcollina and fixed by aduh95". The Node.js advisory credits the report to OpenAI Codex Security — Khai Tran and Sylvie Mayer — and thanks mcollina and aduh95 for the fix. Secondary coverage of this advisory is already drifting, two days in, on a detail that is trivial to check. Assume the same drift in the parts that are harder to check.
The advisory is unambiguous: "End-of-Life versions are always affected when a security release occurs." Node.js 20 reached end of life on 30 April 2026, 25.x on 1 June 2026 and 23.x on 1 June 2025, per the release schedule. There is no patched build coming for any of them, and the eMudhra CA blocklist does not reach them either.
If that describes your fleet, this is a line migration rather than a patch, and the choice of target line is the one in the table above — which is the same decision we laid out in which line to target after Node 20's end of life. Commercial extended-support builds exist and buy you time; they do not change the migration arithmetic.
Upgrade to 22.23.4, 24.22.1 or 26.12.1 on your current line, then work the reachability list rather than the version list. For the Brotli bug that means public routes that decompress request bodies, outbound fetch() calls to parties you do not control, and direct node:zlib use on untrusted input. For the three High-severity TLS and DNS bugs, which have attracted far less attention, it means anything that validates a certificate against a hostname you did not canonicalise yourself; we covered those four together in the TLS hostname bypasses in this release.
Then close the loop the version table cannot: rebuild every snapshot and SEA, restart every process, recycle long-lived TLS connection pools, and check whether your binary links system Brotli. The entropy-cache fix, the CA blocklist and — on distro builds — the Brotli fix itself all need a step beyond the upgrade, and the one thing worse than an unpatched runtime is a deployment record that says you patched it.
The October 2026 Node.js security release fixed ten CVEs across the 22.x, 24.x and 26.x lines: four High, three Medium and three Low. The four High-severity issues are a Brotli decoder out-of-bounds write permitting remote code execution, a dns.resolve NUL truncation bug, and two TLS certificate hostname verification bypasses.
Upgrade to Node.js 22.23.4, 24.22.1 or 26.12.1, matching your current release line. As of 23 October 2026 nodejs.org lists 24.22.1 as Latest LTS and 26.12.1 as Current, and no newer release has shipped on any supported line since 21 October.
Checking the binary is not enough, because a patched file on disk is not a patched process in memory. Run ps -eo pid,lstart,args and filter for node to confirm every process started after the upgrade, then confirm the fixed decoder is present in the running interpreter rather than inferring it from a version string.
Yes. The Node.js advisory states that end-of-life versions are always affected when a security release occurs. Node.js 20 reached end of life on 30 April 2026 and receives no patched build, so affected estates need a line migration to 22.x, 24.x or 26.x rather than a patch.
Restarting is necessary but not always sufficient. A restart picks up the patched binary, but startup snapshots and single-executable applications must be rebuilt with the patched runtime, and long-lived TLS sessions resumed from before the upgrade are not re-verified against the new certificate blocklist until they time out.
Node.js 26 becomes Active LTS on 28 October 2026 and reaches end of life on 30 April 2029, according to the official nodejs/Release schedule. Node.js 24 entered Maintenance LTS on 20 October 2026, so the two line labels changed within days of this security release.
Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.