Someone left the back gate open by only checking forward slashes while backslashes waltz right through
CVE-2026-85124 is a path-traversal flaw in @fastify/http-proxy versions prior to 11.6.2. When the plugin is configured with prefix and rewritePrefix to expose only a subset of an upstream service, the HTTP request handler validates traversal sequences using forward-slash dot-segments (../) but ignores backslash equivalents (..\). An unauthenticated attacker sends GET /pub/dir\..\..\secret, and the new URL() constructor normalises the backslashes into path separators, collapsing segments and delivering the request to upstream paths outside the allowed prefix — such as admin panels, health endpoints, or internal APIs the proxy was explicitly hiding. The package has ~162K weekly npm downloads and this is the third prefix-escape variant disclosed in 2026 (after CVE-2026-16117 and CVE-2026-15631).
The vendor's HIGH / 7.5 rating is accurate and well-calibrated. The attack is unauthenticated, network-reachable, and low-complexity — three factors that rightly push severity up. The scope is limited to confidentiality only (C:H/I:N/A:N): you can read what's behind the upstream, but you cannot modify data or crash the service through this vector alone. That ceiling on impact is what keeps the score from reaching CRITICAL. The vector also requires the application to be using prefix-based routing to an upstream with sensitive paths outside the allowed prefix — a common but not universal configuration pattern.
4 steps from start to impact.
Identify a Fastify proxy endpoint
@fastify/http-proxy with a visible prefix route such as /api/ or /pub/. This is typically found via simple path enumeration, response headers, or JavaScript bundle analysis. No tooling beyond a browser or curl is needed.- Target application uses @fastify/http-proxy < 11.6.2
- Application is internet- or network-reachable
- Application must be using prefix/rewritePrefix configuration — not all deployments use this pattern
x-powered-by header (if not stripped) can identify potential targets.Craft backslash dot-segment request
GET /pub/x\..\..\admin HTTP/1.1. No authentication is required. The request can be sent with curl, a browser, or any HTTP client. The key insight is that the traversal guard only rejects /.. sequences, not \.. sequences.- Attacker can send arbitrary HTTP requests to the proxy endpoint
- Some upstream web servers (e.g. nginx, Apache) may reject or normalise backslash paths before processing, neutralising the traversal
- WAFs with path-normalisation rules may block backslash sequences
../ will miss it.Proxy forwards to unintended upstream path
@fastify/reply-from library underlying the proxy receives the request with the raw backslash path. It passes the URL to new URL(), which normalises backslashes as path separators and collapses .. segments. The resulting request targets an upstream path outside the configured rewritePrefix boundary — e.g. /admin instead of /internal/x.- Upstream service has sensitive paths outside the prefix boundary
- Upstream processes the normalised request and returns content
- If the upstream service itself requires authentication on sensitive paths, the leaked content is limited to unauthenticated endpoints
- Upstream may return 404/403 for paths the attacker doesn't know about
Exfiltrate internal data or pivot
- Upstream exposes sensitive data on paths reachable via traversal
- Impact is confidentiality-only — no direct RCE, no write capability, no DoS
- Actual blast radius is bounded by what the upstream serves on the escaped paths
The supporting signals.
| In-the-Wild Exploitation | No known active exploitation as of 2026-09-03. Not listed in CISA KEV. Disclosed same day (today). |
|---|---|
| Proof of Concept | The GitHub advisory GHSA-qv33-689p-2xq5 includes a conceptual PoC: GET /pub/x\..\..\secret. Exploitation is trivial — a single curl command. No standalone exploit repos identified yet. |
| EPSS Score | Not yet scored (CVE published 2026-09-03). Prior variants CVE-2026-16117 and CVE-2026-15631 had low-to-moderate EPSS given the application-layer scope. |
| KEV Status | Not listed. No CISA KEV entry as of 2026-09-03. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — Unauthenticated network attack, low complexity, confidentiality-only impact. No integrity or availability impact limits the ceiling. |
| Affected Versions | @fastify/http-proxy < 11.6.2 (all prior versions using prefix/rewritePrefix). Note: versions < 11.6.0 are also affected by CVE-2026-16117 and CVE-2026-15631. |
| Fixed Version | @fastify/http-proxy 11.6.2. No backports to older major lines documented. |
| Exposure / Install Base | ~162K weekly npm downloads per npmjs.com. Moderate adoption — significantly smaller than Express ecosystem proxies. Shodan/Censys cannot directly enumerate this (application-layer library, not a network appliance). |
| Disclosure Date | 2026-09-03 (today). Coordinated disclosure by EQSTLab via GitHub Security Advisory. |
| Reporting Researcher | EQSTLab (reporter). Fix developed by mcollina and UlisesGascon (Fastify core team). |
noisgate verdict.
The vendor's HIGH / 7.5 is justified because the attack is unauthenticated, network-reachable, and trivially exploitable with a single HTTP request — no tooling, credentials, or user interaction required. The single most decisive factor sustaining the HIGH rating is the zero-prerequisite remote exploitability combined with the confidentiality impact ceiling (C:H/I:N/A:N): easy to reach, meaningful data leak, but no path to code execution or persistence through this vector alone.
Why this verdict
- Unauthenticated remote access with zero complexity — the attack requires only a single crafted HTTP request. No credentials, no user interaction, no prior foothold. This is the strongest upward pressure on severity.
- Confidentiality-only impact caps the ceiling — the CVSS vector explicitly scores I:N/A:N. The attacker can read upstream paths but cannot modify data, execute code, or cause denial of service through this bug alone. This prevents escalation to CRITICAL.
- Configuration-dependent exposure — the vulnerability only fires when the application uses
prefix+rewritePrefixconfiguration AND the upstream has sensitive paths outside the prefix boundary. Not all deployments meet both conditions, but this is a common pattern for API gateways and BFF architectures. - Role multiplier: @fastify/http-proxy is an application-layer Node.js library, not a network edge appliance or identity provider. Its high-value role is as an API gateway or BFF proxy in microservice architectures. In that role, a successful traversal can leak internal microservice endpoints, health checks with environment variables, or admin APIs — blast radius is tenant-to-service level, not fleet or domain level. The library is not canonically a high-value-role component (it's not a hypervisor, DC, PAM, or CA), so the floor is HIGH based on the unauthenticated network vector, not elevated to CRITICAL.
- Third variant in the same package in 2026 — the pattern of repeated prefix-escape bypasses (URL-encoding, WebSocket, now backslash) suggests the input validation approach is fundamentally fragile. This increases confidence that the vulnerability is real and the attack surface is well-understood by researchers.
Why not higher?
CRITICAL would require either integrity/availability impact (RCE, data modification, DoS), active exploitation, or a fleet-scale blast radius. This vulnerability is read-only — it leaks upstream paths but provides no write primitive or code execution. The affected component is an application-layer npm library, not a canonical high-value-role component like a hypervisor or domain controller. The blast radius is bounded to the specific upstream service's exposed paths, not fleet-wide.
Why not lower?
The attack is completely unauthenticated and requires only a single HTTP request with no special tooling — this is about as frictionless as web vulnerabilities get. The 162K weekly download count and common API-gateway use case mean a non-trivial number of internet-facing applications are affected. Downgrading to MEDIUM would understate the ease of exploitation and the realistic likelihood that internal endpoints behind these proxies contain sensitive data (tokens, configs, admin UIs).
What to do — in priority order.
- Deploy WAF rule normalising backslashes to forward slashes in URL paths — A WAF or reverse proxy (nginx, Cloudflare, AWS ALB) in front of the Fastify application that rewrites
\to/in request paths before forwarding will neutralise this traversal variant. Deploy within the noisgate mitigation SLA of 30 days for HIGH severity. Most WAF platforms support this via a request transformation rule. - Strip or reject requests containing backslash characters in the URL path — If your application has no legitimate reason for backslashes in URL paths (most don't), configure your edge proxy or load balancer to return 400 for any request with
\in the path. This is a more aggressive but simpler control. Deploy within 30 days. - Add upstream authentication on sensitive paths — Ensure the upstream service behind the proxy enforces its own authentication on admin/internal endpoints rather than relying solely on the proxy's prefix restriction for access control. This is defense-in-depth that limits the blast radius even if the prefix is bypassed.
- Upgrade to @fastify/http-proxy ≥ 11.6.2 — The definitive fix. Run
npm update @fastify/http-proxyor pin^11.6.2in package.json. This also covers the two prior prefix-escape CVEs (CVE-2026-16117, CVE-2026-15631) if you haven't patched those yet. Target the noisgate remediation SLA of 180 days for HIGH, but given the trivial exploitability, aim for your next sprint.
- Rate limiting — this attack requires only a single request to succeed; rate limiting provides no protection against path traversal.
- Forward-slash-only traversal rules — WAF rules that only match
../or%2e%2e/will miss the backslash variant (..\). Ensure your rules normalise backslashes first. - CORS headers — CORS is a browser-enforced policy. This attack can be executed from any HTTP client (curl, scripts, scanners) and is not constrained by CORS.
Crowdsourced verification payload.
Run this script on any machine with node and npm installed to check if a project's @fastify/http-proxy dependency is vulnerable. Invoke it from the root of your Node.js project directory: bash check_cve_2026_85124.sh /path/to/your/project. No special privileges required.
#!/usr/bin/env bash
# check_cve_2026_85124.sh — Detect CVE-2026-85124 in @fastify/http-proxy
# Usage: bash check_cve_2026_85124.sh [/path/to/project]
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
PROJECT_DIR="${1:-.}"
PKG_NAME="@fastify/http-proxy"
FIXED_VERSION="11.6.2"
if ! command -v node &>/dev/null; then
echo "UNKNOWN — node is not installed"
exit 2
fi
# Try to resolve the installed version
if [ -f "$PROJECT_DIR/node_modules/$PKG_NAME/package.json" ]; then
INSTALLED=$(node -e "console.log(require('$PROJECT_DIR/node_modules/$PKG_NAME/package.json').version)" 2>/dev/null)
elif command -v npm &>/dev/null; then
INSTALLED=$(cd "$PROJECT_DIR" && npm ls "$PKG_NAME" --json 2>/dev/null | node -e "
const j=require('fs').readFileSync('/dev/stdin','utf8');
const d=JSON.parse(j);
function find(o){if(!o)return null;if(o.dependencies&&o.dependencies['$PKG_NAME'])return o.dependencies['$PKG_NAME'].version;for(const k in(o.dependencies||{})){const r=find(o.dependencies[k]);if(r)return r;}return null;}
const v=find(d);console.log(v||'');
" 2>/dev/null)
else
echo "UNKNOWN — cannot determine installed version of $PKG_NAME"
exit 2
fi
if [ -z "$INSTALLED" ]; then
echo "UNKNOWN — $PKG_NAME not found in $PROJECT_DIR"
exit 2
fi
# Compare versions using node semver logic
RESULT=$(node -e "
const inst = '$INSTALLED'.split('.').map(Number);
const fix = '$FIXED_VERSION'.split('.').map(Number);
for (let i = 0; i < 3; i++) {
if (inst[i] < fix[i]) { console.log('VULNERABLE'); process.exit(0); }
if (inst[i] > fix[i]) { console.log('PATCHED'); process.exit(0); }
}
console.log('PATCHED');
")
echo "$RESULT — $PKG_NAME $INSTALLED installed (fixed in >= $FIXED_VERSION)"
if [ "$RESULT" = "VULNERABLE" ]; then
exit 1
elif [ "$RESULT" = "PATCHED" ]; then
exit 0
else
exit 2
fiIf you remember one thing.
prefix/rewritePrefix routing (the API-gateway pattern), you are exposed. Under the noisgate mitigation SLA for HIGH severity, deploy a compensating control — a WAF rule that normalises or blocks backslashes in URL paths — within 30 days. Under the noisgate remediation SLA, apply the actual patch (npm update @fastify/http-proxy to ≥ 11.6.2) within 180 days, though given how easy exploitation is, prioritise this in your next deployment cycle. This is the third prefix-escape bypass in this package in 2026; if you patched to 11.6.0 for the July advisories, you still need 11.6.2. Audit your upstream services to confirm they enforce their own auth on sensitive paths rather than relying on the proxy prefix as a security boundary.Sources
- GitHub Advisory GHSA-qv33-689p-2xq5
- @fastify/http-proxy npm package
- Prior advisory: URL-encoded prefix escape (GHSA-mx7v-qhg9-2mvv)
- Prior advisory: WebSocket path traversal (GHSA-7hrw-592w-9wh2)
- fast-uri backslash authority advisory (GHSA-7p8r-x3mc-p8w7)
- Socket.dev @fastify/http-proxy analysis
- Original 2021 prefix escape advisory (GHSA-c4qr-gmr9-v23w)
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.