← Back to Feed CACHED · 2026-08-18 21:18:14 · CACHE_KEY CVE-2026-16732
CVE-2026-16732 · CWE-348 · Disclosed 2026-03-24

fastify vulnerable to X-Forwarded-* spoofing under trustProxy hop-count

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

Like a VIP badge scanner that still reads fake laminates if you sneak past the rope line

Fastify versions prior to 5.8.3 contain a flaw in how request.protocol and request.host getters process X-Forwarded-Proto and X-Forwarded-Host headers. When trustProxy is configured with a *restrictive* trust function (a specific IP, subnet, hop count, or custom function), these getters still read forwarded headers from any connection — including untrusted ones that bypass the reverse proxy entirely. An attacker who can open a direct TCP connection to the Fastify listening port can spoof the perceived protocol (e.g., force https on a plaintext connection) and host, potentially undermining HTTPS enforcement, secure cookie flags, CSRF origin checks, and host-based routing. Affected versions: fastify < 5.8.3; fixed in 5.8.3+.

The vendor rates this MEDIUM at CVSS 6.1, and that assessment is *fair to generous*. The AV:A (Adjacent Network) attack vector already encodes the hard prerequisite: the attacker must bypass the reverse proxy and reach the raw Fastify port, which in any competent deployment sits behind an ALB, nginx, or similar edge. The AC:H (High Complexity) further reflects the need for a specific trustProxy configuration. The impact is Confidentiality-High with Scope Changed, but there is no Integrity or Availability impact — the attacker can *read* things they shouldn't by tricking protocol/host logic, but cannot write data or crash the service. With an EPSS of 0.12% (3rd percentile) and zero known exploitation, the real-world risk is narrow.

"Adjacent-network header spoof in Fastify trustProxy — narrow conditions, no active exploitation."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify exposed Fastify port

The attacker scans internal network segments or cloud VPCs for the raw Fastify listening port (commonly 3000, 8080, or similar). In most production deployments this port is bound to 127.0.0.1 or firewalled behind a load balancer, but misconfigured cloud security groups or flat internal networks can leave it reachable. The attacker needs adjacent network access — either on the same VLAN, VPC, or having compromised a neighboring host.
Conditions required:
  • Adjacent network access to the Fastify listening port
  • Fastify port not bound to loopback or firewalled
Where this breaks in practice:
  • Most production deployments bind Fastify behind a reverse proxy with the app port unreachable externally
  • Cloud deployments typically use security groups/NACLs restricting direct port access
  • Container orchestration (ECS, K8s) usually exposes only the load balancer endpoint
Detection/coverage: Network scanning tools (nmap) or cloud asset inventory showing open application ports on non-standard listeners.
STEP 02

Confirm trustProxy restrictive config

The vulnerability only fires when trustProxy is set to a restrictive function (IP, subnet, hop count, or custom function) — not when set to true (trust all) or false (trust none). The attacker can infer this by sending a crafted X-Forwarded-Proto: https header on an HTTP connection and observing whether the application behaves as if the connection is HTTPS (e.g., sets Secure cookies, redirects differently). This is a necessary precondition that limits the vulnerable population.
Conditions required:
  • trustProxy configured with restrictive trust function (not true or false)
  • Application uses request.protocol or request.host for security logic
Where this breaks in practice:
  • Many Fastify deployments use trustProxy: true (not vulnerable) or trustProxy: false (not vulnerable)
  • Applications that don't rely on request.protocol/request.host for security decisions are unaffected even if the getter is spoofable
STEP 03

Craft spoofed X-Forwarded headers

The attacker sends HTTP requests directly to the Fastify port with X-Forwarded-Proto: https and/or X-Forwarded-Host: attacker-controlled.com. Because the vulnerable code reads these headers before checking whether the connection comes from a trusted proxy, the application sees the spoofed values. No special tooling is needed — curl suffices: curl -H 'X-Forwarded-Proto: https' -H 'X-Forwarded-Host: evil.com' http://target:3000/.
Conditions required:
  • Steps 1 and 2 satisfied
Where this breaks in practice:
  • Requires direct TCP to the app port — WAFs and edge proxies in the normal request path strip or override these headers
Detection/coverage: WAF rules or reverse proxy configs that strip X-Forwarded-* from non-trusted sources will block this. Application-level logging of request.protocol mismatches can detect anomalies.
STEP 04

Exploit spoofed protocol/host

With protocol and host spoofed, the attacker exploits downstream security logic: bypassing HTTPS-only cookie enforcement (cookies sent over plaintext), defeating CSRF origin validation (mismatched host), or manipulating URL construction for open redirects or SSRF via crafted host headers. The actual impact depends entirely on what the application does with request.protocol and request.host. In the worst case, authentication tokens leak over plaintext; in the common case, the impact is limited to incorrect redirect URLs.
Conditions required:
  • Application makes security-sensitive decisions based on request.protocol or request.host
