← Back to Feed CACHED · 2026-09-03 11:49:34 · CACHE_KEY CVE-2026-85124
CVE-2026-85124 · CWE-22 · Disclosed 2026-09-03

@fastify/http-proxy vulnerable to prefix escape via backslash dot-segments

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

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.

"Trivial unauthenticated path traversal in a popular Node.js proxy; keep vendor HIGH"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a Fastify proxy endpoint

The attacker discovers a web application fronted by @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.
Conditions required:
  • Target application uses @fastify/http-proxy < 11.6.2
  • Application is internet- or network-reachable
Where this breaks in practice:
  • Application must be using prefix/rewritePrefix configuration — not all deployments use this pattern
Detection/coverage: Web application scanners that fingerprint Fastify via the x-powered-by header (if not stripped) can identify potential targets.
STEP 02

Craft backslash dot-segment request

The attacker sends a request with backslash-based path traversal embedded after the prefix, e.g. 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.
Conditions required:
  • Attacker can send arbitrary HTTP requests to the proxy endpoint
Where this breaks in practice:
  • 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
Detection/coverage: WAF rules that normalise backslashes to forward slashes before inspection will flag this. Regex-based path traversal rules that only look for ../ will miss it.
STEP 03

Proxy forwards to unintended upstream path

The @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.
Conditions required:
  • Upstream service has sensitive paths outside the prefix boundary
  • Upstream processes the normalised request and returns content
Where this breaks in practice:
  • 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
Detection/coverage: Upstream access logs will show requests to paths that should never arrive from the proxy. Anomaly detection on upstream path patterns can catch unexpected traversal.
STEP 04

Exfiltrate internal data or pivot

The attacker reads responses from the upstream's internal paths. Depending on what the upstream exposes, this could include health/status endpoints with environment variables, internal API documentation (Swagger/OpenAPI), admin interfaces, or other microservice endpoints. In the worst case, leaked credentials or tokens from internal endpoints enable lateral movement.
Conditions required:
  • Upstream exposes sensitive data on paths reachable via traversal
Where this breaks in practice:
  • 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
Detection/coverage: DLP or API gateway logging that monitors response payloads for sensitive patterns (tokens, keys, PII) can detect exfiltration.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo known active exploitation as of 2026-09-03. Not listed in CISA KEV. Disclosed same day (today).
Proof of ConceptThe 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 ScoreNot 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 StatusNot listed. No CISA KEV entry as of 2026-09-03.
CVSS VectorCVSS: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 Date2026-09-03 (today). Coordinated disclosure by EQSTLab via GitHub Security Advisory.
Reporting ResearcherEQSTLab (reporter). Fix developed by mcollina and UlisesGascon (Fastify core team).
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.5/10)

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.

HIGH Vulnerability existence and attack mechanism
HIGH Affected/fixed version ranges
MEDIUM Real-world exploitability (depends on upstream topology)
LOW Active exploitation status (CVE is hours old)

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 + rewritePrefix configuration 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).

05 · Compensating Control

What to do — in priority order.

  1. 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.
  2. 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.
  3. 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.
  4. Upgrade to @fastify/http-proxy ≥ 11.6.2 — The definitive fix. Run npm update @fastify/http-proxy or pin ^11.6.2 in 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.
What doesn't work
  • 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.
06 · Verification

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.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/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
fi
07 · Bottom Line

If you remember one thing.

TL;DR
This CVE dropped today (2026-09-03) and is trivially exploitable with a single HTTP request — no auth, no tooling. If you run @fastify/http-proxy with 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

  1. GitHub Advisory GHSA-qv33-689p-2xq5
  2. @fastify/http-proxy npm package
  3. Prior advisory: URL-encoded prefix escape (GHSA-mx7v-qhg9-2mvv)
  4. Prior advisory: WebSocket path traversal (GHSA-7hrw-592w-9wh2)
  5. fast-uri backslash authority advisory (GHSA-7p8r-x3mc-p8w7)
  6. Socket.dev @fastify/http-proxy analysis
  7. Original 2021 prefix escape advisory (GHSA-c4qr-gmr9-v23w)
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.