Node.js published its October security releases on 21 October 2026, covering the 26.x, 24.x and 22.x lines in v26.12.1, v24.22.1 and v22.23.4. 10 CVEs, four high, three medium, three low.
Three of the ten are the same kind of bug, and reading them together says more than reading any one of them.
Six ways to write one address
Every one of these is a flaw in tls.checkServerIdentity, the function that decides whether the certificate a server presented actually belongs to the thing you connected to.
CVE-2026-105483, high, is the fullwidth one. Write the address with fullwidth Unicode digits instead of ASCII ones and the function stops recognising it as an IP address at all. It then matches the host against the certificate's DNS names and Common Name instead, so a certificate carrying DNS:127.0.0.1, or even a wildcard, is accepted for an IP endpoint it was never issued for. Node.js calls it a regression introduced after the fix for an earlier CVE. It affects 26.x and 24.x.
CVE-2026-106069, high, is the disagreement. Write the address with a leading zero, as 0127.0.0.1, and two pieces of software read it differently. The WHATWG URL rules Node.js uses for normalisation read a leading-zero octet as octal and get 87.0.0.1. The operating system resolver that actually makes the connection reads it as decimal on some platforms, macOS among them, and gets 127.0.0.1. The certificate is then checked against one address while the socket is connected to another.
CVE-2026-106072, medium, is the rest of the family. Node.js names four more spellings: 0177.0.0.1 in octal, 0x7f.0.0.1 in hexadecimal, 2130706433 as a single integer, and the shorthand 127.1. None of these were classified as IP addresses, so each was normalised and matched against the certificate's DNS names. A certificate containing DNS:127.0.0.1 and no IP address entry at all was accepted.
Node.js is explicit about the precondition on that last one: exploitation needs a certificate with a numeric DNS SAN issued by a CA the client already trusts, and a platform resolver that accepts these spellings, such as glibc.
The same release also drops a compromised CA
Under the dependency updates, between c-ares and OpenSSL, sits this line: ca-cert, with the parenthetical eMudhra Intermediate CA Compromise, on all three release lines.
So in one release Node.js fixed three ways to accept the wrong certificate and removed a certificate authority from the trust store. Read the certificate bugs with that line in view. The prerequisite that sounds reassuring, a certificate from a CA your client trusts, is a prerequisite that the same page is quietly dealing with.
Four of the ten are old fixes that did not hold
This is the pattern worth counting, because the advisory states it itself rather than leaving it to inference.
- CVE-2026-105482, the dns.resolve NUL truncation, is described as an incomplete fix of CVE-2026-48930, which covered only dns.lookup and the net and tls host options.
- CVE-2026-105483, the fullwidth bypass above, is a regression introduced after the fix for CVE-2026-48618.
- CVE-2026-105481, the keep-alive socket accepting a response written before the request was sent, is an incomplete fix of CVE-2026-48931.
- CVE-2026-106073, the Permission Model bypass through fs.realpathSync, is an incomplete fix of CVE-2026-21715, which covered only the native variant of the same call.
Four out of ten. A fifth entry, the Permission Model wildcard over-grant, goes out of its way to say it is a different root cause from an earlier CVE, which is the project checking and saying so.
The honest reading is not that Node.js is careless. It is that hostname parsing, path matching and socket reuse are areas where a fix that passes its tests is routinely narrower than the bug, and the only way anyone finds out is when someone looks again.
The quiet one
CVE-2026-106074, medium, has nothing to do with certificates and deserves its own paragraph. The entropy caches behind crypto.randomUUID, crypto.randomUUIDv7 and crypto.randomInt get saved into user-land startup snapshots and into single executable applications.
If any of those functions runs while the snapshot is being built, every process started from that snapshot returns the same values until the cache refills: up to 127 UUIDs and about 1,000 randomInt values. Identifiers meant to be unique collide across processes, and values issued by one process can be predicted by watching another.
A random number generator that is not random after a snapshot is a bug that will not announce itself. It will look like a duplicate key.
What to do
- Update to v22.23.4, v24.22.1 or v26.12.1. End-of-life lines are always affected when a security release lands.
- Grep your code for places that build a connection target from user input and then validate it. The three TLS bugs all live in the gap between normalising a host and resolving it.
- Reject non-canonical address spellings at your own boundary. If a value should be an IPv4 address, parse it as four decimal octets and refuse anything else.
- If you build snapshots or single executable applications, check whether anything calls randomUUID during the build, including indirectly through URL.createObjectURL.
- Pull the eMudhra intermediate from any trust store you manage yourself.
What is not established
- Whether any of these have been exploited. The advisory makes no such claim.
- Which fix maps to which CVE in the commit history. The page does not map them.
- How widely the resolvers that accept these spellings are deployed. Node.js names glibc and macOS as examples, not as a survey.
- What the eMudhra compromise involved. The release notes it as a dependency update and says nothing more.
- Whether the four incomplete fixes share a cause. They are four separate reports by four different people.