Where this breaks in practice:
  • Many modern apps use framework-level CSRF protections that don't solely rely on host header matching
  • HSTS preload on the domain prevents browser-side protocol downgrade even if the server is confused
  • Token leakage requires the attacker to also intercept the plaintext traffic (additional MitM requirement)
Detection/coverage: Monitor for requests where the transport-layer protocol disagrees with the application-layer request.protocol value.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Not listed on CISA KEV. No reports of active campaigns or exploitation in the wild as of 2026-08-19.
Proof-of-ConceptTrivial to reproduce with curl — the GHSA-444r-cwp2-x5xf advisory describes the exact header manipulation. No weaponized exploit tools circulating.
EPSS Score0.12% probability of exploitation in next 30 days (3rd percentile). Extremely low predicted exploitation activity.
KEV StatusNot listed. No CISA KEV entry.
CVSS VectorCVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N — Adjacent network, high complexity, no privileges, scope changed, confidentiality-high only. The AV:A is the key limiter.
Affected Versionsfastify < 5.8.3 (all 5.x releases through 5.8.2 when using restrictive trustProxy). Versions using trustProxy: true or trustProxy: false are not affected.
Fixed Versionfastify 5.8.3 (npm). No backports to 4.x branch.
Exposure / Scanning DataFastify receives ~8.5M npm downloads/week with ~5,500 dependent packages. However, direct internet exposure of raw Fastify ports (bypassing reverse proxy) is uncommon — no significant Shodan/Censys fingerprint for exposed Fastify instances.
Disclosure Date2026-03-24 (published via GitHub Security Advisory and Snyk).
Reporting ResearcherDisclosed via the Fastify project's responsible disclosure process. Specific researcher not publicly credited in the advisory.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.5/10)

The single most decisive factor is the AV:A (adjacent network) prerequisite: exploitation requires direct TCP connectivity to the Fastify application port, bypassing the reverse proxy — a condition absent in the vast majority of production deployments where the app port is firewalled or loopback-bound. Combined with the narrow trustProxy configuration requirement and confidentiality-only impact (no RCE, no integrity, no availability), the real-world risk sits below the vendor's 6.1.

HIGH Vulnerability mechanics and affected versions
HIGH No active exploitation or KEV listing
MEDIUM Deployed population with vulnerable trustProxy configurations (unknown share)

Why this verdict

  • Adjacent-network gate: AV:A means the attacker must already have internal network access or be on the same VLAN/VPC. In cloud-native Fastify deployments behind ALBs, security groups block direct port access. This eliminates unauthenticated remote attack from the internet.
  • Configuration-dependent: Only fires with restrictive trustProxy settings (hop count, IP, subnet, custom function). Deployments using trustProxy: true (common for apps behind a single trusted proxy) and trustProxy: false are unaffected, narrowing the vulnerable population.
  • Confidentiality-only, no RCE: Impact is limited to protocol/host spoofing leading to potential cookie leakage or CSRF bypass — not remote code execution, not data destruction, not lateral movement.
  • Role multiplier: Fastify is an application-tier web framework. It is not a domain controller, hypervisor, identity provider, PAM, backup system, or kernel-mode agent. Its canonical deployment role is a line-of-business API server. Blast radius of a successful exploit is confined to the single application's session/cookie security — host-level at worst, not fleet or domain scale. Even in an API gateway role (via @fastify/http-proxy), the spoofing affects protocol/host perception, not arbitrary command execution. No high-value role floor override applies.
  • EPSS 0.12% (3rd percentile): Predictive models rate exploitation probability as extremely low, consistent with zero observed in-the-wild activity.

Why not higher?

Upgrading to HIGH would require either active exploitation, a broader attack vector (AV:N), or a blast radius reaching fleet/domain compromise. None of these conditions are present. The vulnerability cannot achieve RCE, and the adjacent-network prerequisite plus configuration dependency compound to significantly reduce the reachable population. The Scope:Changed flag reflects cross-component impact on downstream security logic, but the actual damage ceiling (cookie/protocol confusion) does not rise to HIGH-tier consequences.

Why not lower?

The Scope:Changed with C:H means a successful exploit can leak authentication tokens or bypass HTTPS enforcement in downstream components beyond the Fastify process itself. While conditions are narrow, the *potential* for credential theft via plaintext cookie leakage is non-trivial in environments where the preconditions are met. Dismissing to LOW would undercount the risk for the subset of deployments with flat networks and restrictive trustProxy configs.

05 · Compensating Control

