October Node.js Fixes Reach Beyond Brotli
October’s Node.js security releases address a collection of trust failures: names can change meaning between checks, client responses can arrive too early, and prebuilt applications can repeat supposedly fresh random values. The useful starting point is the behaviour of each workload, followed by the runtime that actually executes it.
The release cohort contains ten CVEs: four High, three Medium and three Low. The corrected upstream releases are 22.23.4, 24.22.1 and 26.12.1. These security builds are available from 21 October.
Ten findings with different exposure paths
The matrix uses the individual grades in the security bulletin. Affected lines describe vulnerable builds in those families, not every historical version or a verified inventory of an organisation’s systems. Seven findings apply to the supported 22.x line, eight to 24.x and all ten to 26.x.
| CVE, Node grade and affected lines | Principal issue |
|---|---|
| CVE-2026-105482 High 22.x, 24.x, 26.x |
DNS name truncation |
| CVE-2026-105483 High 24.x, 26.x |
Fullwidth address verification |
| CVE-2026-106069 High 22.x, 24.x, 26.x |
Address interpretation mismatch |
| CVE-2026-111497 High 22.x, 24.x, 26.x |
Brotli memory corruption |
| CVE-2026-105481 Medium 22.x, 24.x, 26.x |
Premature client responses |
| CVE-2026-106072 Medium 22.x, 24.x, 26.x |
Numeric certificate names |
| CVE-2026-106074 Medium 22.x, 24.x, 26.x |
Repeated snapshot randomness |
| CVE-2026-106070 Low 26.x |
ZIP content disagreement |
| CVE-2026-106071 Low 26.x |
Wildcard permission overreach |
| CVE-2026-106073 Low 22.x, 24.x, 26.x |
Missing path permission checks |
Brotli input can reach process memory
The Brotli row concerns an application decompressing attacker-supplied data through node:zlib. Malformed input can corrupt decoder memory, with possible crashes, disclosure or code execution.
Name checks need to describe the same destination
The DNS finding completes an earlier repair that covered lookup and connection-host interfaces but missed dns.resolve*() and dns.reverse(). A NUL in an application-supplied name can end the string passed to the resolver. If validation examines the full name but resolution uses its prefix, an allowlist can approve one destination while the application acts on another.
The fullwidth-digit TLS issue is a regression after an earlier fix. An unusual spelling resolves to an IP address, while certificate checks compare it with certificate DNS names or the Common Name and can accept a certificate without the matching IP address SAN. This particular regression excludes 22.x.
The other two TLS cases have distinct prerequisites. Leading-zero addresses can acquire different meanings under URL normalisation and the operating system resolver, so the certificate can be checked against an address other than the connected endpoint. Separately, an accepting resolver and a numeric DNS SAN certificate from a trusted CA can let non-canonical IP spellings pass without the required IP SAN. These are identity-matching failures with specific certificate and platform conditions.
The release notes group the last two TLS fixes under a High-labelled change. The individual security bulletin rates the numeric-DNS-certificate case Medium; that grouped heading does not change its row above.
Client traffic and stored randomness need attention too
The HTTP Agent issue is another incomplete repair. Unsolicited response bytes can reach an idle keep-alive socket but remain unread when it is assigned to a later request. Removing the guard at that point lets old data become the new request’s response. Synchronous event-loop work is one documented timing condition. This concerns client connection reuse, not a general claim that every server accepts arbitrary requests.
The randomness finding requires affected APIs to run while a startup snapshot is built, directly or through another API. Saved caches can then give different processes matching values until replenished: up to 127 UUIDs and roughly 1,000 integer results. The affected APIs include crypto.randomUUID(), crypto.randomUUIDv7() and crypto.randomInt(). Rebuild affected snapshots and snapshot-bearing single executable applications with a corrected, compatible runtime; replacing an unrelated system executable does not replace an embedded one.
Low grades still describe security boundaries
The ZIP issue requires a mismatch between local and central headers, followed by reading the entry’s modified property or compacting the archive. An invalid header remains cached without a content offset; later reads can return attacker-chosen prefix bytes. An attacker-controlled CRC can still validate those bytes. A scanner can therefore approve content different from what another extractor produces.
The wildcard permission defect needs a filesystem read or write grant directly beneath the permission tree’s root, such as the only grant for that scope. A path shorter than the wildcard prefix can incorrectly inherit that permission. Its root cause differs from the earlier wildcard flaw; it is not simply the same repair being repeated.
The separate path-resolution defect misses read checks in fs.realpathSync(). An earlier repair covered only its native variant. Code running under --permission with restricted --allow-fs-read can still discover paths, check existence and resolve symlink targets beyond its authorised directories. Keep that information-disclosure boundary distinct from unrestricted file-content access.
The dependency work extends beyond the ten rows
The releases also replace bundled components and trust data. Those dependency advisories are additional work, not extra rows silently added to the ten-CVE cohort. The branch-specific versions below come from the actual release notes, including the commit list where a summary omits a change.
| Security release | Bundled dependency changes |
|---|---|
| 22.23.4 | c-ares 1.34.9 NSS roots 3.131.1 OpenSSL 3.5.9 SQLite 3.53.4 Undici 6.29.1 |
| 24.22.1 | c-ares 1.34.9 NSS roots 3.131.1 OpenSSL 3.5.9 SQLite: none listed Undici 7.30.1 |
| 26.12.1 | c-ares 1.34.9 NSS roots 3.131.1 OpenSSL: none listed SQLite: none listed Undici 8.12.2 |
“None listed” means no such dependency upgrade is specified in that release, not that the component is absent or unaffected. All three runtimes cherry-pick the Brotli correction; a generic upstream library version is not a substitute for the correct runtime or distribution package.
Upgrade the workload that is actually running
Prioritise workloads that decompress untrusted Brotli input, accept attacker-influenced destinations, make affected outbound requests or rely on the affected permission checks. Check application code and deployment configuration for the actual path. Severity helps describe the consequence; it does not establish that a particular machine exposes it.
Identify the runtime in each service, container, build image and packaged application. Select a supported corrected release through its actual delivery route, rebuild images and affected prebuilt executables, then redeploy or restart the workloads. Confirm the version reported by the running process and test DNS, certificate validation, outbound requests and any snapshot-based startup. Updating application packages alone does not prove the runtime changed.
Support status also needs its date. The 22 and 24 lines are in Maintenance LTS, while 26 is Current. Node recommends LTS lines for production. Older unsupported lines need a migration or an explicitly verified separate support route. Their omission from the three corrected builds does not establish that they are safe, or that every individual flaw affects every old version.
Scope
Counted here: the ten individual findings in the dated Node security bulletin, with dependency advisories kept separate. Installed state and application exposure still require verification by the operator.
Update, 23 October 2026: CVE records published
Nine Node-related CVE records have now been published and substantially repeat the 21 October release bulletin. They do not provide independent attack observations. The publication of a record is separate from evidence that a vulnerability has been exploited.
Update, 27 October 2026: exploitation confirmed for Brotli
CISA added the Brotli component to its exploitation catalogue on 27 October. That adds urgency for workloads that decompress untrusted input, but does not establish that every Node.js deployment has been attacked. The catalogue records ransomware involvement as unknown.
Update, 28 October 2026: Node.js 26 enters LTS
Node.js 26 has entered LTS. Select a supported corrected release through the appropriate delivery route and continue to verify the actual runtime and workload. BlackTree’s 28 October Brotli analysis covers the later exploitation development separately.
Update, 29 October 2026: dependency exposure and deployment checks
The c-ares update includes reply-source matching and memory-lifetime corrections. The documented reply mismatch needs multiple configured DNS servers; a separate cancellation fault requires a cancellation call inside a query callback after connection failure. Those conditions matter when assessing exposure, and neither should be relabelled as the ten-row DNS truncation issue.
Undici also repairs two different client paths. A malicious endpoint must first establish an accepted TLS 1.2 connection. Renegotiation with another CA-trusted certificate whose hostname fails verification can then crash the client process; TLS 1.3 does not support that renegotiation. The Agent flaw drops function-valued TLS options, including custom pinning callbacks. The peer must still pass Node’s default chain and hostname checks; only the additional custom verification is lost. Options supplied through connect are unaffected.
The trust change addresses compromised eMudhra intermediate keys. Node’s embedded trust store does not receive the browser’s automatic revocation protection. The correction adds a public-key blocklist as well as updated roots. Its documented limit is important during deployment: sessions resumed from before the upgrade are not reverified until their timeout. A replaced file alone does not settle the state of existing connections.
These components have their own timelines. OpenSSL’s security release predates this Node update, and SQLite’s selected patch dates to July. Their inclusion does not turn every upstream correction into a newly discovered, remotely reachable flaw in every application.
Node.js source attribution and licence
This original BlackTree review draws on the Node.js security bulletin and the linked release notes. The Node.js website material is available under the MIT licence reproduced below.
MIT License
Copyright Node.js Website WG contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


