← Back to Feed CACHED · 2026-08-13 12:28:40 · CACHE_KEY CVE-2026-19484
CVE-2026-19484 · CWE-835 · Disclosed 2026-08-13

@fastify/busboy is a multipart form-data parser.

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

A single misaligned byte in the boundary lookup table turns your API server's event loop into a hamster wheel that never stops

CVE-2026-19484 is an infinite-loop denial-of-service in @fastify/busboy versions 3.1.0 through 3.2.0. The multipart boundary-search algorithm uses a lookup table internally. When an attacker sends a multipart request with a boundary of exactly 252 bytes, the search needle becomes 256 bytes, causing a table index to wrap to zero. This traps the parser in a CPU-bound loop on the Node.js event loop — a single malicious request is enough to hang the entire process. No authentication is required; the parser runs before any application middleware. Any service accepting multipart/form-data via @fastify/multipart, Fastify, or direct @fastify/busboy usage on the affected versions is vulnerable. The fix is in version 3.2.1, released August 12, 2026.

The vendor's HIGH / 7.5 rating is fair but slightly generous. The CVSS vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) correctly reflects unauthenticated network-reachable DoS. However, two factors temper real-world risk: (1) the affected version window is narrow — only two minor versions (3.1.0–3.2.0) are vulnerable, so a large portion of the ~22 million weekly download base still on 2.x or earlier 3.0.x is unaffected; and (2) the impact ceiling is availability loss, not code execution or data breach. We downgrade fractionally to 7.0 to reflect the constrained blast radius while respecting the trivial exploitability.

"One 252-byte boundary hangs an entire Node.js server — patch the narrow window now."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a target accepting multipart/form-data

The attacker scans for Node.js-based APIs or web applications that accept file uploads or form submissions. Any endpoint parsed by @fastify/busboy ≥3.1.0 qualifies. Shodan/FOFA Server: fastify headers or framework fingerprinting narrows the search.
Conditions required:
  • Target runs @fastify/busboy 3.1.0–3.2.0
  • Target endpoint accepts multipart/form-data Content-Type
Where this breaks in practice:
  • Many deployments still run 2.x or 3.0.x — only 3.1.0+ is affected
  • Some reverse proxies enforce RFC 2046 boundary length limits (≤70 chars), which would reject the 252-byte boundary before it reaches the app
Detection/coverage: WAF rules checking boundary length; Fastify access logs showing hung connections
STEP 02

Craft a multipart request with a 252-byte boundary

The attacker constructs an HTTP POST with Content-Type: multipart/form-data; boundary=<252 chars>. This is trivial — no special tooling beyond curl is needed. The 252-byte boundary plus the -- prefix and CRLF creates a 256-byte search needle internally. No weaponized tool required; a one-liner suffices: curl -X POST -H 'Content-Type: multipart/form-data; boundary=AAAA...252 chars' --data-binary $'--AAAA...\r\n' target/upload.
Conditions required:
  • Network reachability to the target endpoint
Where this breaks in practice:
  • Rate limiting or connection timeouts at the load balancer may cap the damage window
  • Some CDNs (Cloudflare, AWS ALB) may normalize or reject oversized boundary values
Detection/coverage: IDS/WAF signature matching boundary length >70 bytes in Content-Type header
STEP 03

Node.js event loop hangs indefinitely

The parser enters a tight CPU-bound loop because the lookup table entry wraps to zero. Since Node.js is single-threaded, the entire process becomes unresponsive. No further requests are served. If the application runs in cluster mode with N workers, the attacker needs N concurrent requests to take down the full service.
Conditions required:
  • Request reaches the busboy parser (pre-middleware, pre-auth)
Where this breaks in practice:
  • Cluster mode (pm2, node cluster) requires one poisoned request per worker
  • Process managers with health checks will restart hung workers, limiting downtime to seconds
  • Kubernetes liveness probes will restart the pod
Detection/coverage: Node.js process CPU spike to 100% with zero request throughput; APM tools (Datadog, New Relic) flag event-loop lag >10s
STEP 04

Service unavailability achieved

With all workers hung, the application returns 502/503 from the load balancer. The attacker sustains the outage by re-sending the payload whenever health checks restart workers. This is a classic asymmetric DoS — a few KB of request data pins an entire service.
Conditions required:
  • Attacker can sustain a low rate of requests (1 per worker per restart cycle)
Where this breaks in practice:
  • IP-based rate limiting or connection limits at the edge mitigate sustained attacks
  • Automated scaling (HPA in k8s) can outpace a single-source attacker
