# Node.js TLS: multiple spellings of an IP, conflicting security decisions

> Three Node.js CVEs show how host resolution and certificate validation can interpret a non-canonical IP address differently.

Published: 2026-11-05  
Canonical: https://rootzero.eu/en/research/node-tls-ip-certificate-normalization-2026/

**Patches released October 21, 2026.** Three Node.js vulnerabilities, **CVE-2026-105483, CVE-2026-106069, and CVE-2026-106072**, share a design flaw: the code that decides *where to connect* and the code that decides *which certificate to accept* do not always interpret an IP address representation in the same way. The [Node.js bulletin](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases) provides concrete examples. The lesson is not limited to TLS: any authorization on a name must use the same canonical identity as the actual operation.

## A connection has two potential names

A TLS client receives a character string representing the host. The network layer resolves it to a destination address; certificate verification then compares the advertised host to the certificate's `subjectAltName`. For an IP address, validation should use a SAN entry of type **IP Address**. A SAN entry of type **DNS** with numbers that resemble an IP is not equivalent. If the resolver and validator classify the same string differently, the certificate can be verified for a different identity from the machine actually contacted.

For **CVE-2026-105483**, full-width Unicode digits like `１２７.0.0.1` normalized to an IPv4 for connection, but `tls.checkServerIdentity()` did not recognize them as an IP. It could then accept a certificate whose SAN was a numeric DNS string, or even a DNS pattern, without a corresponding SAN IP. The flaw is an identity *type* confusion, not a cryptographic break of TLS.

For **CVE-2026-106069**, the `0127.0.0.1` example shows another discrepancy: some WHATWG normalization rules read the zero-prefixed byte as octal, while a system resolver on some platforms treats it as decimal. The client can then verify a certificate for **87.0.0.1** while actually connecting to **127.0.0.1**. This result depends on the platform: Node.js notably cites resolver differences as a condition.

For **CVE-2026-106072**, notations such as `0x7f.0.0.1`, `2130706433`, or `127.1` could be accepted as IP addresses by the connection but incorrectly verified as DNS names. The [Node.js project](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases) highlights an important precondition: the attack requests a trusted certificate with a suitable numeric DNS SAN and a resolver that accepts this notation. A simple arbitrary self-signed certificate is not enough in an application that normally validates its chain of trust.

## How to properly test this bug class

An authorized test creates a matrix of representations: canonical form, Unicode digits, leading zeros, hexadecimal, single integer, and abbreviated form. For each, it records **the address actually reached** and **the identity used by the certificate check**. Laboratory certificates are required whose SAN DNS and SAN IP are deliberately different; otherwise a test that “passes” may hide the mismatch. The expected result is that the validation applies to the same endpoint as the connection, with the correct SAN type.

The fixes are in **Node.js 22.23.4, 24.22.1 and 26.12.1** depending on the branch. Libraries that prevalidate URLs or hosts must also check their own rules: a runtime update does not fix an application allowlist that accepts a string and then uses another representation of it. Actual surface area needs to be measured: applications that open TLS connections to user-provided or user-influenced hosts, and those that use destination rules based on host text.

These CVEs provide a clear example of disagreement between components. The TLS guarantee only makes sense if the question “Which server did I contact?” has **the same answer** on resolution and certificate verification.

**Primary source:** [Node.js security publication October 21, 2026](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases).
