← Back to Feed CACHED · 2026-08-29 13:32:11 · CACHE_KEY CVE-2026-77078
CVE-2026-77078 · CWE-248 · 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 handing a balloon pump a number so big the balloon pops before you even squeeze

CVE-2026-77078 is a denial-of-service flaw in multer, the dominant Express.js middleware for multipart/form-data file uploads (~20 million weekly npm downloads). A single HTTP POST containing two specially crafted text field names triggers an uncaught RangeError: Invalid array length inside the append-field dependency. The first field name uses a massive numeric array index (e.g., field[4294967295]) to allocate a maximum-length sparse array; the second field pushes one element past that ceiling. Because multer never wraps the append-field call in a try/catch, the exception propagates uncaught and terminates the Node.js process. All versions before 2.3.0 are affected — that includes every 1.x release and every 2.x release through 2.2.x.

The vendor's HIGH / 7.5 score is fair and accurate. The CVSS vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) correctly reflects that exploitation is unauthenticated, remote, trivially low-complexity, and causes complete availability loss of the affected process. The only mitigating factor the score doesn't capture is that most production Node.js deployments use process managers (PM2, cluster mode, systemd auto-restart) that recover the worker within seconds — so sustained outage requires a loop of requests, not just one. That operational nuance is real but doesn't justify a downgrade: the attacker payload is a single small HTTP request, the package is ubiquitous, and repeated crashes still cause visible service degradation, error spikes, and potential data loss for in-flight uploads.

"Trivial unauthenticated DoS on 20M-download/week middleware — one HTTP request kills the process"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a multer-backed upload endpoint

The attacker locates any Express route using multer() middleware — typically /upload, /api/files, or any endpoint accepting multipart/form-data. No authentication is required; these endpoints are frequently public-facing for user avatars, document uploads, or form submissions. Scanning tools like httpx or nuclei with content-type probing can enumerate candidates at scale.
Conditions required:
  • Target application uses multer < 2.3.0
  • Endpoint accepts multipart/form-data POSTs
Where this breaks in practice:
  • Endpoint may be behind a WAF that limits field name length
  • Endpoint may require a valid session/token for the route itself
Detection/coverage: SCA scanners (Snyk, npm audit, Dependabot) flag the vulnerable multer version. WAF rules inspecting field name length or array index patterns can detect anomalous payloads.
STEP 02

Send first field with oversized array index

The attacker crafts a multipart POST where the first text field has a name like x[4294967295]. When multer passes this to append-field, the library interprets the bracket notation and calls new Array(4294967295), allocating a maximum-length sparse array in the V8 heap. This alone doesn't crash the process — the array is sparse and uses little actual memory — but it sets the trap.
Conditions required:
  • append-field parses bracket notation in field names (default behavior)
Where this breaks in practice:
  • Some custom multer configurations with fieldNameSize limits in busboy may truncate the field name before it reaches append-field
STEP 03

Send second field to trigger RangeError

A second text field in the same request (e.g., x[push] or simply another x[] entry) causes append-field to call .push() on the already-at-max-length array. V8 throws RangeError: Invalid array length. Because multer's middleware has no try/catch around the append-field invocation, the error becomes an unhandled exception and the Node.js worker process exits immediately.
Conditions required:
  • No external error boundary catching synchronous throws in the middleware chain
Where this breaks in practice:
  • Process managers (PM2, cluster, systemd) restart the worker within 1-5 seconds
  • Express global error handlers do NOT catch synchronous throws inside middleware — this is not friction, it's a common misconception
Detection/coverage: Application crash logs will show RangeError: Invalid array length with a stack trace through append-field. Node.js uncaughtException handlers that log-and-exit will capture the event.
STEP 04

Loop for sustained denial of service

The attacker repeats the request in a tight loop. Even with process manager restarts, each crash kills all in-flight requests on that worker, causes brief unavailability, and generates error spikes in monitoring. At sufficient request rate, the service is effectively offline. The payload is tiny (~200 bytes), so bandwidth is not a constraint.
Conditions required:
  • No rate limiting on the target endpoint
  • Process restarts are slower than attacker request rate
Where this breaks in practice:
  • Rate limiting, IP-based throttling, or CDN-level DDoS protection can cap request rate
  • Geographic or IP reputation filtering blocks automated sources
  • Load balancers with health checks can quarantine crashing instances