Detection/coverage: Load balancer 502 rate spike; upstream health check failure alerts
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo known exploitation as of 2026-08-13. Not listed on CISA KEV. Disclosed same day as patch — exploitation window just opened.
Proof of ConceptThe GHSA advisory (GHSA-xjh9-v7x6-24jw) includes the trigger condition in its description. A working PoC is trivial — a single curl command with a 252-char boundary. No public exploit repo found yet, but weaponization is minutes away.
EPSS ScoreNot yet scored (CVE disclosed 2026-08-13). Expected to be moderate (~0.15–0.30) given unauthenticated network DoS with trivial complexity.
KEV StatusNot listed. No federal directive to patch.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — unauthenticated remote DoS, no scope change, availability-only impact. The vector is accurate.
Affected Versions@fastify/busboy ≥3.1.0, <3.2.1. Versions 1.x and 2.x are not affected. Version 3.0.x is not affected.
Fixed Version3.2.1 (released August 12, 2026). Drop-in replacement — no breaking API changes.
Exposure / Install Base~22 million weekly npm downloads. @fastify/busboy is a dependency of undici and is used indirectly by Node.js core's built-in fetch(). However, the server-side multipart parsing path (where this bug lives) is only exercised by applications explicitly parsing incoming multipart/form-data, not by client-side fetch() consumers.
Disclosure Date2026-08-13 (coordinated disclosure, patch available same day)
ReporterMatteo Collina (mcollina), Fastify core maintainer. Self-reported and self-patched.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.0/10)

The single most decisive factor keeping this at HIGH is the trivially exploitable unauthenticated CPU-hang with zero-click, single-request lethality against any Node.js process accepting multipart uploads. The narrow affected version window (3.1.0–3.2.0 only) and availability-only impact ceiling prevent escalation to CRITICAL.

HIGH Vulnerability mechanics and affected version range
HIGH Exploitability (trivial, PoC derivable from advisory text)
MEDIUM Exposed population share on 3.1.x/3.2.0 vs older versions

Why this verdict

  • Unauthenticated, zero-click DoS — a single crafted HTTP request hangs the entire Node.js event loop. No credentials, no user interaction, no chaining required. This anchors the score at HIGH.
  • Narrow affected version range — only 3.1.0 through 3.2.0 are vulnerable. The 2.x line and 3.0.x are unaffected, which materially reduces the exposed population from the ~22M weekly download figure. This is the primary downward pressure from the vendor's 7.5.
  • Availability-only impact ceiling — there is no path from this bug to code execution, data exfiltration, or privilege escalation. The worst outcome is service downtime, which bounds the maximum severity.
  • Role multiplier: @fastify/busboy is a userland npm library consumed by Node.js web applications. Typical deployment roles are API servers and web backends (role b). It does not run on domain controllers, hypervisors, identity providers, or kernel-mode agents. In a high-value role scenario (e.g., a Node.js API gateway fronting critical services), successful exploitation causes service unavailability — significant but not fleet compromise, domain takeover, or supply-chain pivot. The blast radius is host/service-level, not domain/fleet-level, so the floor remains HIGH (not CRITICAL).
  • Trivial weaponization — the advisory description is essentially the PoC. Any attacker who can read the GHSA can reproduce it in under 5 minutes with curl. This prevents any downgrade below HIGH.

Why not higher?

This is not CRITICAL because the impact is limited to availability — there is no code execution, no data breach, no lateral movement. The affected component is a userland npm library, not a hypervisor, identity provider, or kernel-mode agent. The narrow version window (two minor releases) further limits the reachable population. DoS-only vulnerabilities, even trivially exploitable ones, do not meet the CRITICAL floor unless they affect safety-critical OT/ICS systems or enable cascading infrastructure failure.

Why not lower?

This cannot be MEDIUM because the exploitation is completely unauthenticated, requires zero user interaction, has trivial attack complexity, and the PoC is effectively public. A single small HTTP request can take down an entire Node.js process. The asymmetric cost (bytes in vs. full service hang) and the lack of any prerequisite compromise step mean there is no meaningful friction to justify a downgrade to MEDIUM.

05 · Compensating Control

