← Back to Feed CACHED · 2026-08-29 13:26:58 · CACHE_KEY CVE-2026-77037
CVE-2026-77037 · CWE-400 · Disclosed 2026-08-28

multer is a middleware for handling multipart/form-data in Node.js.

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

Like a faucet that nobody remembers to shut off — each aborted upload drips one file descriptor until the sink overflows

CVE-2026-77037 affects only multer 2.2.0 using the built-in diskStorage engine. When a multipart upload is aborted or truncated mid-stream, multer dutifully calls fs.unlink to remove the partial file — but never calls .close() on the write stream's underlying file descriptor. The deleted inode stays open, pinning disk blocks and consuming a slot in the process's FD table. An unauthenticated attacker who can reach any upload route can repeat this hundreds of times per second, eventually exhausting the ulimit -n ceiling (typically 1024–65536) and starving the Node.js process of the ability to open sockets, files, or pipes. The result is a denial-of-service of the affected Express/Koa/Fastify application. There is no confidentiality or integrity impact — no code execution, no data exfiltration, no privilege escalation.

The vendor's HIGH / 7.5 score is mechanically correct per the CVSS vector (unauthenticated, network, low complexity, high availability impact) but overstates real-world urgency. The affected version window is a single semver release (2.2.0 only), the prerequisite is that the app uses diskStorage on an externally reachable upload route, and the worst-case outcome is a process restart. In an ecosystem where multer sees 20M+ weekly npm downloads, the fraction actually running 2.2.0 with disk storage exposed externally is small. A MEDIUM rating better reflects the operational risk.

"Single-version FD leak DoS in multer disk storage; narrow blast, no data risk."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Identify an upload endpoint

The attacker locates an HTTP route that accepts multipart/form-data and is backed by multer with diskStorage. This is typically a file-upload form, avatar endpoint, or document-ingest API. No authentication is required if the route is public, but many upload routes sit behind auth or CSRF tokens.
Conditions required:
  • Target runs multer 2.2.0
  • Route uses built-in diskStorage engine
  • Route is network-reachable to attacker
Where this breaks in practice:
  • Many upload routes require authentication or a valid session
  • Rate limiters, WAFs, or reverse-proxy request-size caps may throttle repeated POSTs
  • Apps using memoryStorage or a custom storage engine (S3, GCS) are unaffected
Detection/coverage: WAF logs will show a spike in aborted multipart POSTs to the upload path. No CVE-specific scanner signature is widely available yet.
STEP 02

Send aborted multipart uploads in a loop

The attacker opens a TCP connection, begins a valid multipart/form-data POST with a file part, then resets the connection (RST or simply closes the socket) before the upload completes. Each aborted request triggers the bug path: multer deletes the temp file but leaves the write stream's FD open. A simple curl one-liner or Python script can automate this at high volume.
Conditions required:
  • Ability to send and abort HTTP requests rapidly
Where this breaks in practice:
  • Reverse proxies (nginx, HAProxy) may buffer the upload and not propagate the abort to Node
  • Connection rate limits or SYN cookies on the load balancer slow the attack
  • Container orchestrators restart crashed pods automatically, limiting sustained impact
Detection/coverage: Process-level monitoring (lsof -p <pid> | grep deleted) will show a growing count of deleted-but-open FDs. Node.js process metrics (open handles count) will trend upward.
STEP 03

Exhaust file descriptors → DoS

Once the process hits its ulimit -n ceiling, every subsequent open(), socket(), or accept() call fails with EMFILE. The Node.js event loop can no longer accept new connections or write logs. The application becomes fully unresponsive until the process is restarted (which closes all leaked FDs). In a single-process deployment without a process manager, this is a sustained outage; in a clustered or Kubernetes deployment the pod is restarted within seconds.
Conditions required:
  • Sufficient aborted requests to exhaust the FD limit (typically 1024–65536 iterations)
