Sep 2, 2026·6 min read·2 visits
fast-uri parses percent-encoded schemes with lenient decoding and no validation, resulting in structure mutation, host confusion, and SSRF upon serialization.
A critical parser differential and host confusion vulnerability (CVE-2026-76172) exists in fast-uri, a dependency-free URI validation and normalization library for Node.js. This vulnerability stems from improper validation of the URI scheme component after decoding percent-encoded characters using the legacy global unescape() function. This allows structural characters such as path delimiters and control characters to be written raw into the output stream during serialization, causing host confusion, Server-Side Request Forgery (SSRF), or HTTP response splitting downstream.
The fast-uri library is a high-performance, dependency-free URI validation and normalization library for Node.js. It is widely adopted within the Fastify ecosystem to parse, format, and resolve RFC 3986 compliant URIs. A critical vulnerability, designated as CVE-2026-76172, exists in how fast-uri validates and handles URI schemes containing percent-encoded characters.
The core of the vulnerability resides in the lax processing of hex-encoded sequences inside the scheme component of an incoming URI. When fast-uri parses a URI, it performs a decoding pass on the parsed elements. However, it fails to validate that the resulting decoded scheme conforms to standard RFC 3986 scheme grammar before serialization. This oversight creates a major parser differential when the output is processed downstream.
An attacker can construct a payload where structural separators are hidden behind percent-encoding inside the scheme. This allows the malformed string to pass validation checks, only to mutate into a structurally different URI upon normalization. When processed by downstream clients or validation engines, this mutated output introduces an authority/host component that was previously unrecognized.
The primary technical defect is the insecure decoding of the scheme component combined with a complete lack of post-decoding validation. According to RFC 3986, the scheme component of a URI must adhere to a strict pattern: a letter followed by letters, digits, plus signs, periods, or hyphens. The scheme component must never contain percent-encoded characters, control bytes, or path delimiters.
During parsing, fast-uri extracts the scheme using a preliminary regular expression. If the input contains a percent character, the library passes the extracted scheme to the deprecated, lenient global JavaScript unescape() function. The legacy unescape function is highly tolerant of non-standard escapes, allowing it to translate hex values like %2f%2f into raw slashes (//) or %0d%0a into carriage return and line feed (CRLF) characters.
After decoding the scheme, the library stores the output in the parsed.scheme property. In affected versions, the library does not verify if the decoded scheme matches valid scheme grammar. When the parsed URI is subsequently serialized or normalized, the unescaped scheme is written raw directly to the output stream. This structural mutation transforms an apparently harmless URI with no authority into an absolute URI with an attacker-defined authority.
To understand the exact mechanics, examine the vulnerability at the code level. In vulnerable versions of the library, the parsing logic in index.js checks for percent signs and decode the parsed scheme using unescape():
// Vulnerable scheme decoding logic in fast-uri
if (uri.indexOf('%') !== -1) {
if (parsed.scheme !== undefined) {
parsed.scheme = unescape(parsed.scheme);
}
}During the final serialization step, the library constructs the URI string from the component tokens. Because the parsed scheme was unescaped and never validated, it gets appended verbatim to the output string:
// Insecure serialization of scheme
if (options.reference !== 'suffix' && component.scheme) {
uriTokens.push(component.scheme, ':');
}The patch addresses this structural vulnerability by introducing a strict regular expression validation step immediately after the decoding pass. A new regex pattern, VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u, is declared to strictly enforce RFC 3986 rules. Any scheme containing characters outside this range, including slashes or control bytes, triggers a validation failure.
// Patched logic to validate decoded scheme
const VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
const MALFORMED_SCHEME_ERROR = 'URI scheme is malformed.';
function decodeValidScheme (scheme) {
const decodedScheme = unescape(String(scheme));
if (!VALID_SCHEME.test(decodedScheme)) {
throw new TypeError(MALFORMED_SCHEME_ERROR);
}
return decodedScheme;
}This validator is integrated into both the parseWithStatus and serialize functions, ensuring that malformed schemes are flagged during parsing and rejected during serialization. If an application attempts to parse a relative URL with an invalid scheme, the library sets malformedScheme = true and populates the error property, causing resolution functions to fail closed.
Exploitation of CVE-2026-76172 requires an application structure where fast-uri validates user-supplied URIs before they are normalized and passed to a downstream HTTP client. This design pattern is typical in API gateways, microservices, and reverse proxies. The attacker exploits the parser differential by supplying percent-encoded path delimiters in the scheme.
Consider an endpoint validating relative paths to prevent access to external hosts. When the attacker submits the payload %2f%2fevil.com:/pwn, fast-uri parses %2f%2fevil.com as the scheme. Since there is no explicit // introducing an authority during the initial extraction, parsed.host remains undefined, successfully bypassing host validation checks.
During the subsequent resolution or normalization process, fast-uri decodes the scheme to //evil.com. When the finalized string is written, it becomes http://evil.com/pwn (or similar depending on base resolution). When this output is sent to a downstream client like fetch or undici, the downstream parser interprets the mutated string as containing an authority, routing the request to the external server.
In addition to SSRF, an attacker can perform HTTP response splitting. By passing %0d%0aSet-Cookie:%20session=attacker, the unescape function writes raw carriage return and line feed characters into the normalized URL. If this output is placed into an HTTP redirection header, the server splits the response and injects attacker-controlled headers.
The impact of CVE-2026-76172 is high, particularly for cloud-native architectures where microservices communicate via internal networks. By bypassing host checks, attackers can perform arbitrary Server-Side Request Forgery. This allows unauthorized access to internal metadata services, backend databases, and administrative consoles that are isolated from the internet.
If the application utilizes the normalized output to redirect users, the vulnerability facilitates open-redirect phishing campaigns. Users are redirected to malicious external sites while believing they are interacting with a trusted platform. This undermines user trust and increases the success rate of credential harvesting operations.
Furthermore, the ability to inject carriage return and line feed characters into HTTP headers introduces risk of HTTP response splitting. This enables session hijacking, cross-site scripting (XSS), and cache poisoning. The CVSS score of 7.5 reflects high integrity impact, and applications processing untrusted URIs must treat this vulnerability as high priority.
Remediation requires upgrading fast-uri to a patched version immediately. The maintainers have released patches across all active branches. Development teams must update their package configurations to require at least version 2.4.5, 3.1.6, or 4.1.3 depending on their major version path.
If immediate dependency updates are not possible, developers should implement manual verification of user input. Validate that all user-supplied URLs conform to standard formats before passing them to fast-uri. Specifically, reject any input containing percent-encoded characters inside the scheme portion of the string.
Additionally, standardize the URI parsers used across your application architecture. Avoid validating input with a relaxed, non-WHATWG-compliant library while executing requests with a strict client. Aligning the validation and execution engines eliminates the parser differentials that make this class of vulnerability exploitable.
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 | >= 2.3.1 < 2.4.5 | 2.4.5 |
fast-uri Fastify | >= 3.0.0 < 3.1.6 | 3.1.6 |
fast-uri Fastify | >= 4.0.0 < 4.1.3 | 4.1.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-177 |
| Attack Vector | Network (Unauthenticated) |
| CVSS Score | 7.5 |
| EPSS Score | 0.00247 (Percentile: 15.89%) |
| Impact | Host Confusion / SSRF / HTTP Response Splitting |
| Exploit Status | Proof-of-Concept (PoC) |
| KEV Status | Not Listed |
The application fails to properly handle, validate, or sanitize hex-encoded characters during URL processing, leading to structural mutations when the string is normalized or serialized.
CVE-2026-62388 represents a critical design flaw in the Natural Language Toolkit (NLTK) before version 3.10.0. The central security module (`nltk/pathsec.py`) initialized its validation enforcement flag to false by default. This fail-open configuration rendered security controls—such as path traversal checks, zip archive audits, and SSRF validations—non-blocking, only emitting warnings while permitting arbitrary file operations and code execution.
A double-decoding vulnerability in the fast-uri package allows unauthenticated remote attackers to bypass host-policy validation and conduct Server-Side Request Forgery (SSRF) attacks by submitting nested percent-encoded URI strings.
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.
A host confusion vulnerability exists in the fast-uri Node.js library when parsing scheme-relative URI references. Due to inconsistent domain name canonicalization, applications validating resolved hosts can be bypassed by downstream WHATWG-compliant parsers, facilitating Server-Side Request Forgery (SSRF).
Sulu CMS, an open-source PHP content management system based on the Symfony framework, is affected by an Insecure Direct Object Reference (IDOR) vulnerability within its media relocation API. Authenticated users with restricted edit permissions can relocate media out of secure, unauthorized collections into folders they control, bypassing access controls entirely. This security issue is tracked under CVE-2026-82395 and GHSA-h6cx-gjxx-v25c.
An incomplete sanitization fix for CVE-2026-35536 in Tornado allowed cookie attribute injection. The framework's validation loop checked lowercase keyword arguments but neglected legacy case-insensitive parameters passed through arbitrary keyword arguments, which Python's underlying library parses case-insensitively.