What to do — in priority order.

  1. Enforce RFC 2046 boundary length at the reverse proxy — RFC 2046 limits multipart boundaries to 70 characters. Configure your reverse proxy (nginx, HAProxy, Envoy, Cloudflare WAF) to reject requests with boundary= values exceeding 70 bytes. This neutralizes the attack vector entirely. Deploy within the noisgate HIGH mitigation SLA of 30 days, though given trivial exploitability, aim for days not weeks.
  2. Upgrade @fastify/busboy to 3.2.1 — Drop-in fix with no breaking changes. Run npm update @fastify/busboy or pin ^3.2.1 in package.json. This is the definitive remediation. Target deployment within the noisgate HIGH remediation SLA of 180 days, but realistically push this in your next release cycle.
  3. Run Node.js in cluster mode with health checks — Use node:cluster, PM2, or Kubernetes liveness probes with tight thresholds (e.g., 5-second event loop lag). This limits the blast radius of a single hung worker and auto-restarts affected processes. Not a fix — just damage containment.
  4. Rate-limit multipart endpoints by source IP — Configure your WAF or API gateway to rate-limit POST requests to multipart-accepting endpoints. This raises the attacker's cost for sustained DoS but does not prevent single-request hangs.
What doesn't work
  • Generic request-size limits (e.g., client_max_body_size) — the malicious payload is tiny (a few hundred bytes in the Content-Type header). Body size limits won't catch it.
  • Application-layer auth middleware — the busboy parser runs *before* your auth middleware in the Fastify request lifecycle. Adding authentication to the endpoint does not prevent the parser from triggering on the raw request.
  • Node.js --max-old-space-size memory limits — this is a CPU-bound loop, not a memory exhaustion. Memory limits are irrelevant.
06 · Verification

Crowdsourced verification payload.

Run this on any host with node and npm installed to check whether the installed @fastify/busboy version is in the vulnerable range. No special privileges required. Example: bash check_busboy_cve_2026_19484.sh /path/to/your/project

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_busboy_cve_2026_19484.sh
# Checks whether @fastify/busboy is in the vulnerable range 3.1.0–3.2.0
# Usage: bash check_busboy_cve_2026_19484.sh [project_dir]
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

PROJECT_DIR="${1:-.}"

if [ ! -d "$PROJECT_DIR/node_modules" ]; then
  echo "UNKNOWN — no node_modules found in $PROJECT_DIR. Run npm install first."
  exit 2
fi

PKG_JSON="$PROJECT_DIR/node_modules/@fastify/busboy/package.json"

if [ ! -f "$PKG_JSON" ]; then
  echo "UNKNOWN — @fastify/busboy not found in $PROJECT_DIR/node_modules."
  exit 2
fi

VERSION=$(node -e "console.log(require('$PKG_JSON').version)" 2>/dev/null)

if [ -z "$VERSION" ]; then
  echo "UNKNOWN — could not read version from $PKG_JSON."
  exit 2
fi

# Parse semver
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)

# Vulnerable: >=3.1.0, <3.2.1
if [ "$MAJOR" -eq 3 ]; then
  if [ "$MINOR" -eq 1 ]; then
    echo "VULNERABLE — @fastify/busboy $VERSION is in the affected range (3.1.0–3.2.0). Upgrade to 3.2.1."
    exit 1
  elif [ "$MINOR" -eq 2 ] && [ "$PATCH" -eq 0 ]; then
    echo "VULNERABLE — @fastify/busboy $VERSION is in the affected range (3.1.0–3.2.0). Upgrade to 3.2.1."
    exit 1
  fi
fi

echo "PATCHED — @fastify/busboy $VERSION is not in the vulnerable range."
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Inventory all Node.js services for @fastify/busboy 3.1.0–3.2.0 this week. The fix is a one-line version bump to 3.2.1 — no breaking changes, no migration. For services you can't redeploy immediately, enforce the RFC 2046 boundary length limit (≤70 chars) at your reverse proxy as a compensating control. Per the noisgate mitigation SLA for HIGH severity, have the compensating control deployed within 30 days; per the noisgate remediation SLA, complete the actual package upgrade across all services within 180 days. Given that exploitation is trivial and the patch is a drop-in, there's no reason to ride the full SLA window — target the upgrade in your next sprint. No active exploitation has been observed yet, but the PoC is derivable from the advisory text in minutes, so the clock is ticking.

Sources

  1. GHSA-xjh9-v7x6-24jw — @fastify/busboy DoS via oversized boundary
  2. @fastify/busboy v3.2.1 release (security fix)
  3. @fastify/busboy npm package
  4. CWE-835: Loop with Unreachable Exit Condition
  5. FIRST EPSS — Exploit Prediction Scoring System
  6. CISA Known Exploited Vulnerabilities Catalog
  7. @fastify/busboy GitHub repository
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.