Where this breaks in practice:
  • Kubernetes liveness probes or PM2/forever will restart the process, limiting downtime to seconds
  • A high ulimit -n (e.g., 65536) means the attacker needs tens of thousands of aborted uploads
  • Each leaked FD also holds disk blocks, but modern SSDs and large volumes make disk exhaustion unlikely before FD exhaustion
Detection/coverage: EMFILE errors in application logs. Prometheus/node_exporter process_open_fds metric crossing threshold. Health-check failures triggering alerts.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo evidence. Not listed in CISA KEV. No reports of active exploitation as of 2026-08-29.
Proof-of-ConceptNot publicly available. No named PoC repos found on GitHub. The attack is trivially reproducible with curl --max-time 0.1 -F [email protected] <url> in a loop, so weaponization is straightforward.
EPSS ScoreNot yet scored — CVE was published 2026-08-28, EPSS lag is typical for newly disclosed CVEs. Expected to be low given DoS-only impact.
KEV StatusNot listed. DoS-only CVEs rarely enter KEV.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — Network-accessible, no auth, no user interaction, availability-only impact. Scope unchanged.
Affected Versionsmulter 2.2.0 only (semver exact match). Versions < 2.2.0 and ≥ 2.3.0 are not affected.
Fixed Versionmulter 2.3.0 — fix closes the destination write stream on abnormal source termination and defers unlink until after stream close.
Scanning / Exposuremulter has ~20M weekly npm downloads, but the affected version 2.2.0 is a single release. Actual exposure is a fraction of that install base. No Shodan/GreyNoise/Censys signatures applicable (this is an application-layer library, not a listening service).
Disclosure TimelineReserved 2026-08-20, published 2026-08-28. Assigned by OpenJS Foundation.
Reporter / CreditsReported via OpenJS Foundation security process. Advisory GHSA-qfvm-cv95-jqjf.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.5/10)

The single most decisive factor is the extremely narrow affected version range: only multer 2.2.0 is vulnerable, making the reachable population a small fraction of multer's 20M-weekly-download install base. Combined with DoS-only impact (no code execution, no data access) and automatic recovery via process restart, the operational risk does not warrant a HIGH classification.

HIGH Vulnerability mechanics and affected version range
HIGH DoS-only impact classification (no RCE/data path)
MEDIUM Absence of in-the-wild exploitation (negative evidence, CVE is < 48 hours old)

Why this verdict

  • Single-version scope: Only multer 2.2.0 is affected — not a range, not 'all versions before X'. Any team that installed multer before 2.2.0 or has already moved to 2.3.0 is unaffected, drastically shrinking the exposed population.
  • DoS-only, self-healing blast radius: The worst outcome is an unresponsive Node.js process. A kill -9 or pod restart clears all leaked FDs instantly. No data is exposed, no code is executed, no persistence is gained. In Kubernetes or PM2-managed deployments the outage window is seconds.
  • Friction from upload-route prerequisites: The attacker must reach a route that uses diskStorage specifically. Apps using memoryStorage, S3 storage engines, or routes behind authentication are not exploitable. Rate limiters and reverse-proxy buffering further narrow the practical attack surface.
  • Role multiplier: Multer is an application-tier middleware — it does not run on domain controllers, hypervisors, identity providers, or backup servers. Even a successful DoS affects a single application process, not fleet-wide infrastructure. The blast radius is *host* at most (single process, really), never *domain* or *fleet*. No high-value-role floor applies.

Why not higher?

There is no code execution, no data exfiltration, and no privilege escalation path. The impact ceiling is availability loss of a single Node.js process, recoverable by restart. The affected component (a file-upload middleware) does not occupy a high-value infrastructure role where DoS translates to cascading failures. Upgrading to HIGH would require either active exploitation evidence or a broader blast radius.

Why not lower?

