← Back to Feed CACHED · 2026-09-04 10:49:34 · CACHE_KEY CVE-2026-76169
CVE-2026-76169 · CWE-288 · Disclosed 2026-09-04

fastify versions >= 4.0.0 and before 5.12.2 can route a malformed URL sent under one plugin prefix to the…

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

Like a hotel guest slipping a bent key into the wrong room's lock and getting the minibar inventory

CVE-2026-76169 affects Fastify versions >= 4.0.0 and < 5.12.2 — a span of over four years of releases covering both the v4 and v5 major lines. The flaw lives in how Fastify's internal router dispatches malformed request targets. Normally, each plugin prefix gets its own encapsulated setNotFoundHandler with its own authentication hooks (preValidation, preHandler). A crafted, malformed URL sent to a *public* plugin prefix can skip URL decoding and land in a *different* plugin's not-found handler — one that was supposed to be behind authentication. The result is CWE-288: authentication bypass via an alternate path. Impact is confidentiality-only (CVSS C:H/I:N/A:N): the attacker reads data the protected handler exposes, but cannot write or crash the service.

The vendor's HIGH 7.5 rating is defensible but slightly generous. The CVSS vector (AV:N/AC:L/PR:N/UI:N) correctly reflects that the attack is unauthenticated and network-reachable with low complexity. However, the real-world blast radius depends on whether the target application's not-found handler actually *serves protected data* — many Fastify apps simply return a generic {"error": "Not Found"} JSON payload from their 404 handlers, rendering the bypass moot. The advisory explicitly warns that global onRequest authentication hooks do NOT mitigate this flaw, which broadens the exploitable population beyond apps that only use prefix-scoped auth. noisgate holds at HIGH but nudges the score to 7.0 to reflect the data-exposure precondition.

"Auth bypass in Fastify: malformed URLs cross plugin boundaries to reach protected not-found handlers."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify Fastify target with plugin-prefix encapsulation

The attacker fingerprints a web application as running Fastify (via x-powered-by, error format, or response timing). They enumerate route prefixes — e.g. /public, /api, /admin — to identify which prefixes return distinct 404 responses, indicating separate setNotFoundHandler registrations per plugin.
Conditions required:
  • Target runs Fastify >= 4.0.0 and < 5.12.2
  • Application uses multiple plugin prefixes with separate not-found handlers
Where this breaks in practice:
  • Many Fastify deployments sit behind a reverse proxy (nginx, Cloudflare, AWS ALB) that may normalize or reject malformed URLs before they reach Fastify
  • Not all apps use prefix-scoped not-found handlers; single-prefix apps have no cross-prefix to reach
Detection/coverage: WAF rules for malformed request targets; Fastify access logs showing unusual URL encoding in the request line
STEP 02

Craft malformed URL targeting the wrong prefix

The attacker constructs a request with a malformed URL path — likely using partial percent-encoding, null bytes, or path segment abuse — addressed to the *public* prefix. Because Fastify's internal not-found router processes the malformed target before URL decoding, the routing logic misidentifies which plugin prefix the request belongs to and dispatches it to the *protected* plugin's not-found handler instead.
Conditions required:
  • Knowledge of the protected prefix name or ability to brute-force common prefixes like /admin, /internal, /api/v2
Where this breaks in practice:
  • Upstream proxies (nginx, HAProxy, Envoy) with strict URI validation may reject or rewrite the malformed path before it reaches Node.js
  • CDNs like Cloudflare normalize URLs by default, potentially neutralizing the payload
Detection/coverage: IDS/WAF signatures for double-encoded or malformed URI paths; Node.js onBadUrl hook logging (if configured)
STEP 03

Bypass authentication hooks

The protected plugin's preValidation and preHandler authentication hooks are skipped entirely because the request was routed via the internal not-found path rather than the normal route lifecycle. The advisory confirms that even global onRequest hooks do not mitigate this bypass. The attacker's request reaches the not-found handler code with no authentication check applied.
Conditions required:
  • The protected plugin's not-found handler is the target (not a regular route handler)