Detection/coverage: Spike in 502/503 errors, rapid process restart alerts in PM2/systemd, abnormal crash rate in APM tools (Datadog, New Relic).
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo known exploitation as of 2026-08-29. Disclosed yesterday (2026-08-28). Not listed on CISA KEV.
Proof of ConceptNo standalone PoC repository identified yet, but the advisory description is a complete recipe — crafting the payload requires only curl and two field names. Expect weaponized PoCs within days.
EPSS ScoreNot yet scored (CVE published 2026-08-28; EPSS typically populates within 1-3 days of NVD ingestion).
KEV StatusNot listed. Pure DoS CVEs rarely make KEV unless tied to ransomware or APT campaigns.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — Network-reachable, zero-click, availability-only impact. No scope change, no C/I impact.
Affected VersionsAll multer versions < 2.3.0, including the entire 1.x line (1.4.4-lts.1 through 1.4.5-lts.1) and 2.0.0 through 2.2.x.
Fixed Versionmulter 2.3.0 (released 2026-08-28). The fix adds fieldArrayIndexLimit configuration and wraps append-field calls.
Scanning / Exposure~20 million weekly npm downloads. Over 6,500 direct dependents on npm. Multer is the de facto file-upload middleware for Express.js — exposure is enormous across SaaS, internal tools, and API backends.
ReporterO4FDev (independent researcher). Fix developed by UlisesGascon (OpenJS Foundation / Express.js maintainer).
Related CVEsPart of a batch of 4 CVEs fixed in multer 2.3.0: CVE-2026-77037, CVE-2026-77063, CVE-2026-82333. Earlier DoS CVEs (CVE-2025-47944, CVE-2025-48997) fixed in 2.0.0 had the same CWE-248 pattern.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.5/10)

The single most decisive factor is the zero-prerequisite remote attack surface: any unauthenticated HTTP client can crash the target process with a ~200-byte request, and the affected package has 20 million weekly downloads. Impact is capped at availability loss (no RCE, no data breach), which is the single factor preventing escalation to CRITICAL.

HIGH Vulnerability mechanics and exploitability assessment
HIGH Affected version range and fix availability
MEDIUM Real-world exposure estimate (install base is clear, but fraction of public-facing endpoints unknown)

Why this verdict

  • Unauthenticated remote, zero-click, low-complexity — the CVSS base score correctly captures the trivial attack surface. No friction adjustments are warranted for attacker prerequisites because there are none.
  • Massive install base — 20M+ weekly downloads and 6,500+ direct dependents make this one of the most widely deployed npm packages. Even a small fraction of vulnerable deployments represents thousands of targets.
  • Process managers provide partial operational mitigation — PM2, cluster mode, and systemd restart workers within seconds, converting a single-shot kill into a degraded-service scenario rather than permanent outage. This is real friction but insufficient to downgrade because the attacker payload is trivially repeatable.
  • Role multiplier: Multer is a web-application-tier middleware. In *typical roles* (SaaS backends, internal APIs, admin panels), the blast radius is application-level availability loss — impactful but contained to one service. In *high-value roles* (e.g., an Express-based API gateway fronting microservices, or a CI/CD webhook receiver built on Express), a crash loop could cascade to broader service unavailability. However, even in worst-case high-value deployments, the outcome is availability loss only — no code execution, no credential theft, no lateral movement. The blast radius never reaches domain/fleet/supply-chain compromise, so the floor remains HIGH, not CRITICAL.

Why not higher?

Escalation to CRITICAL would require confidentiality or integrity impact (RCE, data exfiltration) or a blast radius reaching fleet/domain/supply-chain compromise. This is a pure availability bug — it crashes one process at a time, with no path to code execution, privilege escalation, or data access. Process managers limit sustained impact. DoS-only CVEs with no secondary chain are correctly capped at HIGH.

Why not lower?

Downgrading to MEDIUM would require meaningful friction in the attack path — authentication requirements, complex preconditions, or a narrow install base. None exist here: the attack is unauthenticated, single-request, trivially craftable from the advisory text alone, and targets one of the most popular npm packages in existence. The payload will be weaponized in nuclei templates within days of disclosure.

05 · Compensating Control