The vulnerability is unauthenticated and network-reachable with zero user interaction — the CVSS access vector is legitimately easy. Weaponization is trivial (a shell loop with curl), so any exposed instance can be targeted by an unsophisticated attacker. While the version window is narrow, organizations that *are* on 2.2.0 face a real availability risk until they patch. Dropping to LOW would understate the ease of exploitation for affected instances.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade multer to 2.3.0 immediately — This is a one-line npm install [email protected] change. Given the MEDIUM verdict, target remediation within the noisgate 365-day remediation window, but the fix is trivial enough to deploy this sprint.
  2. Set process-level file descriptor limits — Ensure ulimit -n or the container's nofile rlimit is set high (e.g., 65536+). This does not fix the leak but raises the threshold an attacker must cross, buying time. Deploy as general hardening.
  3. Rate-limit upload endpoints — Apply per-IP rate limiting on multipart upload routes at the reverse proxy or WAF layer (e.g., nginx limit_req at 10 req/s per IP). This slows FD exhaustion to an impractical pace.
  4. Enable health-check-driven restarts — Ensure Kubernetes liveness probes, PM2 max_restarts, or systemd Restart=always are configured for the Node.js process. A restart clears all leaked FDs and restores service in seconds.
  5. Switch to memoryStorage or cloud storage engine — If the application does not require disk-backed temp files, switching to multer.memoryStorage() or an S3/GCS storage engine sidesteps the vulnerable code path entirely.
What doesn't work
  • WAF signature blocking — there is no malicious payload to match; the attack uses a normal multipart POST that is simply aborted early. WAF content inspection cannot distinguish this from a user with a flaky connection.
  • Network-level DDoS mitigation (e.g., Cloudflare, AWS Shield) — the attack is low-bandwidth (small partial uploads) and does not trigger volumetric thresholds. It looks like normal upload traffic at the network layer.
06 · Verification

Crowdsourced verification payload.

Run this on any host where a Node.js application with multer is deployed, or from a CI pipeline that has access to the project's node_modules. Requires read access to node_modules/multer/package.json. No elevated privileges needed. Example: bash check_cve_2026_77037.sh /app where /app is the project root.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_77037.sh — Detect CVE-2026-77037 (multer FD leak DoS)
# Usage: bash check_cve_2026_77037.sh <project_root>
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

PROJECT_ROOT="${1:-.}"
PKG="${PROJECT_ROOT}/node_modules/multer/package.json"

if [ ! -f "$PKG" ]; then
  echo "UNKNOWN — multer not found in ${PROJECT_ROOT}/node_modules"
  exit 2
fi

VERSION=$(grep '"version"' "$PKG" | head -1 | sed 's/.*"version": *"\([^"]*\)".*/\1/')

if [ -z "$VERSION" ]; then
  echo "UNKNOWN — could not parse multer version from $PKG"
  exit 2
fi

echo "Detected multer version: $VERSION"

if [ "$VERSION" = "2.2.0" ]; then
  echo "VULNERABLE — multer $VERSION is affected by CVE-2026-77037 (FD leak DoS)"
  echo "Remediation: npm install [email protected]"
  exit 1
else
  echo "PATCHED — multer $VERSION is not affected by CVE-2026-77037"
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
CVE-2026-77037 is a file-descriptor-leak DoS in multer 2.2.0 only, downgraded from vendor HIGH (7.5) to noisgate MEDIUM (5.5). If you're running multer 2.2.0 in production, run npm install [email protected] — the fix is a clean semver-minor bump with no breaking changes. There is no noisgate mitigation SLA for MEDIUM — go straight to the 365-day noisgate remediation SLA. That said, this is a one-command fix; there is no reason to wait. If you cannot patch immediately, rate-limit your upload endpoints and ensure your process manager auto-restarts on health-check failure. If you are on any other multer version (< 2.2.0 or ≥ 2.3.0), you are not affected — document and move on.

Sources

  1. THREATINT CVE-2026-77037 Detail
  2. GitHub Advisory GHSA-qfvm-cv95-jqjf
  3. CISA Weekly Vulnerability Summary (Aug 17 2026)
  4. Snyk multer Package Intelligence
  5. npm multer Package
  6. GBHackers — Critical Multer Vulnerability Coverage
  7. IBM Security Bulletin — multer Vulnerability
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.