Sep 2, 2026·6 min read·24 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.
An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.
CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.
A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.
CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.
An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.
An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.