VYPR
High severityNVD Advisory· Published Feb 27, 2026· Updated Feb 27, 2026

Multer vulnerable to Denial of Service via resource exhaustion

CVE-2026-2359

Description

Multer is a node.js middleware for handling multipart/form-data. A vulnerability in Multer prior to version 2.1.0 allows an attacker to trigger a Denial of Service (DoS) by dropping connection during file upload, potentially causing resource exhaustion. Users should upgrade to version 2.1.0 to receive a patch. No known workarounds are available.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Multer before 2.1.0 is vulnerable to Denial of Service via resource exhaustion when an attacker drops connection during file upload.

Vulnerability

Description

Multer is a Node.js middleware for handling multipart/form-data file uploads [1]. In versions prior to 2.1.0, a vulnerability exists where an attacker can trigger a Denial of Service (DoS) by dropping the connection during a file upload. This causes the server to not properly release allocated resources, leading to resource exhaustion [3][4].

Exploitation

An attacker can exploit this vulnerability by initiating a file upload request and then abruptly closing the connection. The attack can be performed remotely without authentication if the upload endpoint is publicly accessible. No special privileges are required [3].

Impact

Successful exploitation can consume server memory or file handles, eventually causing the server to become unresponsive. Repeated attacks can lead to a full DoS condition, impacting the availability of the application. No known workarounds exist [3][4].

Mitigation

The vulnerability is fixed in Multer version 2.1.0. Users are advised to upgrade immediately. There are no known workarounds for affected versions [3].

AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
multernpm
< 2.1.02.1.0

Affected products

2

Patches

1
cccf0fe0e641

🔒️ improve disconnect handling

https://github.com/expressjs/multerctcpipFeb 11, 2026via ghsa
2 files changed · +89 21
  • lib/make-middleware.js+39 21 modified
    @@ -28,24 +28,8 @@ function makeMiddleware (setup) {
     
         req.body = Object.create(null)
     
    -    req.on('error', function (err) {
    -      abortWithError(err)
    -    })
    -
         var busboy
    -
    -    try {
    -      busboy = Busboy({
    -        headers: req.headers,
    -        limits: limits,
    -        preservePath: preservePath,
    -        defParamCharset: defParamCharset
    -      })
    -    } catch (err) {
    -      return next(err)
    -    }
    -
    -    var appender = new FileAppender(fileStrategy, req)
    +    var appender = null
         var isDone = false
         var readFinished = false
         var errorOccured = false
    @@ -55,12 +39,14 @@ function makeMiddleware (setup) {
         function done (err) {
           if (isDone) return
           isDone = true
    -      req.unpipe(busboy)
    +      if (busboy) {
    +        req.unpipe(busboy)
    +        setImmediate(() => {
    +          busboy.removeAllListeners()
    +        })
    +      }
           drainStream(req)
           req.resume()
    -      setImmediate(() => {
    -        busboy.removeAllListeners()
    -      })
           next(err)
         }
     
    @@ -90,6 +76,38 @@ function makeMiddleware (setup) {
           abortWithError(new MulterError(code, optionalField))
         }
     
    +    function handleRequestFailure (err) {
    +      if (isDone) return
    +      if (busboy) busboy.destroy(err)
    +      abortWithError(err)
    +    }
    +
    +    req.on('error', function (err) {
    +      handleRequestFailure(err || new Error('Request error'))
    +    })
    +
    +    req.on('aborted', function () {
    +      handleRequestFailure(new Error('Request aborted'))
    +    })
    +
    +    req.on('close', function () {
    +      if (req.readableEnded) return
    +      handleRequestFailure(new Error('Request closed'))
    +    })
    +
    +    try {
    +      busboy = Busboy({
    +        headers: req.headers,
    +        limits: limits,
    +        preservePath: preservePath,
    +        defParamCharset: defParamCharset
    +      })
    +    } catch (err) {
    +      return next(err)
    +    }
    +
    +    appender = new FileAppender(fileStrategy, req)
    +
         // handle text field data
         busboy.on('field', function (fieldname, value, { nameTruncated, valueTruncated }) {
           if (fieldname == null) return abortWithCode('MISSING_FIELD_NAME')
    
  • test/error-handling.js+50 0 modified
    @@ -7,6 +7,8 @@ var util = require('./_util')
     var multer = require('../')
     var stream = require('stream')
     var FormData = require('form-data')
    +var http = require('http')
    +var net = require('net')
     
     function withLimits (limits, fields) {
       var storage = multer.memoryStorage()
    @@ -277,4 +279,52 @@ describe('Error Handling', function () {
           done()
         })
       })
    +
    +  it('should not hang when client aborts multipart upload', function (done) {
    +    this.timeout(5000)
    +
    +    var upload = multer({ storage: multer.memoryStorage() }).any()
    +
    +    var server = http.createServer(function (req, res) {
    +      var hung = false
    +
    +      var timer = setTimeout(function () {
    +        hung = true
    +        server.close()
    +        done(new Error('Middleware hung when client aborted request'))
    +      }, 1000)
    +
    +      upload(req, res, function (/* err */) {
    +        if (hung) return
    +        clearTimeout(timer)
    +        server.close()
    +        done()
    +      })
    +    })
    +
    +    server.listen(0, function () {
    +      var port = server.address().port
    +      var boundary = 'PoC' + Date.now()
    +      var sock = new net.Socket()
    +
    +      sock.connect(port, '127.0.0.1', function () {
    +        sock.write(
    +          'POST / HTTP/1.1\r\n' +
    +          'Host: localhost\r\n' +
    +          'Content-Type: multipart/form-data; boundary=' + boundary + '\r\n' +
    +          'Content-Length: 999999\r\n\r\n' +
    +          '--' + boundary + '\r\n' +
    +          'Content-Disposition: form-data; name="file"; filename="test.bin"\r\n' +
    +          'Content-Type: application/octet-stream\r\n\r\n' +
    +          'AAAAAAAAAAAAAAAA'
    +        )
    +
    +        setTimeout(function () {
    +          sock.destroy()
    +        }, 50)
    +      })
    +
    +      sock.on('error', function () {})
    +    })
    +  })
     })
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.