Where this breaks in practice:
  • If the application uses external auth (e.g., an API gateway like Kong or AWS API Gateway enforcing JWT validation upstream), the bypass at the Fastify layer is irrelevant
  • Applications using middleware-based auth via @fastify/middie may or may not be affected depending on middleware path matching
Detection/coverage: Audit logs showing 404 responses on protected prefixes without corresponding auth token validation events
STEP 04

Exfiltrate protected data from the not-found handler response

The attacker reads the response body from the protected not-found handler. If the handler returns contextual data — user-scoped error messages, partial route listings, internal API metadata, or debug information — the attacker gains unauthorized access to confidential information. The impact ceiling is C:H per the CVSS vector, but the *actual* value depends entirely on what the handler returns.
Conditions required:
  • The protected not-found handler must return data more sensitive than a generic 404 JSON stub
Where this breaks in practice:
  • Many production Fastify apps return a static {"statusCode":404,"error":"Not Found","message":"Route not found"} with no sensitive context — in this case the bypass is a no-op
  • Well-configured apps strip debug output in production (NODE_ENV=production)
Detection/coverage: Response body inspection in WAF or API gateway; anomaly detection on 404 response sizes from protected prefixes
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. Disclosed today (2026-09-04). No KEV listing, no known campaigns.
Proof-of-conceptNot yet public. No PoC repos on GitHub as of disclosure date. Finders: *vvvvvvvvvvitel* and *schecthellraiser606*; fix by *mcollina*, reviewed by *UlisesGascon*.
EPSSNot yet scored — CVE just assigned. Expect initial EPSS within 7-14 days. Predicted range: low-to-moderate given AV:N/PR:N but application-specific preconditions.
KEV statusNot listed as of 2026-09-04.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — 7.5 HIGH. Network-reachable, no auth needed, no user interaction. Confidentiality-only impact; no integrity or availability.
Affected versionsFastify >= 4.0.0 and < 5.12.2. This covers the entire v4 major line and v5 up to 5.12.1.
Fixed version5.12.2 (npm). v4.x has no announced backport — users on v4 must upgrade to v5.12.2 or apply proxy-level mitigations.
Exposure footprintFastify has ~8-10 million weekly npm downloads. Direct internet exposure is difficult to fingerprint via Shodan/Censys since Node.js apps rarely advertise framework identity in banners unless x-powered-by is left enabled (disabled by default since Fastify v4).
Disclosure date2026-09-04 via GHSA-p68q-wchp-6fh7.
Reporting researchersFound by vvvvvvvvvvitel and schecthellraiser606. Fix developed by mcollina (Fastify lead maintainer).
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.0/10)

The single most decisive factor keeping this at HIGH is that the attack is unauthenticated and network-reachable with low complexity — any internet-facing Fastify app in the affected version range with prefix-encapsulated auth is a candidate. The score is nudged from 7.5 to 7.0 because real-world impact requires the not-found handler to actually serve protected data, which is an application-specific precondition that narrows the exploitable population.

HIGH Vulnerability mechanics and affected version range
MEDIUM Real-world exploitability (depends on application architecture)
LOW Exploitation timeline (no PoC or in-the-wild activity yet)