What to do — in priority order.

  1. Set busboy fieldNameSize limit to ≤ 100 bytes — Multer uses busboy under the hood. Configuring limits: { fieldNameSize: 100 } in your multer options truncates oversized field names before they reach append-field, neutralizing the array-index trick. Deploy this configuration change within the noisgate mitigation SLA of 30 days (HIGH), though given the trivial exploit, aim for days not weeks.
  2. Add WAF rule blocking numeric array indices > 6 digits in multipart field names — A regex-based WAF rule (e.g., in Cloudflare, AWS WAF, or ModSecurity) matching \[\d{7,}\] in Content-Disposition field names will drop the malicious payload before it reaches your application. This is a defense-in-depth layer while you patch.
  3. Enable rate limiting on upload endpoints — Rate limiting (e.g., 10 requests/second per IP on file-upload routes) prevents an attacker from sustaining a crash loop even if individual requests succeed. Use your reverse proxy (nginx limit_req, Envoy, Cloudflare Rate Limiting) to enforce this.
  4. Ensure process managers are configured with restart limits and alerting — Verify PM2, systemd, or your container orchestrator (Kubernetes liveness probes) will restart crashed workers quickly but also alert on rapid restart cycles. Set max_restarts with backoff to avoid infinite crash-restart loops consuming resources.
What doesn't work
  • Express global error handler (app.use((err, req, res, next) => ...)) — does NOT catch this crash. The RangeError is a synchronous throw inside middleware, not an error passed to next(err). Express error handlers only catch errors routed through the next() callback.
  • process.on('uncaughtException') with continue — while this handler fires, the Node.js docs explicitly warn against continuing after uncaught exceptions because process state is undefined. It can log the crash but should not be used as a mitigation to keep the process alive.
  • Helmet.js or CORS middleware — these are HTTP header/security middlewares and have zero interaction with multipart field name parsing. They provide no protection against this CVE.
06 · Verification

Crowdsourced verification payload.

Run this on any host where your Node.js application is deployed, or in your CI pipeline. Requires node and npm in PATH. No elevated privileges needed. Example: bash check_cve_2026_77078.sh /path/to/your/app

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_77078.sh — Detect multer < 2.3.0 (CVE-2026-77078)
# Usage: bash check_cve_2026_77078.sh [/path/to/project]
# Exit codes: 1=VULNERABLE, 0=PATCHED, 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 or provide the correct path."
  exit 2
fi

# Check if multer is installed
MULTER_PKG="$PROJECT_DIR/node_modules/multer/package.json"
if [ ! -f "$MULTER_PKG" ]; then
  echo "PATCHED — multer is not installed in this project (not affected)."
  exit 0
fi

# Extract version
VERSION=$(node -e "console.log(require('$MULTER_PKG').version)" 2>/dev/null)
if [ -z "$VERSION" ]; then
  echo "UNKNOWN — could not read multer version from $MULTER_PKG."
  exit 2
fi

# Compare version: vulnerable if < 2.3.0
IS_VULN=$(node -e "
  const semver = require('semver') || null;
  const v = '$VERSION';
  // Simple comparison without semver module
  const parts = v.split('.').map(Number);
  if (parts[0] < 2) { console.log('yes'); }
  else if (parts[0] === 2 && parts[1] < 3) { console.log('yes'); }
  else { console.log('no'); }
" 2>/dev/null)

if [ "$IS_VULN" = "yes" ]; then
  echo "VULNERABLE — multer $VERSION is installed (CVE-2026-77078 affects all versions < 2.3.0). Upgrade to >= 2.3.0."
  exit 1
else
  echo "PATCHED — multer $VERSION is installed (>= 2.3.0, not affected by CVE-2026-77078)."
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
CVE-2026-77078 is a trivially exploitable, unauthenticated DoS in one of npm's most popular packages. The vendor patch (multer 2.3.0) dropped yesterday. Your Monday-morning action: run npm audit across all Node.js repositories to identify multer < 2.3.0 instances, then immediately apply the fieldNameSize busboy limit as a compensating control (noisgate mitigation SLA: within 30 days for HIGH, but given zero-friction exploitability, push this config change out this week). Schedule the actual npm update multer to 2.3.0 across all services within the noisgate remediation SLA of 180 days — but realistically, this is a one-line package.json bump with no breaking API changes, so target completion within 2-3 weeks. Prioritize any public-facing upload endpoints first. If you run multer behind a WAF, deploy the numeric array-index field-name rule today as an additional safety net.

Sources

  1. CVE-2026-77078 — THREATINT
  2. GHSA-wc9g-mqfw-jrwm — GitHub Security Advisory (multer)
  3. Multer Releases — GitHub
  4. Multer — npm
  5. Multer Snyk Package Page
  6. Express.js June 2026 Security Releases
  7. Multer DoS via malformed requests — GHSA-4pg4-qvpc-4q3h (prior CVE pattern)
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.