{
  "ticket_id": "CVE-2026-6322",
  "code_root": "external/fast-uri",
  "source": {
    "type": "cve",
    "cve_id": "CVE-2026-6322",
    "advisory_id": "GHSA-v39h-62p7-jpjc",
    "advisory_url": "https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc",
    "vendor": "fastify",
    "product": "fast-uri",
    "repo": "https://github.com/fastify/fast-uri"
  },
  "facts": {
    "cve_id": "CVE-2026-6322",
    "advisory_id": "GHSA-v39h-62p7-jpjc",
    "issue_summary": "Host confusion in fast-uri. normalize() decodes percent-encoded authority delimiters that appear inside the host and then re-emits them raw. A host string that combines an allowed domain, an encoded '@' (%40), and a second domain is re-emitted with the '@' as a raw userinfo separator, so the effective authority of the normalized URI becomes the SECOND domain. This defeats host-allowlist, SSRF, and redirect-validation checks built on top of normalize().",
    "vulnerability_type": "Interpretation Conflict",
    "suspected_cwe": ["CWE-436"],
    "affected_versions": "<= 3.1.1",
    "fixed_versions": ["3.1.2"],
    "reproduce_version": "3.1.1",
    "verify_fixed_version": "3.1.2",
    "repo_url": "https://github.com/fastify/fast-uri.git",
    "code_root": "external/fast-uri",
    "ecosystem": "npm",
    "package": "fast-uri",
    "affected_functions": ["normalize"],
    "install_recipe": "In a scratch directory run `npm install fast-uri@3.1.1` (vulnerable) or `npm install fast-uri@3.1.2` (fixed). The published npm tarball is the canonical artifact; git tags v3.1.1 / v3.1.2 on the repo are equivalent.",
    "attacker_access": "Any code path that forwards an attacker-influenced URI string into fast-uri's normalize() and then uses the normalized authority/host for an allowlist, SSRF, or redirect-validation decision.",
    "exploit_outline": "Call normalize('https://allowed.com%40attacker.com/'). The vulnerable build decodes the encoded '@' inside the host and re-emits it raw, so the effective authority becomes attacker.com (allowed.com is reinterpreted as userinfo).",
    "vulnerable_indicator": "After normalize('https://allowed.com%40attacker.com/'), the effective authority/host of the normalized URI is `attacker.com`.",
    "fixed_indicator": "In 3.1.2 normalize() does not re-emit the decoded delimiter raw: the effective authority is `allowed.com` (or the input is rejected).",
    "reproduction_requirements": "Node.js (any maintained LTS) plus the fast-uri package at the specified version. No network service, database, browser, or OS-specific behavior required - the difference is observable purely in-process by inspecting the host/authority of the value returned by normalize().",
    "notes": "Do not invent specific version numbers or commit hashes beyond those stated here. The Pruva repro agent reads the patch diff itself (git diff v3.1.1..v3.1.2) to confirm the root cause and guard."
  }
}
