Sep 2, 2026·7 min read·52 visits
The fast-uri library's IPv6 parser silently normalises invalid IP literals like [::not-valid] to [::] (the unspecified loopback address). Attackers exploit this parser differential to bypass security blocklists, redirecting outbound HTTP requests to internal networks or local services.
A critical parser differential vulnerability in the Node.js fast-uri library allows unauthenticated remote attackers to bypass address-validation filters and perform Server-Side Request Forgery (SSRF). The library fails to validate complete IPv6 grammar inside bracketed literals, silently truncating invalid trailing characters and normalising malformed hosts into valid loopback or private addresses.
The fast-uri library is an RFC 3986-compliant URI parsing toolbox designed for Node.js environments. It serves as a performance-optimized utility within the Fastify ecosystem. Because it lacks external dependencies, many downstream packages rely on its parsing and normalization logic to validate outbound requests, proxies, and redirects.
This security vulnerability arises from a custom parser designed to handle bracketed IPv6 literals (such as [::1]). Instead of enforcing a strict grammar validation on the contents inside the brackets, the parser sequentializes character processing. When it encounters invalid trailing text, it fails to throw an exception or flag an error. Instead, the parser silently discards the malformed trailing payload and normalizes the parsed host to a different, valid IP address.
This behavior establishes a classic parser differential vulnerability. Downstream applications checking the original URL or expecting strict error handling will bypass input validation filters. When the processed string is forwarded to native Node.js HTTP clients, the connection resolves to local loopback interfaces or private networks, facilitating Server-Side Request Forgery (SSRF).
The root cause of this vulnerability lies in the sequential scanner logic implemented within the internal getIPV6 helper function located in lib/utils.js. In vulnerable versions of fast-uri, the parser steps through characters sequentially inside bracketed literals without maintaining a strict state machine or validating against RFC 3986 IPv6 standards.
When parsing a host like [::not-valid], the scanner begins processing characters. Upon reaching the non-hexadecimal character n, the parser's logic halts or exits processing of the current segment without raising an error. The current buffer of successfully parsed characters (the :: prefix) is then used to construct the finalized host address.
Consequently, the host resolves to [::] (the unspecified address), while the malformed suffix :not-valid is silently discarded. Other malformed patterns similarly collapse into valid private or loopback ranges, such as [fc00::not-hex] collapsing into [fc00::]. Because the parser returns the output object with the error property set to false, downstream verification blocks treat the host as structurally valid and safe.
To understand the technical mechanics of the failure, analyze the structure of the getIPV6 function in the vulnerable version of lib/utils.js. The parser maintains state in arrays but allows loop exits that truncate input rather than forcing validation failure.
// Vulnerable sequential loop inside getIPV6 (lib/utils.js)
for (let i = 0; i < input.length; i++) {
const cursor = input[i]
if (cursor === '[' || cursor === ']') { continue }
if (cursor === ':') {
// ...
if (!consume()) { break } // Silent break on parsing error
// ...
}
}
// Truncation occurs silently when exiting loop with partial buffer
if (buffer.length) {
if (isZone) {
output.zone = buffer.join('')
} else {
address.push(stringArrayToHexStripped(buffer))
}
}
output.address = address.join('')
return outputThe patched version replaces this highly permissive sequential traversal with strict regular expression assertions matching RFC 3986 standards. Rather than stripping characters, the implementation explicitly returns undefined or throws an error when structural requirements are violated.
// Patched validation utilizing explicit RFC regular expressions
function normalizeIPv6Address (input) {
const compression = input.indexOf('::')
if (compression !== -1 && input.indexOf('::', compression + 1) !== -1) return undefined
const left = compression === -1 ? input.split(':') : input.slice(0, compression).split(':')
const right = compression === -1 ? [] : input.slice(compression + 2).split(':')
// ...
for (let i = 0; i < parts.length; i++) {
const part = parts[i]
if (part === '') return undefined
if (!isHextet(part)) return undefined // Rejects non-hexadecimal inputs immediately
}
// ...
}Additionally, the patch alters index.js to ensure the core parser (parseWithStatus) processes the validation failure from normalizeIPv6(). If the bracketed IP literal generates an error during normalisation, malformedIPLiteral is evaluated as true, setting the parsed error state to URI host is malformed. and blocking downstream normalization.
An attacker can exploit this vulnerability to achieve Server-Side Request Forgery (SSRF) or bypass network access policies designed to restrict internal service routing. This attack scenario requires the target application to accept user-controlled URLs, parse them with fast-uri for security checks, and execute outbound HTTP requests using Node.js clients like undici or axios.
In a standard SSRF scenario, an attacker issues a POST request to an external endpoint with the payload http://[::not-valid]:8080/admin. The security middleware uses fast-uri to parse the host. Because [::not-valid] is not explicitly found in standard local domain blocklists (such as localhost, 127.0.0.1, or [::1]), the request is permitted by the filter.
Step 1: Attacker sends POST /fetch?url=http://[::not-valid]:8080/admin
Step 2: App validates URL -> fastURI.parse('http://[::not-valid]:8080/admin') -> parses host
Step 3: App normalizes URL -> fastURI.normalize() -> outputs 'http://[::]:8080/admin'
Step 4: App connects -> fetch('http://[::]:8080/admin') -> routes to localhost admin portal
During normalization, fast-uri reconstructs the host as [::] because the parser discarded the invalid :not-valid suffix. Node.js's underlying network stack resolves the unspecified IPv6 address [::] directly to the local host interface (127.0.0.1 or ::1). This mechanism routes the outbound HTTP request internally, exposing endpoints on port 8080 to the attacker without authorization.
The impact of CVE-2026-75975 is classified as High (CVSS v3.1 Score: 7.5). The vulnerability undermines the integrity of network perimeter definitions and routing restrictions. The attack complexity is low, as it does not require prior authentication or user interaction to exploit successfully.
Successful exploitation allows complete bypass of address-validation policies. Attackers gain access to arbitrary HTTP endpoints on the internal network segment. In cloud environments, this primitive can be leveraged to access sensitive metadata services (e.g., IMDSv1 at 169.254.169.254 or local IPv6 link-local addresses) to harvest API keys, database credentials, and session tokens.
Additionally, because the parser does not set an error state, security tools built on fast-uri cannot log or identify that a parser differential attack occurred. The silent rewriting of destination hosts prevents audit logging systems from accurately capturing the true target of outbound connections, creating a significant blind spot for incident response teams.
The primary remediation path is upgrading the fast-uri package to a patched release. Ensure that your application and transitive dependencies are upgraded. Depending on your version branch, apply the corresponding update:
Verify that the lockfiles (package-lock.json, yarn.lock, or pnpm-lock.yaml) reflect the updated version. If direct modification is restricted, utilize npm overrides or yarn resolutions to force transitive dependencies to resolve to the secure versions.
In environments where an immediate package upgrade is not feasible, implement a temporary input validation layer. Before passing user-supplied input to fast-uri, validate that any host containing bracketed literals strictly adheres to IPv6 structure. Reject URLs that match the regular expression /^https?:\/\/\[.*?[^a-fA-F0-9:].*?\]/ to prevent silent truncation.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
fast-uri Fastify / OpenJS Foundation | >= 2.3.1, < 2.4.5 | 2.4.5 |
fast-uri Fastify / OpenJS Foundation | >= 3.0.0, < 3.1.6 | 3.1.6 |
fast-uri Fastify / OpenJS Foundation | >= 4.0.0, < 4.1.3 | 4.1.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-20, CWE-918 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 7.5 (High) |
| Exploit Maturity | Proof of Concept (PoC) |
| CISA KEV Status | Not Listed |
| Impact | Integrity (High), Server-Side Request Forgery (SSRF) |
The product does not validate or incorrectly validates input that can affect the control flow or data flow of a program.
CVE-2026-109618 (dubbed PHP2Shell) is a critical vulnerability in the PHP engine core resulting from improper out-of-memory exception handling via longjmp(). When request allocation fails mid-processing, non-local control flow bypasses cleanup procedures, leaving memory structures uninitialized or in a use-after-free state during request shutdown.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.