Why this verdict

  • Unauthenticated network access with zero interaction: The CVSS vector AV:N/AC:L/PR:N/UI:N means any scanner or script kiddie can fire this at scale. No credentials, no phishing, no user click required. This alone anchors the floor at HIGH.
  • Global auth hooks explicitly do not mitigate: The advisory's warning that onRequest-level hooks are bypassed eliminates the most common compensating control developers would assume protects them. This widens the exploitable surface beyond what a casual reader might expect.
  • Application-specific data exposure precondition: The attack only yields value if the target not-found handler returns sensitive data. Generic 404 stubs — the default pattern in most Fastify apps — produce no exfiltrable content. This compounding friction prevents escalation to CRITICAL.
  • Role multiplier: Fastify is an application-tier web framework. (a) *Low-value role* — dev/test servers: bypass is inconsequential. (b) *Typical role* — production API server: auth bypass exposes API-scoped data, blast radius is tenant/service-level, not fleet-level. (c) *High-value role* — Fastify used as an API gateway or BFF fronting microservices: auth bypass could expose aggregated backend data, but the blast radius remains bounded to that gateway's scope, not domain/fleet/supply-chain. No canonical high-value-role floor (Fastify is not a DC, hypervisor, IdP, PAM, or kernel-mode agent). Floor remains HIGH based on network-reachable auth bypass.
  • No v4 backport available: The entire v4 major line (4.0.0 through end-of-life) is vulnerable with no patch. Organizations pinned to v4 must either upgrade to v5.12.2 (a major version jump) or rely on proxy-level mitigations, increasing real-world exposure duration.

Why not higher?

Escalation to CRITICAL would require fleet-scale or identity-scale blast radius. Fastify is an application framework, not infrastructure software — compromise of one Fastify service does not grant lateral movement to other hosts, domain takeover, or supply-chain pivot. The impact is confidentiality-only (I:N/A:N), and the exfiltrated data is bounded by what a single not-found handler returns. There is no code execution, no write primitive, and no persistence mechanism.

Why not lower?

Downgrading to MEDIUM would require either authenticated access or significant attack complexity. This CVE has neither — it is PR:N/AC:L, meaning unauthenticated attackers can exploit it trivially from the network. The affected version range spans four years of releases across two major versions with ~8-10M weekly downloads. Even with the data-exposure precondition, the population of exploitable apps is non-trivial.

05 · Compensating Control

What to do — in priority order.

  1. Reject malformed URLs at the reverse proxy or API gateway — Configure nginx (merge_slashes on, strict URI validation), HAProxy, AWS ALB, or Cloudflare WAF to reject or normalize requests with malformed path segments (double-encoding, null bytes, non-standard percent sequences) before they reach Node.js. Deploy within the noisgate mitigation SLA of 30 days. This is the highest-value compensating control because it neutralizes the attack vector regardless of application code.
  2. Upgrade to Fastify 5.12.2 — The definitive fix. Version 5.12.2 routes malformed URLs through onBadUrl/onMaxParamLength for early rejection and removes the shared not-found handler pointer. For v4 users, this requires a major version upgrade — plan and test within the noisgate remediation SLA of 180 days.
  3. Audit not-found handlers for data exposure — Review every setNotFoundHandler callback across your Fastify plugins. Ensure none return sensitive data (user context, internal routes, debug info, stack traces). Strip to a static 404 stub in production. This reduces impact to zero even if the routing bypass succeeds.
  4. Move authentication to an external gateway — If auth is enforced at a dedicated API gateway (Kong, AWS API Gateway, Apigee) or identity-aware proxy (OAuth2 Proxy, Pomerium) upstream of Fastify, the Fastify-level hook bypass becomes irrelevant. This is a strategic architectural control.
What doesn't work
  • Global onRequest hooks — The advisory explicitly states these do NOT mitigate the vulnerability. Do not rely on application-level global auth hooks as a compensating control.
  • Rate limiting alone — Rate limiting slows the attacker but does not prevent the auth bypass. A single well-crafted request is sufficient to exfiltrate data from the handler response.
  • Disabling x-powered-by — While good hygiene, this only removes one fingerprinting vector. Attackers can identify Fastify through error response formats, timing, or other behavioral signals.
06 · Verification

Crowdsourced verification payload.

