← Back to Feed CACHED · 2026-09-17 06:53:27 · CACHE_KEY CVE-2026-92081
CVE-2026-92081 · CWE-248 · Disclosed 2026-09-16

fastify is a fast and low-overhead web framework for Node.js.

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

Like a fire sprinkler that floods the office — but only if you installed a rare ceiling tile and left the test valve open

CVE-2026-92081 affects the Fastify web framework for Node.js in all versions prior to 5.12.5. When a route registers a response trailer via reply.trailer() and the request arrives over HTTP/2, Fastify unconditionally injects a Transfer-Encoding: chunked header — a header that HTTP/2 explicitly forbids. Node.js throws while serializing the response, producing an uncaught exception (CWE-248) that kills the entire process. Every in-flight request is dropped. The crash is repeatable on every restart, meaning a single attacker can loop and keep the service down indefinitely.

The vendor's MEDIUM / 5.9 rating is directionally correct but slightly generous. The CVSS vector scores AC:H (high attack complexity), which acknowledges the narrow trigger conditions, but the score still overweights the unauthenticated-remote posture without discounting for two compounding prerequisites: the service must expose HTTP/2 *directly* to the Fastify process (most production deployments terminate HTTP/2 at a reverse proxy like Nginx, ALB, or Cloudflare), and at least one route must use the reply.trailer() API, which is uncommon in real codebases. When both conditions align the bug is trivially weaponizable — one crafted request crashes the server — but the population of deployments meeting both conditions is small. A reassessed score of 5.0 better reflects real-world exposure.

"HTTP/2 trailer crash is real but gated by two uncommon config choices"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a Fastify HTTP/2 endpoint

The attacker scans or fingerprints the target to confirm it runs Fastify and accepts direct HTTP/2 connections. This can be done passively via the server response header or ALPN negotiation. If the target sits behind a reverse proxy that terminates HTTP/2, this step fails — the proxy downgrades to HTTP/1.1 before traffic reaches Fastify.
Conditions required:
  • Target exposes Fastify directly on HTTP/2 (no TLS-terminating reverse proxy in front)
Where this breaks in practice:
  • Most production Fastify deployments sit behind Nginx, HAProxy, AWS ALB, or a CDN that terminates HTTP/2 and forwards HTTP/1.1
  • Default Fastify configuration uses HTTP/1.1; HTTP/2 requires explicit opt-in via http2: true
Detection/coverage: Standard HTTP/2 negotiation — no scanner signature needed; ALPN h2 in TLS handshake confirms HTTP/2 support
STEP 02

Locate a route using reply.trailer()

The attacker must hit a route that calls reply.trailer() to register at least one response trailer. This is a relatively niche Fastify API used primarily for streaming integrity checks (e.g., content checksums). Enumerating which routes use trailers may require fuzzing or knowledge of the application codebase.
Conditions required:
  • At least one route in the application uses reply.trailer()
Where this breaks in practice:
  • reply.trailer() is an uncommon API — most Fastify apps never call it
  • Attacker has no way to remotely enumerate which routes use trailers without sending requests and observing responses
STEP 03

Send a single HTTP/2 request to the trailer route

The attacker sends a standard HTTP/2 request to the identified route. Fastify sets Transfer-Encoding: chunked on the response, Node.js rejects it as an illegal HTTP/2 header, and the process throws an uncaught exception. The entire Node.js process terminates. No special payload is needed — any valid HTTP/2 request to the route triggers the crash.
Conditions required:
  • Network reachability to the Fastify HTTP/2 port
Where this breaks in practice:
  • Process managers (PM2, systemd, Kubernetes) will auto-restart the process, limiting sustained impact
  • Rate limiting or connection limits at the load balancer may slow repeated crashes
Detection/coverage: Application crash logs will show ERR_HTTP2_INVALID_HEADER_VALUE or similar Node.js uncaught exception; crash-loop alerts in Kubernetes or PM2 will fire
STEP 04

Loop to sustain denial of service

The attacker repeats the request on every process restart to maintain the outage. Each crash drops all in-flight requests for all users of that process. In a containerized environment, the crash loop may trigger backoff delays, amplifying downtime per crash. The attacker needs only one request per restart cycle.
Conditions required:
  • Continued network access to the target
