Node.js 22.23.4, 24.22.1, 26.12.1: Brotli decoder out-of-bounds write reachable through fetch() and zlib, CVE-2026-111497 (9.2), plus two TLS hostname bypasses
TL;DR
Node.js shipped 22.23.4, 24.22.1 and 26.12.1 on 2026-10-21 with ten CVEs. The one to patch for is CVE-2026-111497: the bundled Google Brotli decoder writes past its buffer on a crafted compressed stream, which the Node.js project describes as permitting remote code execution and Google's CNA record scores 9.2 (CVSS 4.0). It is reachable wherever Node decompresses attacker-controlled Brotli data: a request body handed to node:zlib, or a fetch() to a server the attacker controls, because fetch() decompresses Content-Encoding: br automatically. Three more Highs: two TLS certificate hostname bypasses (CVE-2026-105483, CVE-2026-106069) and a dns.resolve truncation at a NUL byte (CVE-2026-105482). The Brotli bug was reported by OpenAI Codex Security. A public proof of concept on 2026-10-22 reached code execution only on a deliberately weakened build and a crash plus a limited memory read on a standard one; no in-the-wild exploitation was reported as of 2026-10-22. Node 20 and older get no fix. Vercel added firewall rules the same day that cover inbound requests, not responses your functions fetch.
What happened
The Node.js security release page (2026-10-21) lists fixed versions 22.23.4, 24.22.1 and 26.12.1, highest severity High, with these vulnerabilities and credits:
| CVE | Severity (Node.js) | Lines | What the title says | Reported by |
|---|---|---|---|---|
| CVE-2026-111497 | High | 22, 24, 26 | Brotli decoder out-of-bounds write permits remote code execution | OpenAI Codex Security (Khai Tran, Sylvie Mayer); fixed by mcollina and aduh95 |
| CVE-2026-106069 | High | 22, 24, 26 | TLS certificate hostname bypass when the host loosely resolves to an IP address | anagnorisis2peripeteia |
| CVE-2026-105483 | High | 24, 26 | TLS certificate hostname bypass when the IP is written in fullwidth digits | hasanfleyah |
| CVE-2026-105482 | High | 22, 24, 26 | dns.resolve truncates names containing a NUL character |
hasanfleyah |
| CVE-2026-105481 | Medium | 22, 24, 26 | keep-alive socket processes a response written before the request was sent | hasanfleyah |
| CVE-2026-106072 | Medium | 22, 24, 26 | non-canonical IPv4 hostnames let DNS SANs authenticate IP endpoints | br41ny |
| CVE-2026-106074 | Medium | 22, 24, 26 | crypto.randomUUID() and randomInt() entropy caches saved into startup snapshots and single-executable apps, so every process repeats the same values |
gesposito |
| CVE-2026-106070 | Low | 26 | ZipFile returns attacker-controlled prefix bytes after failed header validation |
startimeash |
| CVE-2026-106071 | Low | 26 | Permission Model over-grant via wildcard radix lookup | malikhamzaiqbal |
| CVE-2026-106073 | Low | 22, 24, 26 | Permission Model bypass with fs.realpathSync |
0xoroot |
CVE-2026-111497. Google is the CNA; the record (published 2026-10-22) names Brotli 1.0.3 through 1.2.0 on all platforms, CVSS 4.0 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H), and says a crafted stream lets a remote unauthenticated attacker corrupt adjacent decoder state, disclose memory, cause a denial of service "or potentially execute arbitrary code." Its only reference is the Node.js release page. The Hacker News (2026-10-22) adds that the upstream fix shipped as Brotli 1.2.1, 1.1.1 and 1.0.10 on 2026-10-21, that the change first landed in Brotli's source in February 2026 and became a security release only in October, that the affected code paths are direct node:zlib use and automatic decompression on fetch(), and that the advisory offers no workaround. The same article reports a public proof of concept published 2026-10-22 whose author reached code execution only on a deliberately weakened test build and a crash with a limited read of process memory on a standard build. The Node.js page rates the bug High; Google's record scores it 9.2. This file rates it high on the project's own rating and the state of the public proof, and prints the CNA score beside it.
The TLS pair. Both hostname bypasses let a certificate issued for one name satisfy verification for an IP endpoint written in a non-canonical form. The Hacker News notes that Node.js rates CVE-2026-105483 High while the fixing commit calls it low severity and hard to exploit; this file reports both.
Also in the releases. Undici is updated for three moderate advisories (GHSA-f72v-6w45-q472, GHSA-4qv8-2p9j-2685, GHSA-9fm3-97px-rjf6), c-ares on all lines, OpenSSL on 22 and 24, SQLite on 22. The releases also block eight eMudhra intermediate CA keys reported compromised days earlier and remove three emSign roots from the bundle (nodejs/node PR #66871 and #66877); Node.js does no revocation checking by default, sessions opened before the update are not re-checked, and end-of-life lines do not get the block.
Vercel's position. Vercel's bulletin says it deployed WAF rules on 2026-10-21 that block the inbound attack vector for every project, that blocked requests show in the Firewall dashboard, that the WAF does not cover responses a function fetches from other servers, and that it is rolling patched Node.js across its managed runtimes. Projects pinned to Node 20 on Vercel must move to 22 or 24 and redeploy, because 20 is end of life.
Why it is here: nearly every app this corpus covers runs on one of these three lines, and fetch() of a model-provider, webhook or scraped URL is the default way an agent or a generated backend talks to the world. Brotli is also the encoding most CDNs negotiate.
Am I affected?
node --version. Affected if below 22.23.4 on 22.x, 24.22.1 on 24.x, 26.12.1 on 26.x, or on any line at or below 20.fetch()with noAccept-Encodingoverride negotiates Brotli, so any code that fetches a URL an outside party can influence (a user-supplied webhook, an RSS feed, a tool result, an MCP server) reaches the decoder.zlib.brotliDecompress*on request bodies reaches it directly.- Container images: check the base image tag, not only the host. CI runners and local development count.
- Vercel managed runtimes on 22 and 24 receive the patch from Vercel; self-hosted Next.js, external backends and container images do not.
If you are affected
- Upgrade to 22.23.4, 24.22.1 or 26.12.1 and restart. Rebuild container images on a patched base and redeploy.
- On Node 20 or older, migrate; there is no fix.
- Until patched, you can refuse Brotli from untrusted origins by sending
Accept-Encoding: gzip, deflateon outboundfetch()calls and by rejectingContent-Encoding: brrequest bodies at the edge. Neither is a vendor-stated workaround; the advisory offers none. - For the TLS bypasses, nothing to rotate; upgrade.
- If a host is suspected compromised through a crafted response, follow if your webapp was compromised and rotating cloud credentials.
Prevention
- CI/CD hardening: keep runtime images on supported lines and rebuild on security releases.
- Agent sandboxing: an agent that fetches URLs is a decoder for attacker-chosen bytes; run it with egress limits and without long-lived credentials.
Update 2026-10-26 — the Brotli bug ("Node2Shell") is now a cross-ecosystem patch event: Microsoft, Python, Bun, Java, Envoy and Go all shipped fixes; still no exploitation in the wild
The decoder is Google's C library, so every runtime that bundles it was affected: Brotli 1.0.3 through 1.2.0, fixed upstream in 1.0.10, 1.1.1 and 1.2.1. SecurityWeek (10-26) lists Microsoft's updates for .NET 8.0.33, 9.0.22, 10.0.14 and 11 RC3 and for PowerShell, with Microsoft rating the bug "Exploitation More Likely"; Python's Brotli 1.2.1 and brotlicffi 1.2.1.0 (PYSEC-2026-4322 and 4323 per Aikido); Bun 1.4.4 rebuilt on the fixed library; brotli4j 1.24.0 for Java; Envoy and Istio releases; and Imperva's finding that the public proof of concept is unreliable on standard builds. The same article and The Hacker News (10-24) report no in-the-wild exploitation as of their dates. Socket (10-26) adds the long tail: Go 1.27.3 and 1.26.10 for the eMudhra CA block that Node shipped alongside this release, and the slower runtimes still carrying the old decoder. Aikido's running list (10-23, updated 10-26) is the place to check a Python dependency tree. Node's own fixed versions are unchanged: 22.23.4, 24.22.1, 26.12.1. For an app this corpus covers, the practical additions are: rebuild any Python service that imports brotli or brotlicffi (FastAPI and Streamlit deployments behind compression middleware), update Bun if it is the runtime, and treat a .NET or Java sidecar the same way as the Node process.
Update 2026-10-27 — PHP's Windows builds were rebuilt against Brotli 1.2.1 on 10-26; the PyPI brotli record carries no CVE of its own; FFmpeg and Apache Arrow join the list; still no exploitation recorded
PHP. The PHP Foundation rebuilt the Windows packages on 2026-10-26 as 8.5.12-1, 8.4.27-1, 8.3.36-1 and 8.2.35-1; the PHP version string is unchanged, so php -v cannot tell the builds apart and the -1 package name and the SHA-256 on the downloads page are the signals. The prior week's x64 non-thread-safe builds shipped Brotli 1.2.0. The path is the cURL extension decompressing responses when CURLOPT_ENCODING is set; cURL does not enable that by default, but The Hacker News (10-26) notes Guzzle 7.16.1 and 8.3.1 set an empty value by default, so an app on Guzzle defaults meets the condition, untested on Windows. Workaround stated there: leave CURLOPT_ENCODING unset, or set Guzzle's decode_content to false, which also stops gzip. CISA's October 23 assessment recorded no exploitation and the KEV JSON read on 10-27 does not list CVE-2026-111497.
Python. GHSA-9v8h-qqgm-4m35 (database 2026-10-22, updated 10-23) covers brotli 1.0.3 before 1.2.1 and brotlicffi 1.0.3 before 1.2.1.0 at CVSS 4.0 9.2; its CVE field says "No known CVE" while its references cite CVE-2026-111497, so a scanner keyed to the CVE may not show the Python packages under it.
.NET and the rest. The Register (10-26) confirms Microsoft's out-of-band updates for .NET 8, 9, 10 and 11 published 10-25 at 8.1 on CVSS 3.1 with "Exploitation More Likely" and no evidence of use in attacks; JFrog's "Brotli2Shell" (10-25) adds FFmpeg through libjxl's JPEG XL metadata path, with an exploit JFrog built, and a denial-of-service path in Apache Arrow; Wiz's figures, as The Register reports them, are 91% of cloud environments carrying a vulnerable component and 82% with a publicly exposed Node.js instance.
Update 2026-10-28 — CISA added CVE-2026-111497 to the KEV catalog on 2026-10-27 (due 2026-11-10); the same Node releases also updated bundled undici, whose eight 10-15 CVEs have their own file
CISA's KEV JSON read on 2026-10-28 lists CVE-2026-111497 with dateAdded 2026-10-27, vendor "Google", product "Brotli", name "Google Brotli Unchecked Return Value Vulnerability", CWE-252 and CWE-787, dueDate 2026-11-10, knownRansomwareCampaignUse Unknown, and a note that the entry covers an open-source component used by many products, pointing at the Brotli v1.2.1 release. The 10-27 update above recorded the catalog as not listing it; that was true when read on 10-27 and is not now. A KEV listing is CISA's statement that exploitation has been observed; the catalog entry gives no detail on where, and no vendor in this file's list has published an exploitation report as of 2026-10-28. Federal agencies have until 2026-11-10 under BOD 26-04; everyone else should read the date as the deadline it is.
The same 2026-10-21 Node releases list "Undici on 26.x, 24.x, 22.x" among dependency updates without naming a CVE. The undici project published eight CVEs on 2026-10-15, fixed in 6.29.1, 7.30.1 and 8.12.2, including cross-user cache poisoning through redirects and a silently dropped checkServerIdentity pin on the default fetch() dispatcher; they are written up in their own file. The Node changelogs show 26.12.1 updating undici to 8.12.2, 24.22.1 to 7.30.1 and 22.23.4 to 6.29.1, the three fixed lines, so a Node upgrade to the 10-21 releases closes both.
Update 2026-11-04 — Node.js pre-announced its next security release for 2026-11-11: 26.x, 24.x and 22.x, highest severity High, no CVEs or counts yet
The Node.js vulnerability blog's "Wednesday, November 11, 2026 Security Releases" post (last updated 2026-11-03) says releases for 26.x, 24.x and 22.x will ship on or shortly after 2026-11-11, that the highest severity fixed in each line is High, and nothing else: no CVE ids, no counts, no subsystems. The October post above pre-announced a count that changed on release day, so this entry records the date and the lines only. The release-day post is the fact source. End-of-life lines (20.x and earlier) are affected and will not be fixed.
Sources
- Node.js — Wednesday, October 21, 2026 Security Releases — fetched 2026-10-22: fixed versions, the ten CVEs with severities, affected lines and credits, the dependency and CA-bundle updates, and the end-of-life note.
- CVE Services — CVE-2026-111497 — fetched 2026-10-22: Google CNA, published 2026-10-22, Brotli 1.0.3 through 1.2.0, CVSS 4.0 9.2 and vector, the description quoted above, reference to the Node.js page.
- The Hacker News — Node.js Brotli Decoder Bug Could Allow Remote Code Execution in All Supported Versions — fetched 2026-10-22 (2026-10-22): the
fetch()andnode:zlibcode paths, the Brotli 1.2.1/1.1.1/1.0.10 releases, the February source change, the public proof-of-concept outcome, the severity disagreement on CVE-2026-105483, the eMudhra block, Vercel's statement, no exploitation reported. - Vercel — Node.js security advisory bulletin — fetched 2026-10-22: the WAF rules, their limit to inbound requests, the managed-runtime rollout, and the Node 20 migration instruction.
- Hacker News (Algolia) — "Node.js: 5 vulnerabilities found, update now" and "Node.js security advisory: Brotli decoder RCE (CVE-2026-111497)" — read 2026-10-22: both stories dated 2026-10-22 linking the Node.js page and the Vercel bulletin.
- Related in this corpus: Next.js out-of-band release of 2026-10-14 for the framework layer above this runtime.
- 2026-10-26 update sources — SecurityWeek — Node2Shell: Brotli Flaw Triggers Patching Across Microsoft, Node.js, Python Packages — fetched 2026-10-26: the Microsoft, Python, PowerShell and Bun fixes, Microsoft's exploitability rating, Imperva on the proof of concept, no exploitation reported.
- Aikido — Python packages vulnerable to Node2Shell (Brotli, CVE-2026-111497) — fetched 2026-10-26 (2026-10-23, updated 10-26): the Python package list, PYSEC ids, brotli4j, Envoy and Istio, mitigations.
- Socket — eMudhra and the Brotli long tail — fetched 2026-10-26: the Go releases for the eMudhra block and the remaining runtimes.
- The Hacker News — Brotli decoder flaw behind Node.js RCE also hits Bun and Python — fetched 2026-10-26 (2026-10-24): Bun 1.4.4, the Python packages, no exploitation reported.
- 2026-10-27 update sources — The Hacker News — PHP Issues Second Windows Security Update in Five Days to Fix Brotli Code Execution Flaw (fetched 2026-10-27: dated 10-26, the four
-1builds, Brotli 1.2.0 to 1.2.1, the cURL and Guzzle conditions, the workarounds, the CISA 10-23 note); PHP — 2026 news archive, 2026-10-26 entry (the Windows rebuild notice THN links); GitHub Advisory Database — GHSA-9v8h-qqgm-4m35 (fetched 2026-10-27: 2026-10-22, the two pip packages and ranges, 9.2, "No known CVE" beside a CVE-2026-111497 reference); The Register — Microsoft releases emergency .NET security fixes for Google Brotli bug (fetched 2026-10-27: .NET 8 to 11, 10-25, 8.1, "Exploitation More Likely", the FFmpeg, Arrow and Wiz figures, the devblogs and MSRC links); JFrog — Brotli2Shell: Beyond Node(2Shell) and HTTP(2Shell) (listed on JFrog's index dated 25 Oct 2026; the FFmpeg and Arrow findings are as The Register reports them); CISA KEV JSON read 2026-10-27 (CVE-2026-111497 absent). - 2026-10-28 update sources — CISA KEV JSON feed (read 2026-10-28: the CVE-2026-111497 entry with
dateAdded2026-10-27,dueDate2026-11-10, CWEs, the component note); Node.js — October 2026 Security Releases (re-read 2026-10-28: the undici dependency line); nodejs/node — CHANGELOG_V26.md, CHANGELOG_V24.md, CHANGELOG_V22.md (fetched 2026-10-28: the undici bump in each 10-21 release); the undici CVE records are cited in the undici file. - 2026-11-04 update source — Node.js — Wednesday, November 11, 2026 Security Releases — fetched 2026-11-04 (last updated 2026-11-03): the pre-announcement, the three lines, highest severity High, no ids.