GitHub Advisoryadvisory · npm
GHSA-2vr4-cq9g-pvrc ip-address: no classifier recognizes the NAT64 local-use range 64:ff9b:1::/48, allowing SSRF and trust-boundary bypass
MEDIUM
Official page ↗
- Aliases
- CVE-2026-101910
- Ecosystem
- npm
- Packages
- ip-address
- Severity
- Moderate
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:H/SI:N/SA:N
- Weaknesses
- CWE-918
- Reviewed
- 2026-09-28
Affected packages
• npm ip-address: >= 10.2.0, < 10.5.1 → fixed in 10.5.1
Description
Summary
No classifier on `Address6` recognizes the NAT64 local-use range `64:ff9b:1::/48` (RFC 8215). `isPrivate()`, `isLoopback()`, `isLinkLocal()` and their siblings all return `false` for every address in it, so an internal IPv4 destination written through a local-use NAT64 prefix (`64:ff9b:1:7f00:0:100::` for `127.0.0.1`, `64:ff9b:1:a9fe:a9:fe00::` for `169.254.169.254`) reads as an ordinary global address. `getType()` names the range `'NAT64 (local-use)'`, so the library knows what the address is and classifies it as nothing.
An application that builds a network trust-boundary decision on these checks (for example a filter intended to block Server-Side Request Forgery, or SSRF) will classify an internal target as external and allow the request. SSRF is an attack in which a user-supplied address coaxes the server into making a request to an internal destination the user could not otherwise reach, such as a loopback service or a cloud metadata endpoint.
Details
The fix for GHSA-22jq-vg5j-6vgg (10.2.1) classifies IPv4-mapped (`::ffff:0:0/96`) and NAT64 well-known (`64:ff9b::/96`) addresses by their embedded IPv4 address: `embeddedIPv4()` in `src/ipv6.ts` decodes the trailing 32 bits and every special-use classifier delegates to the resulting `Address4`. Those are the only two ranges `embeddedIPv4()` handles.
The local-use range differs in kind from the well-known prefix, which is why extending the decoder does not fix it. RFC 8215 reserves `64:ff9b:1::/48` so an operator can carve their own NAT64 prefix out of it, of any length RFC 6052 allows (`/48`, `/56`, `/64`, or `/96`). Where the IPv4 address sits depends on that choice: `127.0.0.1` is `64:ff9b:1:7f00:0:100::` under a `/48` prefix and `64:ff9b:1::7f00:1` under a `/96` prefix, and each of those decodes to a different address under the other prefix length. There is no single embedded IPv4 address for the library to classify by.
What is well-defined is the range as a whole. The IANA IPv6 Special-Purpose Address Registry lists `64:ff9b:1::/48` as not globally reachable, and Python's `ipaddress` module reports `is_private` as `True` and `is_global` as `False` for every address in it. `isPrivate()` covered ULA (`fc00::/7`) plus the decoded mapped and well-known cases, and nothing in the local-use range.
Affected versions
`>= 10.2.0, getType()', new Address6(h).getType());
}
```
On affected versions:
```
BLOCK 64:ff9b::7f00:1 -> getType() NAT64 (well-known)
ALLOW 64:ff9b:1:7f00:0:100:: -> getType() NAT64 (local-use)
ALLOW 64:ff9b:1::7f00:1 -> getType() NAT64 (local-use)
```
Remediation
Upgrade to the patched release. In the fix, `isPrivate()` returns `true` for every address in `64:ff9b:1::/48`, alongside ULA and the decoded mapped and well-known cases. The range is reported private as a whole rather than by a decoded IPv4 address, for the reason given above; `toAddress4Nat64(prefix)` remains the way to decode an address under a known deployment prefix. `isLoopback()` and `isLinkLocal()` are unchanged for this range, since without the prefix length the library cannot know which IPv4 address is embedded.
If you cannot upgrade immediately, test the range directly:
```js
const NAT64_LOCAL_USE = new Address6('64:ff9b:1::/48');
const localUse = new Address6(host).isHostInSubnet(NAT64_LOCAL_USE);
```
A note on SSRF defense
These methods are address classifiers, not a complete SSRF defense. Regardless of this fix, a robust SSRF guard must resolve the hostname and validate the *resolved* IP against the socket it connects to, and account for DNS rebinding and redirects. Treat these checks as one layer, not the only one.
Related
Alias · CVE (1)
- CVE-2026-101910 ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. vulnerability
Weakness · CWE (1)
- CWE-918 Server-Side Request Forgery weakness
References
- https://github.com/beaugunderson/ip-address/security/advisories/GHSA-2vr4-cq9g-pvrc web
- https://nvd.nist.gov/vuln/detail/CVE-2026-101910 advisory
- https://github.com/beaugunderson/ip-address/commit/ab3dc88bcf5374344168a2ba075ca7ac4ff257f8 web
- https://github.com/beaugunderson/ip-address package
- https://github.com/beaugunderson/ip-address/releases/tag/v10.5.1 web