Where this breaks in practice:
  • Kubernetes CrashLoopBackOff increases restart intervals, giving defenders time to react
  • WAF or IP-based rate limiting can block the attacker's source after initial crashes
  • Health check failures will remove the pod from the service mesh, limiting blast radius to that replica
Detection/coverage: Crash-loop monitoring, abnormal restart counts, and HTTP/2 connection metrics will surface the attack pattern quickly
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNo known exploitation. Not listed on CISA KEV. No campaigns or threat actor usage reported as of 2026-09-17.
Proof-of-conceptNo public PoC found. Exploitation is trivial (single HTTP/2 request to a trailer route), so a weaponized script could be written in minutes, but none has surfaced on GitHub or exploit databases yet.
EPSS0.00395 (0.4% probability of exploitation in next 30 days) — bottom quartile, consistent with a niche DoS bug.
KEV statusNot listed. No CISA KEV entry as of 2026-09-17.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H — Network-reachable, high complexity, no privileges or user interaction, availability-only impact. The AC:H reflects the dual prerequisite of HTTP/2 + trailer usage.
Affected versionsFastify < 5.12.5 (all 5.x releases through 5.12.4; also affects 4.x if still in use, though 4.x is EOL).
Fixed versionFastify 5.12.5 (released 2026-09-16).
Scanning / exposureFastify has ~8.5 million weekly npm downloads. However, direct HTTP/2 exposure to Fastify (without a terminating proxy) is a small fraction of that install base. No Shodan/Censys dork reliably identifies vulnerable instances.
Disclosure date2026-09-16 via GitHub Security Advisory GHSA-4mh8-r7rc-xpvc.
ReporterDisclosed via OpenJS Foundation security process. Specific researcher not publicly credited in the advisory.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (5.0/10)

The single most decisive factor is the compound prerequisite narrowing: exploitation requires both direct HTTP/2 termination at the Fastify process (uncommon — most deployments proxy HTTP/2 upstream) *and* use of the niche reply.trailer() API, drastically shrinking the reachable population. The impact ceiling is availability-only (process crash), with no path to code execution, data exfiltration, or lateral movement.

HIGH Vulnerability mechanics and trigger conditions
HIGH Affected and fixed version range
MEDIUM Fraction of Fastify deployments directly exposing HTTP/2
LOW Presence of undisclosed PoC or private exploitation

Why this verdict

  • Dual prerequisite gate: The bug only fires when HTTP/2 reaches Fastify directly *and* a route uses reply.trailer(). Each condition independently eliminates a large fraction of the install base; combined, the reachable population is very small.
  • Availability-only impact: The worst outcome is a process crash (DoS). There is no memory corruption, no code execution, no data leak. The CVSS vector confirms C:N/I:N/A:H.
  • Auto-restart dampening: Modern deployments run Fastify under PM2, systemd, or Kubernetes, all of which auto-restart crashed processes. Sustained DoS requires the attacker to maintain a loop, which is detectable and blockable.
  • Role multiplier: Fastify is an application-tier web framework. It is *not* an identity provider, hypervisor, domain controller, kernel agent, or network edge appliance. (a) *Low-value role (dev/sandbox):* chain succeeds if both conditions met — blast radius is one dev process, negligible. (b) *Typical role (API microservice behind a load balancer):* HTTP/2 is almost always terminated at the LB/proxy, so the chain usually fails; if it succeeds, blast radius is one replica pod, mitigated by auto-restart. (c) *High-value role (API gateway):* conceivable but uncommon; even here, the impact is DoS of one process, not domain/fleet/supply-chain compromise. No high-value role scenario reaches the blast radius floor for a HIGH verdict.
  • No exploitation pressure: EPSS is 0.4%, no KEV listing, no public PoC, no observed campaigns. The bug has been public for one day with zero weaponization signals.

Why not higher?

Upgrading to HIGH would require either a path to code execution, a broader reachable population, or active exploitation — none of which exist. The dual prerequisite (HTTP/2 + trailer API) compresses the exposed population well below 10% of the Fastify install base, and the impact ceiling is a recoverable process crash with no confidentiality or integrity consequences.

Why not lower?

