Multer Orphaned Temporary File Disk-Exhaustion DoS — CVE-2026-3304
by Mkway · 2026-07-05
- Severity
- High
- CVE
- CVE-2026-3304
- Category
- web
- Affected product
- Multer (Node.js multipart/form-data middleware for Express)
- Affected versions
- Multer < 2.1.0
- Disclosed
- 2026-07-05
- Patch status
- patched
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-03 |
| Author / Researcher | Mkway |
| CVE / Advisory | CVE-2026-3304 |
| Category | web |
| Severity | High |
| CVSS Score | 8.7 (CVSS 4.0, per source repo) |
| Status | PoC |
| Tags | multer, nodejs, express, dos, file-upload, orphaned-file, disk-exhaustion, multipart |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Multer (Node.js multipart/form-data middleware for Express) |
| Versions Affected | Multer < 2.1.0 |
| Language / Platform | Node.js/Express server; Python exploit script; Docker lab |
| Authentication Required | No |
| Network Access Required | Yes |
Summary
Multer versions before 2.1.0 can leave temporary uploaded files permanently on disk when a multipart request is malformed in a specific way while using an asynchronous fileFilter callback (e.g., one deferred via setImmediate). When a valid file part is followed by a second part missing its required name attribute, Multer’s parser sets an internal errorOccured flag while the first file’s deferred fileFilter callback is still pending. When that callback later fires, the code never checks errorOccured before calling storage._handleFile(), so the first file is committed to disk even though the overall request will be rejected with an HTTP 500. Because the temp file is never cleaned up, repeating the malformed request drains available disk space. The repository includes a full lab (vulnerable and patched Docker services plus an exploit script) built directly from Multer’s own official regression test for the fix.
Vulnerability Details
Root Cause
The fileFilter completion callback in make-middleware.js does not check the errorOccured flag before invoking storage._handleFile(), so a temp file write scheduled before an error is detected proceeds anyway, and the file is never cleaned up on the resulting error path (CWE-459: Incomplete Cleanup).
Attack Vector
- Configure/target a Multer-based upload endpoint that uses an asynchronous
fileFilter(e.g., wrapped insetImmediate). - Send a multipart request whose first part is a valid file (triggering
storageto open a temp file and the deferredfileFiltercallback to be scheduled). - Include a second part that omits the required
nameattribute, causing Multer to seterrorOccured = truebefore the first part’s callback resumes. - When the deferred callback fires, it calls
storage._handleFile()unconditionally, committing the orphaned temp file to disk; the server then responds with HTTP 500. - Repeat the request many times to accumulate orphaned files and exhaust disk space.
Impact
Unauthenticated remote denial of service via disk exhaustion — repeated malformed uploads accumulate uncleaned temporary files until the upload volume/partition fills.
Environment / Lab Setup
Target: Node.js/Express app using Multer < 2.1.0 with an async fileFilter (Docker: vulnerable on :3000, patched 2.1.0 on :3001)
Attacker: Docker + Docker Compose, curl, Python 3 + requests
Proof of Concept
PoC Script
See
app/,exploit/(curl_poc.sh,exploit.py,monitor.sh),Dockerfile,Dockerfile.patched, anddocker-compose.ymlin this folder.
| |
Starts vulnerable (port 3000) and patched (port 3001) Multer servers, sends malformed multipart requests (valid file part followed by a part missing name), and reports the count of orphaned files and disk space consumed after each run.
Detection & Indicators of Compromise
MulterError: Field name missing
at abortWithCode (/app/node_modules/multer/lib/make-middleware.js:...)
Signs of compromise:
- Growing number of untracked temp files in the upload directory not matching any completed request
- Repeated HTTP 500 responses from upload endpoints tied to
MulterError/missing field name - Steadily increasing disk usage on the upload volume with no corresponding growth in legitimate stored files
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade to Multer 2.1.0, which adds an errorOccured check before storage._handleFile() is invoked (fix commit 739919097d) |
| Interim mitigation | Use synchronous fileFilter callbacks where possible, monitor and periodically clean orphaned files in the upload temp directory, and enforce disk quotas on upload volumes |
References
Notes
Mirrored from https://github.com/Mkway/CVE-2026-3304 on 2026-07-05.