A bouncer checks IDs before guests remove their disguises, so the costume hides the parent-directory climb
The @fastify/http-proxy plugin forwards requests under a configured prefix and validates that the destination stays inside it. In versions 11.6.0 through 11.6.2, the validator normalizes literal backslashes first and only then percent-decodes the path. Attackers can send %5c and %2e%2e sequences that pass the dot-segment check, then become \.. after decoding. On an upstream that treats backslash as a path separator — most commonly a Windows-hosted service — the forwarded request climbs out of the prefix and reaches a sibling location.
The vendor's MEDIUM severity is broadly correct but a touch high for typical Linux-heavy Fastify deployments. The exploit only fires when the upstream is Windows or similarly configured, and only when sensitive resources exist outside the intended prefix. Across a 10,000-host estate, the realistic exposure is a subpopulation of reverse-proxy-to-Windows setups, so we assess this at the low end of MEDIUM.
5 steps from start to impact.
Identify exposed Fastify proxy endpoint
@fastify/http-proxy with a configured prefix. This may be via internet scanning, internal recon, or app enumeration.- Network access to the proxy endpoint
- Proxy has a configured prefix
- Most Fastify apps are internal or behind edge WAF/gateways
- Public exposure of a Node reverse proxy with a Windows upstream is uncommon
x-powered-by or default headers, but not proxy plugin config.Craft encoded backslash and dot-segment path
/prefix/%5c..%5c..%5cWindows%5cwin.ini. The validator sees encoded backslashes as literal characters and does not treat them as path separators; the dot-segment check passes because %2e has not yet been decoded.- Understanding of the proxy prefix mapping
- Upstream path structure knowledge
- Requires knowing or guessing the upstream filesystem/route layout
- Encoded backslashes may be blocked by some edge filters
Proxy decodes path after validation
%5c into \ and %2e%2e into ... The request now contains literal backslash and dot-dot sequences that the validator did not see.- Fastify http-proxy versions 11.6.0–11.6.2
- The validation order is vulnerable
- Fixed in 11.6.3; only unpatched versions affected
Upstream resolves backslash path separator
\ is a path separator, so \..\ climbs out of the configured prefix. The request reaches a sibling file or endpoint outside the intended area.- Upstream runs on Windows or a platform treating backslash as separator
- Upstream has sibling resources accessible via web path traversal
- Linux upstreams treat backslash as a literal character, making the attack inert
- Windows upstreams behind a Node proxy are a minority of deployments
Retrieve sibling resource content
- Sensitive data exists outside prefix
- Upstream service account has read access to the targeted sibling
- Not all sibling paths contain sensitive data
- Upstream may restrict service account permissions
@fastify/http-proxy to 11.6.3 or later — The fix corrects the normalization order. Since verdict is MEDIUM, noisgate remediation SLA is ≤365 days; schedule the upgrade as a normal patch cycle. This fully eliminates the flaw.%5c or %2e%2e at the edge/WAF — A WAF or reverse proxy can reject encoded backslash and dot-segment patterns before they reach Fastify. This breaks the exploit chain even on unpatched versions, though bypass risk remains if normalization differs.\ as a path separator, the decoded traversal has no effect. This is effective for the specific condition but assumes you control the upstream platform.- Relying on the proxy prefix alone for containment — the entire vulnerability is a prefix escape.
- Upstream authentication without path normalization — authenticated users can still send the crafted path and traverse.
- Disabling directory listing on upstream — doesn't prevent reading known file paths outside the prefix.
The supporting signals.
| In-the-wild | No known active exploitation; not listed in CISA KEV as of assessment. |
|---|---|
| PoC availability | No public PoC on pocindex.io or GitHub at assessment time; the path trick is simple enough that a private PoC is likely. |
| EPSS | Not yet scored in EPSS; expected low percentile given conditional upstream dependency. |
| KEV status | Not listed in CISA Known Exploited Vulnerabilities catalog. |
| CVSS vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N — network attack, high complexity, confidentiality only. |
| Affected versions | @fastify/http-proxy 11.6.0 – 11.6.2. |
| Fixed version | 11.6.3; upgrade to latest. |
| Disclosure date | Not available in the CVE record; treat as recent 2026 disclosure. |
| Reporter | Not disclosed in the record; likely coordinated via GitHub Security Advisory. |
Sources.
Why this verdict
- Conditional exploit: the backslash-as-separator requirement knocks out the majority of Linux upstreams, so real exposure is a niche Windows-upstream subset.
- Unauthenticated but blind: no auth needed, but attacker needs to know or guess path layout and sibling resource existence, adding practical friction.
- Role multiplier:
@fastify/http-proxyis an app-tier reverse proxy, not a domain controller, CA, PAM, hypervisor, or edge appliance; a successful read can expose files but does not yield domain/fleet/supply-chain takeover. - No active exploitation: not KEV-listed and no public PoC yet, so imminent mass exploitation risk is low.
Why not higher?
Not higher because the chain requires a Windows upstream and a sensitive sibling location; most Fastify deployments run on Linux where backslashes are inert. The impact is read-only, with no code execution or lateral movement primitive. Current evidence shows no exploitation in the wild.
Why not lower?
Not lower because the attack is unauthenticated, the path trick is deterministic on affected versions, and reverse proxies to legacy Windows file/web servers still exist in enterprise environments. A successful read can expose configuration files or data that facilitate further attacks.
Crowdsourced verification payload.
Run this script on each host where a Fastify app using @fastify/http-proxy is deployed, from the application root or with the app directory as the first argument. Example: bash check_fastify_http_proxy_cve-2026-120214.sh /srv/myapp. Requires read access to the app's node_modules and node on PATH.
#!/usr/bin/env bash
set -euo pipefail
# CVE-2026-120214: @fastify/http-proxy 11.6.0-11.6.2 prefix escape
TARGET_DIR="${1:-$(pwd)}"
cd "$TARGET_DIR" || { echo "UNKNOWN: cannot access $TARGET_DIR"; exit 3; }
if ! command -v node >/dev/null 2>&1; then
echo "UNKNOWN: node not found on PATH"
exit 3
fi
VERSION=""
if [ -f "node_modules/@fastify/http-proxy/package.json" ]; then
VERSION=$(node -e "console.log(require('./node_modules/@fastify/http-proxy/package.json').version)" 2>/dev/null || true)
else
VERSION=$(node -e "try{console.log(require('@fastify/http-proxy/package.json').version)}catch(e){}" 2>/dev/null || true)
fi
if [ -z "$VERSION" ]; then
echo "UNKNOWN: @fastify/http-proxy not found in $TARGET_DIR"
exit 3
fi
# Compare to affected range 11.6.0 - 11.6.2
IFS=. read -r major minor patch <<< "$(echo "$VERSION" | tr '-' '.')"
if [[ "$major" == "11" && "$minor" == "6" ]]; then
if [[ "$patch" =~ ^[0-9]+$ ]] && [ "$patch" -ge 0 ] && [ "$patch" -le 2 ]; then
echo "VULNERABLE: @fastify/http-proxy $VERSION"
exit 0
fi
fi
echo "PATCHED: @fastify/http-proxy $VERSION"
exit 0