CVE-2026-6321: Verified Repro With Script Download
CVE-2026-6321: fast-uri: path traversal via percent-encoded segments decoded before normalization
CVE-2026-6321 is verified against fast-uri · npm. Affected versions: <= 3.1.0. Fixed in 3.1.1. Vulnerability class: Path Traversal. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00145.
What Is CVE-2026-6321?
CVE-2026-6321 (GHSA-q3j6-qgpj-74h6) is a high-severity path-traversal vulnerability (CWE-22) in the fast-uri npm package's normalize() and equal() functions, which decode percent-encoded path segments before applying RFC 3986 dot-segment removal. Pruva reproduced it (reproduction REPRO-2026-00145).
CVE-2026-6321 Severity & CVSS Score
CVE-2026-6321 is rated high severity, with a CVSS base score of 7.5 out of 10.
High — serious impact or readily exploitable. Prioritize remediation.
Affected fast-uri Versions
fast-uri · npm versions <= 3.1.0 are affected.
How to Reproduce CVE-2026-6321
pruva-verify REPRO-2026-00145 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00145/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-6321
Reproduced by Pruva's autonomous agents — 154 tool calls over 10 min. Full root-cause analysis and the complete transcript are below.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-6321
Summary
fast-uri versions 3.1.0 and earlier decode percent-encoded path separators (%2F) and dot segments (%2E) before applying RFC 3986 dot-segment removal during URI normalization. This allows an attacker to bypass path-prefix allowlist checks: an encoded traversal sequence such as %2e%2e%2f is first decoded into literal ../, then processed as a real dot segment, causing the normalized path to escape the intended prefix. The equal() function suffers the same flaw, incorrectly reporting two distinct URIs as equal when one uses encoded traversal.
Impact
- Package:
fast-uri(npm) - Affected versions:
<= 3.1.0 - Fixed version:
3.1.1 - CVE: CVE-2026-6321
- CWE: CWE-22 (Path Traversal)
- Severity: High (CVSS 7.5)
- Consequences: Any authorization logic that relies on
fast-uri.normalize()orfast-uri.equal()to validate a path prefix can be bypassed. An attacker-supplied URI may normalize to a path outside the intended directory, leading to unauthorized access.
Root Cause
The vulnerability stems from the order of operations in the parse() and serialize() pipeline:
Vulnerable (v3.1.0):
parse()callsparsed.path = escape(unescape(parsed.path)). The built-inunescape()converts%2eto.and%2fto/, so%2e%2e%2fbecomes the literal string../. Whenserialize()later callsremoveDotSegments()on this already-decoded path, the sequence is treated as a real parent-directory traversal instruction, collapsingpublic/../admintoadmin.Fixed (v3.1.1): The code replaces the blanket
escape(unescape(...))withnormalizePathEncoding(), which deliberately preserves reserved path escapes such as%2Fand%2E. Because these remain encoded,removeDotSegments()sees them as ordinary path data, not as dot segments, and the path stays confined.
The fix commit changes index.js and lib/utils.js and adds a regression test (test/security-normalization.test.js) that asserts %2E%2E stays encoded during normalization and that equal() no longer conflates encoded and literal separators.
Reproduction Steps
The reproduction is fully automated by repro/reproduction_steps.sh.
What the script does:
- Creates two isolated npm projects.
- Installs
fast-uri@3.1.0(vulnerable) in one project. - Runs a Node.js script that calls
normalize()andequal()on URIs containing encoded traversal sequences (%2e%2e,%2f). - Installs
fast-uri@3.1.1(fixed) in the second project. - Runs the identical test script.
- Compares the outputs and writes a JSON verdict.
Expected evidence:
- Vulnerable:
normalize('http://example.com/public/%2e%2e/admin')returnshttp://example.com/admin. - Fixed:
normalize('http://example.com/public/%2e%2e/admin')returnshttp://example.com/public/%2E%2E/admin. - Vulnerable:
equal('http://example.com/public/%2e%2e/admin', 'http://example.com/admin')returnstrue. - Fixed:
equal(...)returnsfalse.
Evidence
- Vulnerable output log:
logs/vuln-output.txt - Fixed output log:
logs/fixed-output.txt - Validation verdict:
logs/validation_verdict.json
Key excerpts from the vulnerable run:
INPUT: http://example.com/public/%2e%2e/admin
OUTPUT: http://example.com/admin
equal('http://example.com/public/%2e%2e/admin', 'http://example.com/admin') => true
Key excerpts from the fixed run:
INPUT: http://example.com/public/%2e%2e/admin
OUTPUT: http://example.com/public/%2E%2E/admin
equal('http://example.com/public/%2e%2e/admin', 'http://example.com/admin') => false
Environment:
- Node.js runtime (any recent LTS)
- No external services, databases, or browsers required
- Pure in-process JavaScript test
Recommendations / Next Steps
- Upgrade immediately to
fast-uri@3.1.1or later. - Audit existing code that uses
normalize()orequal()for path-prefix or URI-allowlist decisions. Replace any ad-hoc workarounds with the patched library. - Add regression tests for encoded traversal sequences (
%2e%2e%2f,%2e%2e,%2f) in your own URI-handling logic. - Consider defense in depth: wherever possible, validate resolved filesystem paths (e.g., using
path.resolve()and checking the result is under a trusted root) rather than relying solely on URI normalization.
Additional Notes
- Idempotency: The reproduction script was executed twice consecutively with identical results, confirming idempotency.
- Edge cases tested: single encoded slash (
%2f), double encoded dot-dot (%2e%2e), chained sequences (%2e%2e/%2e%2e), and theequal()false-positive case. All behaved consistently with the vulnerability description.
CVE-2026-6321 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-6321
Scripts, logs, diffs, and output captured during the reproduction.
No artifacts available
How to Fix CVE-2026-6321
Upgrade fast-uri · npm to 3.1.1 or later.
FAQ: CVE-2026-6321
How does the CVE-2026-6321 traversal bypass work in practice?
Which fast-uri versions are affected by CVE-2026-6321, and where is it fixed?
How severe is CVE-2026-6321?
How can I reproduce CVE-2026-6321?
References for CVE-2026-6321
Authoritative sources for CVE-2026-6321 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.