CVE-2026-101913
ip-address: Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10, allowing SSRF and trust-boundary bypass to on-link hosts
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
6.3
ip-address: Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10, allowing SSRF and trust-boundary bypass to on-link hosts
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
- Record
CVE-2026-101913- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
EUVDEUVD-2026-88399
6.3
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
- Record
EUVD-2026-88399- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-rpw4-54j3-4h4q
6.3
ip-address: Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10, allowing SSRF and trust-boundary bypass to on-link hosts
Summary
Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10. Link-local unicast is the whole /10 under RFC 4291 §2.4 and the IANA IPv6 Special-Purpose Address Registry, so the method returns false for every link-local address outside the one /64 that stateless address autoconfiguration happens to use. new Address6('fe81::1').isLinkLocal() is false.
The library contradicts itself on the same object: for fe81::1, getType() returns 'Link-local unicast', getScope() returns 'Link local', and isHostInSubnet(new Address6('fe80::/10')) returns true, while isLinkLocal() returns false.
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 a link-local target as unremarkable 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.
Details
isLinkLocal() in src/ipv6.ts compares the first 64 bits of the address against a literal string:
// Zeroes are required, i.e. we can't check isHostInSubnet with 'fe80::/10'
if (
this.getBitsBase2(0, 64) ===
'1111111010000000000000000000000000000000000000000000000000000000'
) {
return true;
}
The comparison requires the first 64 bits to be exactly fe80:0000:0000:0000, so it accepts 2⁶⁴ of the 2¹¹⁸ addresses in fe80::/10. The comment states a premise the library disproves: getType() classifies the same range with isHostInSubnet against the 'fe80::/10': 'Link-local unicast' entry in src/v6/constants.ts, and Address4.isLinkLocal() is a plain isHostInSubnet test against 169.254.0.0/16. RFC 4291 §2.5.6 constrains the format of an autoconfigured link-local address; it does not define the range, and reading it as the definition is the likeliest origin of the /64 comparison.
The IPv4-mapped and NAT64 well-known paths of isLinkLocal() are unaffected: ::ffff:169.254.169.254 and 64:ff9b::a9fe:a9fe are classified by their embedded IPv4 address and report true.
Affected versions
<= 10.5.0. The comparison has had this shape since Address6.isLinkLocal() was introduced, so every release exposing the method is affected.
Impact
Every well-formed address in fe80::/10 outside fe80::/64 is parsed successfully, isValid() is true, and the classifier reports something untrue about it. No other classifier catches these addresses: isPrivate() covers ULA (fc00::/7), not link-local.
| Address | isLinkLocal() | getType() | getScope() |
|---|---|---|---|
| fe80::1 | true | Link-local unicast | Link local |
| fe81::1 | false | Link-local unicast | Link local |
| fe8f::1 | false | Link-local unicast | Link local |
| febf::1 | false | Link-local unicast | Link local |
| fe80:0:0:1::1 | false | Link-local unicast | Link local |
| fe80::1:0:0:0:1 | false | Link-local unicast | Link local |
Python's ipaddress module, the IN6_IS_ADDR_LINKLOCAL macro in netinet6/in6.h, and Linux's ipv6_addr_type() all apply a ten-bit prefix test and classify every row above as link-local.
A request admitted through a guard built on isLinkLocal() reaches a link-local host on the server's own segment: a neighboring machine or the on-link router. An IPv6 link-local destination generally needs a zone index and a neighbor on the same link, so the reach is the server's own segment rather than the internet or a universal metadata endpoint, and the severity reflects that.
Proof of concept
npm i [email protected], then:
const { Address6 } = require('ip-address');
// A guard of the shape the library documents.
function isBlocked(host) {
const a = new Address6(host);
return a.isLoopback() || a.isLinkLocal() || a.isPrivate() || a.isMulticast() || a.isUnspecified();
}
for (const h of ['fe80::1', 'fe81::1', 'febf::1',…
- Record
GHSA-rpw4-54j3-4h4q- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
NVD
6.3
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
- Record
CVE-2026-101913- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
OSV
6.3
ip-address: Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10, allowing SSRF and trust-boundary bypass to on-link hosts
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
- Record
CVE-2026-101913- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-101913
6.3
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
- Record
DEBIAN-CVE-2026-101913- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Updated
- 2026-11-02
Show 8 moreShow less
OSVGHSA-rpw4-54j3-4h4q
6.3
ip-address: Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10, allowing SSRF and trust-boundary bypass to on-link hosts
Summary
Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10. Link-local unicast is the whole /10 under RFC 4291 §2.4 and the IANA IPv6 Special-Purpose Address Registry, so the method returns false for every link-local address outside the one /64 that stateless address autoconfiguration happens to use. new Address6('fe81::1').isLinkLocal() is false.
The library contradicts itself on the same object: for fe81::1, getType() returns 'Link-local unicast', getScope() returns 'Link local', and isHostInSubnet(new Address6('fe80::/10')) returns true, while isLinkLocal() returns false.
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 a link-local target as unremarkable 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.
Details
isLinkLocal() in src/ipv6.ts compares the first 64 bits of the address against a literal string:
// Zeroes are required, i.e. we can't check isHostInSubnet with 'fe80::/10'
if (
this.getBitsBase2(0, 64) ===
'1111111010000000000000000000000000000000000000000000000000000000'
) {
return true;
}
The comparison requires the first 64 bits to be exactly fe80:0000:0000:0000, so it accepts 2⁶⁴ of the 2¹¹⁸ addresses in fe80::/10. The comment states a premise the library disproves: getType() classifies the same range with isHostInSubnet against the 'fe80::/10': 'Link-local unicast' entry in src/v6/constants.ts, and Address4.isLinkLocal() is a plain isHostInSubnet test against 169.254.0.0/16. RFC 4291 §2.5.6 constrains the format of an autoconfigured link-local address; it does not define the range, and reading it as the definition is the likeliest origin of the /64 comparison.
The IPv4-mapped and NAT64 well-known paths of isLinkLocal() are unaffected: ::ffff:169.254.169.254 and 64:ff9b::a9fe:a9fe are classified by their embedded IPv4 address and report true.
Affected versions
<= 10.5.0. The comparison has had this shape since Address6.isLinkLocal() was introduced, so every release exposing the method is affected.
Impact
Every well-formed address in fe80::/10 outside fe80::/64 is parsed successfully, isValid() is true, and the classifier reports something untrue about it. No other classifier catches these addresses: isPrivate() covers ULA (fc00::/7), not link-local.
| Address | isLinkLocal() | getType() | getScope() |
|---|---|---|---|
| fe80::1 | true | Link-local unicast | Link local |
| fe81::1 | false | Link-local unicast | Link local |
| fe8f::1 | false | Link-local unicast | Link local |
| febf::1 | false | Link-local unicast | Link local |
| fe80:0:0:1::1 | false | Link-local unicast | Link local |
| fe80::1:0:0:0:1 | false | Link-local unicast | Link local |
Python's ipaddress module, the IN6_IS_ADDR_LINKLOCAL macro in netinet6/in6.h, and Linux's ipv6_addr_type() all apply a ten-bit prefix test and classify every row above as link-local.
A request admitted through a guard built on isLinkLocal() reaches a link-local host on the server's own segment: a neighboring machine or the on-link router. An IPv6 link-local destination generally needs a zone index and a neighbor on the same link, so the reach is the server's own segment rather than the internet or a universal metadata endpoint, and the severity reflects that.
Proof of concept
npm i [email protected], then:
const { Address6 } = require('ip-address');
// A guard of the shape the library documents.
function isBlocked(host) {
const a = new Address6(host);
return a.isLoopback() || a.isLinkLocal() || a.isPrivate() || a.isMulticast() || a.isUnspecified();
}
for (const h of ['fe80::1', 'fe81::1', 'febf::1',…
- Record
GHSA-rpw4-54j3-4h4q- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N - Weakness
- CWE-697, CWE-918
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-101913
6.3
ip-address is a library for parsing and manipulating IPv4 and IPv6 addresses in JavaScript. Prior to 10.5.1, the Address6 isLinkLocal method in src/ipv6.ts recognizes only fe80::/64 instead of the complete fe80::/10 IPv6 link-local range. An attacker-controlled address elsewhere in fe80::/10 can therefore pass a trust-boundary check that relies on isLinkLocal. The same address is identified as link-local by getType and getScope, exposing the inconsistent classification. A successful bypass can reach an on-link host outside the intended trust boundary. This issue is fixed in version 10.5.1.
- Record
UBUNTU-CVE-2026-101913- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N - Updated
- 2026-11-02
OSVCLSA-2026-1790676837 No score
TuxCare security update for ip-address (1 CVE)
TuxCare rebuilt ip-address to address 1 CVE. Fixed in 6.4.0-tuxcare.4.
- Record
CLSA-2026-1790676837- Updated
- 2026-11-02
OSVCLSA-2026-1790677530 No score
TuxCare security update for ip-address (1 CVE)
TuxCare rebuilt ip-address to address 1 CVE. Fixed in 7.1.0-tuxcare.2.
- Record
CLSA-2026-1790677530- Updated
- 2026-11-02
OSVCLSA-2026-1792233491 No score
TuxCare security update for ip-address (3 CVEs)
TuxCare rebuilt ip-address to address 3 CVEs. Fixed in 9.0.5-tuxcare.3.
- Record
CLSA-2026-1792233491- Updated
- 2026-11-02
OSVCLSA-2026-1792369098 No score
TuxCare security update for ip-address (4 CVEs)
TuxCare rebuilt ip-address to address 4 CVEs. Fixed in 10.5.0-tuxcare.1.
- Record
CLSA-2026-1792369098- Updated
- 2026-11-02
OSVCLSA-2026-1792451467 No score
TuxCare security update for ip-address (6 CVEs)
TuxCare rebuilt ip-address to address 6 CVEs. Fixed in 10.1.1-tuxcare.1.
- Record
CLSA-2026-1792451467- Updated
- 2026-11-02
OSVCLSA-2026-1792476227 No score
TuxCare security update for ip-address (7 CVEs)
TuxCare rebuilt ip-address to address 7 CVEs. Fixed in 10.1.0-tuxcare.1.
- Record
CLSA-2026-1792476227- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
ip-addressnpm |
through 10.5.0 | 10.5.1 |
ip-addressTuxCare:npm |
6.4.0-tuxcare.0 up to 6.4.0-tuxcare.4, plus listed versions 6.4.06.4.0-tuxcare.16.4.0-tuxcare.26.4.0-tuxcare.3 |
6.4.0-tuxcare.4 |
ip-addressTuxCare:npm |
7.1.0-tuxcare.0 up to 7.1.0-tuxcare.2, plus listed versions 7.1.07.1.0-tuxcare.1 |
7.1.0-tuxcare.2 |
ip-addressTuxCare:npm From an advisory covering 3 CVEs |
9.0.5-tuxcare.0 up to 9.0.5-tuxcare.3, plus listed versions 9.0.59.0.5-tuxcare.19.0.5-tuxcare.2 |
9.0.5-tuxcare.3 |
ip-addressTuxCare:npm From an advisory covering 4 CVEs |
10.5.0-tuxcare.0 up to 10.5.0-tuxcare.1, plus listed versions 10.5.0 |
10.5.0-tuxcare.1 |
ip-addressTuxCare:npm From an advisory covering 5 CVEs |
10.1.1-tuxcare.0 up to 10.1.1-tuxcare.1, plus listed versions 10.1.1 |
10.1.1-tuxcare.1 |
ip-addressTuxCare:npm From an advisory covering 5 CVEs |
10.1.0-tuxcare.0 up to 10.1.0-tuxcare.1, plus listed versions 10.1.0 |
10.1.0-tuxcare.1 |
node-ip-addressDebian:12 |
All versions, plus listed versions 10.2.0-110.2.0-210.3.1-110.4.0-110.7.2-18.1.0-28.1.0-3 |
None known |
node-ip-addressDebian:13 |
All versions, plus listed versions 10.2.0-110.2.0-210.3.1-110.4.0-110.7.2-18.1.0-28.1.0-3 |
None known |
node-ip-addressDebian:14 |
before 10.7.2-1, plus listed versions 10.2.0-110.2.0-210.3.1-110.4.0-18.1.0-28.1.0-3 |
10.7.2-1 |
Show 6 moreShow less
| Package | Affected | Fixed |
|---|---|---|
ip-addressnpm |
before 10.5.1 | 10.5.1 |
node-ip-addressUbuntu:20.04:LTS |
All versions, plus listed versions 6.3.0-1 |
None known |
node-ip-addressUbuntu:22.04:LTS |
All versions, plus listed versions 6.4.0-18.1.0-2 |
None known |
node-ip-addressUbuntu:24.04:LTS |
All versions, plus listed versions 8.1.0-2 |
None known |
node-ip-addressUbuntu:26.10 |
All versions, plus listed versions 8.1.0-310.2.0-210.3.1-110.4.0-1 |
None known |
node-ip-addressUbuntu:26.04:LTS |
All versions, plus listed versions 8.1.0-28.1.0-3 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-101913 is a medium vulnerability (CVSS 6.3) in Beaugunderson Ip-address, published September 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.39%, the 32nd percentile. Fixed in ip-address 10.5.1.
References
github.com/beaugunderson/ip-address/security/advisories/GHSA-rpw4-54j3-4h4q
github.com/beaugunderson/ip-address/commit/d03e960c7cc3179ef25c8a44b4f94dd499625546
github.com/beaugunderson/ip-address/releases/tag/v10.5.1
nvd.nist.gov/vuln/detail/CVE-2026-101913
github.com/advisories/GHSA-rpw4-54j3-4h4q
github.com/CVEProject/cvelistV5/tree/main/cves/2026/101xxx/CVE-2026-101913.json
Left out here: the rest of 2 source descriptions. The JSON record has them.