Aug 4, 2026·7 min read·0 visits
Input misclassification in ip-address library <= 10.2.0 enables SSRF. The parser fails to normalize IPv4-mapped or NAT64 transition addresses before running boolean classification checks (e.g., isLoopback). This allows attackers to bypass security guards and connect to restricted internal IPv4 destinations over dual-stack host configurations.
A trust-boundary bypass and Server-Side Request Forgery (SSRF) vulnerability exists in the ip-address library versions 10.1.1 through 10.2.0 due to structural input misclassification. The library fails to resolve and normalize transition IP notations, such as IPv4-mapped IPv6 (::ffff:0:0/96) and NAT64 (64:ff9b::/96) addresses, to their embedded IPv4 representations prior to evaluation. Consequently, standard security validation checks (e.g., isLoopback, isLinkLocal, isULA) return false for these addresses. This allows remote attackers to bypass application-level IP address filters, gaining unauthorized access to internal resources, cloud metadata interfaces, and local services on dual-stack hosts or environments utilizing NAT64 gateways.
The vulnerability classified under CVE-2026-54272 constitutes a trust-boundary bypass inside the popular Node.js and TypeScript network utility library ip-address. This library is widely adopted in backend validation layers to filter and sanitize IP addresses, particularly to prevent Server-Side Request Forgery (SSRF) attacks targeting internal services. By providing transition IP representations, remote attackers bypass security filters that rely on boolean properties such as isLoopback(), isLinkLocal(), or isULA().
The core of the issue resides in how the Address6 class parses and identifies hybrid IPv4-mapped and NAT64 addresses. Transition mechanisms allow legacy IPv4 hosts to communicate across modern IPv6-only or dual-stack topologies. If an application utilizes ip-address to enforce a blocklist before issuing HTTP requests, it remains blind to these hybrid schemas. Under dual-stack host operating system environments, these addresses are automatically routed to local or internal IPv4 stacks, resulting in unauthorized requests.
Because the parser failed to extract and evaluate the underlying embedded IPv4 address, the library misclassified these hybrid representations as 'Global unicast' addresses. This classification indicates that the address is publicly routable on the global internet, allowing validation layers to forward the request. The impact is a substantial increase in exposure to SSRF, potentially exposing sensitive microservices, local APIs, and cloud provider metadata interfaces.
The root cause of this vulnerability lies in the structural separation of Address4 and Address6 validation logic inside the library and the complete absence of prefix validation for embedded IPv4 addresses. Specifically, the helper function Address6.getType() determines an IP's classification by cross-referencing it with a static lookup dictionary named TYPES. In affected versions, this lookup table completely omitted the IPv4-mapped range defined in RFC 4291 as ::ffff:0:0/96.
When an application evaluates an address string like ::ffff:127.0.0.1, the parser evaluates it against the rules of native IPv6. Because no rule matched ::ffff:0:0/96, the internal logic fell back to returning 'Global unicast' as its default type. Consequently, the helper checks isLoopback(), isUnspecified(), and isMulticast() evaluated as false, since they are implemented as direct string comparisons against the output of getType().
Furthermore, other security-critical helpers such as isLinkLocal() and isULA() only performed prefix range checks on native IPv6 prefixes, such as fe80::/10 and fc00::/7 respectively. These functions lacked the capability to unpack the nested IPv4 boundaries. Developers attempting to prevent access to the local network space would find that standard checks returned falsy values for embedded local destinations.
Another critical gap in the API was the lack of an isPrivate() helper within the Address6 class. While Address4 exposed isPrivate() to identify RFC 1918 subnets (such as 10.0.0.0/8 or 192.168.0.0/16), Address6 lacked equivalent logic. Developers validating IPv6 addresses would have to rely on isULA(), which was completely ineffective at flagging RFC 1918 subnets wrapped inside mapped IPv6 strings. This missing validation vector allowed standard private subnet ranges to bypass typical access guards.
The fix introduced in version 10.2.1 remediates this classification flaw through a centralized delegation model called embeddedIPv4(). This helper identifies whether an address resides inside the IPv4-mapped subnet (::ffff:0:0/96) or the NAT64 well-known subnet (64:ff9b::/96). When matched, the method instantiates the embedded target as a proper Address4 instance using the library's pre-existing to4() extraction mechanism.
The corrected logic wraps the boolean properties to perform active delegation. When an embedded IPv4 representation is detected, the wrapper proxies the evaluation directly to the underlying Address4 instance, preserving classification context. The difference between the vulnerable and corrected implementations is visible in the delegation structure.
// Vulnerable implementation in Address6 (version 10.2.0)
isLoopback(): boolean {
return this.getType() === 'Loopback'; // Evaluated to "Global unicast" for ::ffff:127.0.0.1
}
// Remedied implementation in Address6 (version 10.2.1)
embeddedIPv4(): Address4 | null {
if (this.isMapped4() || this.isInSubnet(NAT64_WELL_KNOWN_SUBNET)) {
return this.to4();
}
return null;
}
isLoopback(): boolean {
const embedded = this.embeddedIPv4();
if (embedded) {
return embedded.isLoopback(); // Properly delegates to Address4.isLoopback()
}
return this.getType() === 'Loopback';
}Additionally, the missing helper functions isPrivate(), isCGNAT(), and isBroadcast() were added to the Address6 class. These functions behave in the exact same manner, delegating evaluation to the underlying IPv4 properties when a transitional address is encountered. The patch also registered '::ffff:0:0/96' within the static TYPES mapping table as 'IPv4-mapped' to prevent further fall-through to 'Global unicast'.
Exploitation of this vulnerability requires that the target application uses ip-address to validate user-supplied hostname or IP parameters prior to executing server-side HTTP requests. If the destination system is a dual-stack host or operates with active NAT64/DNS64 gateways, the host operating system's socket layer will automatically route these addresses to the corresponding IPv4 destination stack.
Consider a backend API route that accepts a remote destination, validates that it is not a local address, and fetches the content. When an attacker provides ::ffff:127.0.0.1, the validation routine queries address.isLoopback(). Because the library returns false, the check succeeds. The HTTP client then issues a request to [::ffff:127.0.0.1], which the operating system automatically translates to 127.0.0.1, exposing local administrative endpoints.
The same bypass vector applies to cloud environment endpoints. An attacker can target the AWS Link-Local metadata interface using the payload ::ffff:169.254.169.254. Since the address bypasses isLinkLocal(), the application retrieves metadata credentials on behalf of the attacker. NAT64 setups are similarly vulnerable to targets on the internal private subnet by using the NAT64 well-known prefix combined with private class addresses, such as 64:ff9b::10.0.0.1.
Security researchers evaluating the completeness of this fix must consider specific edge cases where bypasses may still occur. First, the fix explicitly relies on the NAT64 well-known prefix 64:ff9b::/96 defined in RFC 6052. However, network administrators are permitted to configure Network-Specific Prefixes (NSPs) using their own allocated prefixes (e.g., /32, /40, or /48). If an internal network uses a custom NSP, the embeddedIPv4() logic will fail to identify the embedded target, allowing classification bypasses on that network.
Second, legacy systems may still support deprecated IPv4-compatible IPv6 addresses (::/96). Since the embeddedIPv4() implementation only checks isMapped4() (which validates the ::ffff:0:0/96 prefix), it will not extract the IPv4 address from ::127.0.0.1. If the host operating system retains legacy routing behaviors for the ::/96 prefix, this can be exploited to bypass validation.
Lastly, developers must be aware of Time-of-Check to Time-of-Use (TOCTOU) issues, such as DNS Rebinding. Even if the IP address is perfectly parsed and validated by ip-address, executing the connection using the original hostname string allows the attacker to swap the IP resolution to an internal address during the actual HTTP request phase. True remediation requires validating the resolved IP address and pinning the connection to that specific address.
Remediation of CVE-2026-54272 requires updating the dependency tree to ensure ip-address is at version 10.2.1 or above. For Node.js projects, this can be achieved by running npm install ip-address@latest or auditing the package-lock file to verify nested dependencies are updated.
For defense-in-depth, perimeter devices and Web Application Firewalls (WAF) can be configured with request inspection rules to block incoming transition notations in query parameters or HTTP body values. Regular expressions can look for the signature of IPv4-mapped and NAT64 prefixes. For example, matching against (?i)^\[?::ffff:(?:[0-9]{1,3}\.){3}[0-9]{1,3}\]? will block mapped formats, while (?i)^\[?64:ff9b::[a-f0-9:.]{1,15}\]? blocks NAT64 patterns.
To prevent DNS Rebinding alongside the SSRF bypass, applications should resolve hostnames beforehand, perform structural validation using ip-address, and use the validated IP address directly in the HTTP client configuration. This ensures that the IP evaluated by the validation layer is identical to the one accessed during the connection phase.
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| Product | Affected Versions | Fixed Version |
|---|---|---|
ip-address @beaugunderson | >= 10.1.1, <= 10.2.0 | 10.2.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918, CWE-20 |
| Attack Vector | Network |
| CVSS v4.0 Score | 6.9 (Medium) |
| EPSS Score | 0.00254 (0.25%) |
| Exploit Status | poc |
| KEV Status | Not Listed |
The web application receives an address from an upstream source, but fails to validate or limit the destination before establishing an outbound connection.
An interpretation conflict (CWE-436) in the cache interceptor of the undici HTTP client for Node.js causes whitespace-padded Cache-Control directives to be parsed incorrectly, leading to shared cache pollution and the unauthorized disclosure of sensitive, private, or authenticated user information (CWE-524).
CVE-2026-15157 details an improper neutralization of CRLF sequences ('CRLF Injection') within undici, a widely used Node.js HTTP/1.1 client. The vulnerability is triggered when processing request bodies that exhibit a duck-typed blob-like interface. When an application accepts untrusted data and assigns it to the .type property of such an object without setting an explicit Content-Type on the request, undici appends the value directly to the outgoing headers array without validating it against control characters. This allows remote attackers to inject carriage return and line feed sequences, culminating in arbitrary header injection, HTTP response splitting, or HTTP request smuggling.
A critical authentication bypass vulnerability (CVE-2026-18574) in Check Point Security Management and Multi-Domain Security Management (MDS) Servers allows unauthenticated remote attackers to execute arbitrary system commands with administrative privileges. The flaw stems from an alternate path authentication bypass (CWE-288) in the management interface daemons.
An input validation vulnerability in the npm package `ip-address` allows unauthenticated remote attackers to bypass Server-Side Request Forgery (SSRF) protections by appending a `/0` CIDR suffix to IP address strings. This causes the library's classification helper functions to incorrectly identify internal addresses as public, external addresses, while normalization helpers resolve the address back to its internal form during network connection establishment.
An argument injection vulnerability in GitPython allows remote or local attackers to execute arbitrary file reads or arbitrary file overwrites via unsafe command option forwarding. This occurs because the wrapper methods `IndexFile.checkout()` and `TagReference.create()` fail to validate parameters before passing them to system-level git invocations.
An argument injection vulnerability in GitPython allows remote or local attackers with control over repository archive configuration options to retrieve arbitrary local files via native git archive commands. During clone operations, a sibling missing validation vulnerability in the clone option engine allows attackers to perform Server-Side Request Forgery via the git clone bundle-uri mechanism.