What to do — in priority order.

  1. Bind Fastify to loopback or restrict with firewall rules — Ensure the Fastify application port (e.g., 3000) is only reachable from the reverse proxy's IP. Use host: '127.0.0.1' in the Fastify listen config, or enforce security group / iptables rules. This eliminates the AV:A prerequisite entirely. As a MEDIUM verdict, no mitigation SLA applies — go straight to the 365-day remediation window.
  2. Strip X-Forwarded-* headers at the reverse proxy — Configure nginx, HAProxy, or your ALB to overwrite (not append) X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-For headers. This ensures only proxy-set values reach Fastify, neutralizing the spoofing vector regardless of Fastify version.
  3. Upgrade to fastify 5.8.3+ — The definitive fix. The patched version correctly gates X-Forwarded-* header processing on whether the connection originates from a trusted proxy IP. Run npm audit or check package-lock.json to verify your installed version across all services.
  4. Audit trustProxy configurations — Grep your codebase for trustProxy settings. If you're using trustProxy: true or trustProxy: false, you are not affected — document this and close the finding. If using hop count, IP, or custom function, prioritize those services for the upgrade.
What doesn't work
  • WAF rules on the edge proxy — the vulnerability requires *bypassing* the proxy entirely, so WAF rules on the proxy path don't help if the attacker reaches the app port directly. The WAF never sees the malicious request.
  • HSTS headers alone — HSTS protects the browser from protocol downgrade, but server-side logic using request.protocol is still spoofable. If the app makes backend decisions based on the spoofed protocol (e.g., constructing callback URLs), HSTS doesn't prevent that.
06 · Verification

Crowdsourced verification payload.

Run this on each host running a Fastify application, or in your CI pipeline against package.json / package-lock.json. No special privileges needed. Example: bash check_fastify_cve.sh /path/to/your/app

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# Check for CVE-2026-16732 / CVE-2026-3635: Fastify X-Forwarded-* spoofing
# Usage: bash check_fastify_cve.sh /path/to/node/app
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

APP_DIR="${1:-.}"
FIXED_VERSION="5.8.3"

if [ ! -d "$APP_DIR" ]; then
  echo "UNKNOWN - Directory $APP_DIR does not exist"
  exit 2
fi

# Try package-lock.json first
LOCK="$APP_DIR/package-lock.json"
if [ -f "$LOCK" ]; then
  INSTALLED=$(python3 -c "
import json, sys
with open('$LOCK') as f:
    data = json.load(f)
# npm v2+ lockfile format
for key in ['packages', 'dependencies']:
    if key in data:
        for pkg, info in data[key].items():
            if 'fastify' in pkg and 'node_modules/fastify' in pkg or pkg == 'fastify':
                v = info.get('version', '')
                if v:
                    print(v)
                    sys.exit(0)
print('')
" 2>/dev/null)
else
  # Fallback: check node_modules
  PKG_JSON="$APP_DIR/node_modules/fastify/package.json"
  if [ -f "$PKG_JSON" ]; then
    INSTALLED=$(python3 -c "import json; print(json.load(open('$PKG_JSON'))['version'])" 2>/dev/null)
  else
    echo "UNKNOWN - Cannot find fastify in $APP_DIR"
    exit 2
  fi
fi

if [ -z "$INSTALLED" ]; then
  echo "UNKNOWN - Could not determine fastify version"
  exit 2
fi

# Compare versions
RESULT=$(python3 -c "
from packaging.version import Version
installed = Version('$INSTALLED')
fixed = Version('$FIXED_VERSION')
if installed >= fixed:
    print('PATCHED')
else:
    print('VULNERABLE')
" 2>/dev/null || echo "UNKNOWN")

echo "$RESULT - fastify $INSTALLED installed (fixed in >= $FIXED_VERSION)"

case "$RESULT" in
  PATCHED)    exit 0 ;;
  VULNERABLE) exit 1 ;;
  *)          exit 2 ;;
esac
07 · Bottom Line

If you remember one thing.

TL;DR
This is a MEDIUM severity finding with narrow real-world exploitability. As a MEDIUM under the noisgate remediation SLA, there is no mitigation SLA — go straight to the 365-day remediation window to upgrade fastify to 5.8.3+. That said, the fix is a simple npm update fastify with no breaking changes, so there is no reason to wait. Monday morning: run npm audit across your Node.js fleet to identify services still on fastify < 5.8.3. For any hits, verify that the Fastify port is not directly reachable from untrusted network segments (it almost certainly isn't if you're behind an ALB or nginx). If you confirm the app port is firewalled to the proxy, the risk is effectively zero even unpatched. Roll the upgrade into your next scheduled dependency update cycle. No emergency patching warranted.

Sources

  1. GitHub Security Advisory GHSA-444r-cwp2-x5xf
  2. Snyk Vulnerability DB — SNYK-JS-FASTIFY-15762220
  3. SentinelOne Vulnerability Database — CVE-2026-3635
  4. GitLab Advisory Database — CVE-2026-3635
  5. NVD — CVE-2026-3635
  6. fastify on npm
  7. OSV — GHSA-444r-cwp2-x5xf
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.