May 8, 2026·7 min read·19 visits
fast-uri ≤ 3.1.0 decodes percent-encoded URI characters before running path normalization algorithms. This allows attackers to use payloads like %2e%2e to bypass security filters and perform path traversal attacks. Upgrade to version 3.1.1 to implement context-aware decoding.
The fast-uri library (versions ≤ 3.1.0) contains a high-severity path traversal vulnerability due to an order-of-operations flaw during URI normalization. The library incorrectly decodes percent-encoded path separators (%2F) and dot segments (%2E) prior to applying dot-segment removal algorithms, allowing attackers to bypass path-based access controls and filters.
The fast-uri library is a dependency-free URI manipulation toolkit designed to parse, normalize, and serialize URIs in accordance with RFC 3986. Applications frequently use this library to validate incoming requests, enforce security policies, or process routing logic based on requested paths. A critical aspect of this processing is URI normalization, which standardizes divergent URI representations into a single canonical form for consistent evaluation.
CVE-2026-6321 is a path traversal vulnerability (CWE-22) affecting the normalize() and equal() functions within fast-uri versions 3.1.0 and earlier. The flaw resides in the specific sequence of operations the library performs when converting an input string into a normalized URI path. The library fails to correctly separate the decoding of percent-encoded characters from the resolution of relative path segments.
This logical separation is critical because percent-encoded strings represent literal data rather than functional path syntax. By resolving relative segments after decoding encoded inputs, the library mistakenly grants functional properties to data that the sender explicitly encoded to remain inert. Consequently, security mechanisms that rely on fast-uri to accurately represent the final resolved path are subject to bypass.
The root cause of CVE-2026-6321 is an order-of-operations vulnerability during the URI normalization process. The specification for URI generic syntax, RFC 3986, explicitly separates the concepts of percent-encoding and path segment resolution. Section 5.2.4 defines the remove_dot_segments algorithm, which is responsible for evaluating . and .. components to resolve a path to its absolute form.
According to the RFC, percent-encoded characters must only be decoded if they belong to the "unreserved" set (alphanumerics and specific symbols). Characters in the "reserved" set, which include the dot (.) and slash (/), possess special semantic meaning in the context of a URI path. If these characters are percent-encoded, the parser must treat them as literal character data rather than structural delimiters. They must not participate in the remove_dot_segments algorithm.
In vulnerable versions of fast-uri, the internal normalization routine executed a "decode-then-process" workflow. The parser applied an indiscriminate unescaping operation to the entire URI string, converting %2E to . and %2F to /. Only after this universal decoding did the library invoke the logic to process relative directories.
By executing these operations in the wrong order, fast-uri effectively transformed harmless, encoded literals into active path traversal directives. A payload containing %2e%2e became .. inside the parsing engine before path resolution occurred, instructing the library to traverse up a directory hierarchy. This violates the specification and creates a severe discrepancy between the URI the application believes it is processing and the path the library ultimately resolves.
The structural flaw in fast-uri ≤ 3.1.0 was tied to how the normalize() function managed character decoding. Prior to the fix, the logic relied on generalized unescaping mechanisms that did not differentiate between reserved and unreserved characters. When the library encountered %2E or %2F, it immediately converted them into their raw string representations.
The patch introduced in commit 876ce79b662c3e5015e4e7dffe6f37752ad34f35 completely overhauls this behavior by implementing context-aware decoding functions. The developers introduced normalizePathEncoding and normalizePercentEncoding. These functions strictly enforce the rule that only unreserved characters undergo decoding during the normalization phase.
// Conceptual representation of the patch logic introduced in 3.1.1
// BEFORE (Vulnerable Logic)
function normalize(uri) {
let decoded = unescape(uri); // Indiscriminately decodes all percent-encoding
return removeDotSegments(decoded); // Processes encoded dots as active traversal tokens
}
// AFTER (Patched Logic)
function normalizePathEncoding(path) {
// Context-aware decoding: preserves reserved escapes like %2E and %2F
return path.replace(/%[0-9A-Fa-f]{2}/g, (match) => {
const charCode = parseInt(match.slice(1), 16);
if (isUnreserved(charCode)) {
return String.fromCharCode(charCode);
}
return match.toUpperCase(); // Retain encoding for reserved chars
});
}The patched logic ensures that the string %2e%2e is normalized to %2E%2E rather than ... Because the encoding is preserved, the removeDotSegments algorithm subsequently treats %2E%2E as a standard directory name, not a traversal instruction. The equal() function was similarly updated to compare URIs accurately without falsely interpreting reserved escapes as live path syntax.
Exploiting CVE-2026-6321 requires an attacker to identify a target application that utilizes fast-uri for security boundary enforcement. A common architectural pattern involves validating an incoming request URI against a list of permitted prefixes or directories. If the application evaluates the raw URI for authorization but uses the normalized output for downstream routing or file system access, a critical discrepancy emerges.
Consider an application configured to allow unauthenticated access strictly to the /api/public/ directory. The application implements a middleware filter that checks if the request URI begins with this permitted string. If the check passes, the application normalizes the path using fast-uri.normalize() and proxies the request to a backend file server or internal API endpoint.
An attacker crafts the following payload: http://example.com/api/public/%2e%2e/admin/config. The initial security filter examines the raw string, confirms that it starts with /api/public/, and permits the request. The middleware then passes the string to the vulnerable fast-uri normalization routine.
The vulnerable library decodes %2e%2e into .. and processes the traversal. The resulting normalized path returned by the library is /api/admin/config. The application proceeds to fetch or proxy this resolved path, unknowingly granting the attacker access to a restricted internal resource. This attack requires no authentication and relies entirely on the predictable behavior of the flawed URI parser.
The impact of CVE-2026-6321 is classified as High, with a CVSS v3.1 base score of 7.5. The vulnerability directly undermines the integrity of path-based security controls. Because the flaw allows an attacker to manipulate the fundamental state of a URI traversing a system, it introduces significant risks of unauthorized data access, internal API exposure, and potential system compromise.
The specific consequences depend entirely on how the consuming application utilizes the output of fast-uri. If the normalized path dictates file system read operations, the attacker achieves arbitrary local file disclosure (LFD). If the normalized path directs a reverse proxy, the attacker achieves Server-Side Request Forgery (SSRF) or unauthorized routing to internal management endpoints. The vulnerability is characterized by a low attack complexity and requires zero user interaction.
Currently, the EPSS score for this vulnerability is 0.00030, indicating a very low observed exploitation probability in the wild (0.03%). It is not listed in the CISA KEV catalog. However, because URI parsers often sit at the very perimeter of application architectures, organizations should treat this vulnerability with high urgency. A single unpatched microservice handling routing logic can compromise the security posture of an entire backend network.
The primary and most effective remediation for CVE-2026-6321 is to update the fast-uri package to version 3.1.1 or later. The patch completely resolves the order-of-operations defect by introducing context-aware decoding functions. Development teams should audit their package.json and package-lock.json files to ensure no nested dependencies are relying on vulnerable iterations of the library.
For environments where immediate patching is not feasible, security engineers can deploy Web Application Firewall (WAF) rules to detect and block malicious payloads. WAF policies should inspect incoming HTTP request paths and query strings for the presence of encoded traversal sequences. Specifically, blocking requests containing %2e (and its variations like %2E, %252e) or %2f (%2F) provides a robust temporary defense against exploitation attempts targeting this specific parsing flaw.
Furthermore, developers should review their application logic to avoid "time-of-check to time-of-use" (TOCTOU) discrepancies. Security validation must always occur on the final, normalized state of the data, not on the raw, unparsed input. If an application authorizes a path based on a raw string but acts upon a normalized string, it inherently trusts the normalization engine to never introduce bypass conditions. Shifting the authorization check to occur after the fast-uri.normalize() execution mitigates the logical bypass entirely, regardless of underlying library flaws.
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 | <= 3.1.0 | 3.1.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network |
| CVSS Score | 7.5 (High) |
| EPSS Score | 0.00030 |
| Exploit Status | Proof of Concept Available |
| CISA KEV | Not Listed |
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')