Run this script on any host where a Fastify application is deployed, or from a CI pipeline that has access to the application's node_modules. No special privileges required — just read access to the package.json or node_modules/fastify/package.json. Example: bash check_cve_2026_76169.sh /opt/myapp

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash\n# check_cve_2026_76169.sh — Detect CVE-2026-76169 (Fastify auth bypass via malformed URL routing)\n# Usage: bash check_cve_2026_76169.sh <path-to-app-root>\n# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN\n\nset -euo pipefail\n\nAPP_DIR=\"${1:-.}\"\nPKG_JSON=\"${APP_DIR}/node_modules/fastify/package.json\"\n\nif [ ! -f \"$PKG_JSON\" ]; then\n  echo \"UNKNOWN — fastify not found in ${APP_DIR}/node_modules\"\n  exit 2\nfi\n\nVERSION=$(grep -o '\"version\": *\"[^\"]*\"' \"$PKG_JSON\" | head -1 | sed 's/.*\"\\([^\"]*\\)\"/\\1/')\n\nif [ -z \"$VERSION\" ]; then\n  echo \"UNKNOWN — could not parse fastify version from $PKG_JSON\"\n  exit 2\nfi\n\necho \"Detected fastify version: $VERSION\"\n\n# Parse semver components\nMAJOR=$(echo \"$VERSION\" | cut -d. -f1)\nMINOR=$(echo \"$VERSION\" | cut -d. -f2)\nPATCH=$(echo \"$VERSION\" | cut -d. -f3 | cut -d- -f1)\n\n# Vulnerable: >= 4.0.0 and < 5.12.2\nif [ \"$MAJOR\" -lt 4 ]; then\n  echo \"PATCHED — version $VERSION is below the affected range (< 4.0.0)\"\n  exit 0\nelif [ \"$MAJOR\" -eq 4 ]; then\n  echo \"VULNERABLE — version $VERSION is in the affected v4 range (no backport available)\"\n  exit 1\nelif [ \"$MAJOR\" -eq 5 ]; then\n  if [ \"$MINOR\" -lt 12 ]; then\n    echo \"VULNERABLE — version $VERSION is below the fix (5.12.2)\"\n    exit 1\n  elif [ \"$MINOR\" -eq 12 ] && [ \"$PATCH\" -lt 2 ]; then\n    echo \"VULNERABLE — version $VERSION is below the fix (5.12.2)\"\n    exit 1\n  else\n    echo \"PATCHED — version $VERSION includes the fix\"\n    exit 0\n  fi\nelif [ \"$MAJOR\" -gt 5 ]; then\n  echo \"PATCHED — version $VERSION is above the affected range\"\n  exit 0\nfi\n\necho \"UNKNOWN — could not determine vulnerability status\"\nexit 2
07 · Bottom Line

If you remember one thing.

TL;DR
CVE-2026-76169 is a same-day disclosure (2026-09-04) with no known exploitation or public PoC yet, but its unauthenticated, network-reachable attack vector demands prompt attention. Monday morning: inventory all Fastify deployments across your estate using npm ls fastify or your SBOM tooling and flag anything >= 4.0.0 and < 5.12.2. Per the noisgate mitigation SLA for HIGH, deploy compensating controls — specifically, malformed-URL rejection at your reverse proxy or API gateway — within 30 days. Simultaneously audit every setNotFoundHandler callback for data exposure and strip any sensitive content. Per the noisgate remediation SLA for HIGH, complete the upgrade to Fastify 5.12.2 within 180 days. For teams still on the v4 major line (no backport available), treat the major version upgrade as the remediation target and lean harder on the proxy-level mitigation in the interim. Monitor for PoC releases and EPSS movement over the next 2-4 weeks — if exploitation emerges, compress the mitigation timeline to hours.

Sources

  1. GitHub Security Advisory GHSA-p68q-wchp-6fh7
  2. Fastify npm package
  3. Fastify setNotFoundHandler documentation
  4. Snyk Fastify vulnerability database
  5. GitLab Advisory Database — Fastify CVE-2026-18504
  6. Fastify Routes documentation
  7. NVD CVSS v3.1 Specification
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.