Dropping to LOW would undercount the risk for the narrow set of deployments that *do* expose HTTP/2 directly and use trailers. In those environments, the crash is trivially repeatable, unauthenticated, and can sustain a service outage. The 8.5M weekly download footprint means even a small percentage translates to a non-trivial absolute number of vulnerable services.

05 · Compensating Control

What to do — in priority order.

  1. Remove reply.trailer() calls from HTTP/2 routes — The vendor-documented workaround. Audit your codebase for reply.trailer() usage and remove or conditionally disable it when the connection is HTTP/2. This eliminates the trigger entirely. Apply immediately if you cannot upgrade within the 365-day noisgate remediation SLA.
  2. Terminate HTTP/2 at the reverse proxy — Configure Nginx, HAProxy, AWS ALB, or Cloudflare to terminate HTTP/2 and forward HTTP/1.1 to Fastify. This prevents the illegal header from being generated. Most production deployments already do this — verify yours does.
  3. Enable crash-loop alerting — Ensure your process manager (PM2, systemd, Kubernetes) alerts on repeated restarts. Set a CrashLoopBackOff threshold to page on-call if the process crashes more than 3 times in 5 minutes, so you can respond to active exploitation quickly.
  4. Rate-limit HTTP/2 connections at the edge — Apply per-IP connection rate limits at your load balancer or WAF to slow an attacker's ability to repeatedly crash the process on every restart.
What doesn't work
  • WAF payload inspection — the crash is triggered by a normal, well-formed HTTP/2 request with no malicious payload. There is no signature to match; the bug is in how Fastify constructs the *response*, not in the request content.
  • Node.js process.on('uncaughtException') handler — while this can catch the throw and prevent process exit, it leaves the HTTP/2 session in an undefined state. The Fastify team does not recommend this as a mitigation; it may cause memory leaks or hung connections.
06 · Verification

Crowdsourced verification payload.

Run this on any host with node and npm installed to check whether the installed fastify version is vulnerable. No special privileges needed. Example: bash check_cve_2026_92081.sh /path/to/your/project

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-92081 - Fastify HTTP/2 trailer crash check
# Usage: bash check_cve_2026_92081.sh [project_dir]
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

PROJECT_DIR="${1:-.}"

if [ ! -d "$PROJECT_DIR/node_modules/fastify" ]; then
  echo "UNKNOWN - fastify not found in $PROJECT_DIR/node_modules"
  exit 2
fi

VERSION=$(node -e "try { console.log(require('$PROJECT_DIR/node_modules/fastify/package.json').version) } catch(e) { console.log('error') }")

if [ "$VERSION" = "error" ]; then
  echo "UNKNOWN - could not read fastify version"
  exit 2
fi

echo "Detected fastify version: $VERSION"

# Compare versions - 5.12.5 is the fix
FIXED="5.12.5"

version_gte() {
  [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ]
}

if version_gte "$VERSION" "$FIXED"; then
  echo "PATCHED - fastify $VERSION >= $FIXED"
  exit 0
else
  echo "VULNERABLE - fastify $VERSION < $FIXED (CVE-2026-92081)"
  echo "Upgrade: npm install fastify@^5.12.5"
  exit 1
fi
07 · Bottom Line

If you remember one thing.

TL;DR
This is a MEDIUM severity DoS bug gated by two uncommon prerequisites (direct HTTP/2 + reply.trailer() usage). There is no noisgate mitigation SLA for MEDIUM — go straight to the 365-day noisgate remediation SLA. Practically: upgrade to Fastify 5.12.5 in your next regular dependency update cycle. If you know you have HTTP/2 routes using reply.trailer(), either remove the trailer calls or confirm HTTP/2 is terminated at your reverse proxy — do that this week as a precaution. There is no active exploitation and no public PoC, so this does not warrant emergency patching or a weekend deploy. Put it in your next sprint's dependency bump and move on.

Sources

  1. OpenCVE - CVE-2026-92081 Details
  2. Strix AI - CVE-2026-92081 Advisory
  3. GitHub Advisory GHSA-4mh8-r7rc-xpvc
  4. Fastify Issue #7030 - reply.trailer() breaks on bodyless responses
  5. Fastify Reply Documentation (latest)
  6. npm trends - Fastify download statistics
  7. CVE Details - Fastify Security Vulnerabilities
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.