VYPR
High severity7.5NVD Advisory· Published May 19, 2025· Updated Apr 15, 2026

CVE-2025-47935

CVE-2025-47935

Description

Multer is a node.js middleware for handling multipart/form-data. Versions prior to 2.0.0 are vulnerable to a resource exhaustion and memory leak issue due to improper stream handling. When the HTTP request stream emits an error, the internal busboy stream is not closed, violating Node.js stream safety guidance. This leads to unclosed streams accumulating over time, consuming memory and file descriptors. Under sustained or repeated failure conditions, this can result in denial of service, requiring manual server restarts to recover. All users of Multer handling file uploads are potentially impacted. Users should upgrade to 2.0.0 to receive a patch. No known workarounds are available.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
multernpm
< 2.0.02.0.0

Patches

2
2c8505f207d9

🐛 drain stream. fixes regression in node 18, remove old CI, set minimum node version, fix readme badges, add .npmrc

https://github.com/expressjs/multerChris de AlmeidaMay 19, 2025via ghsa
7 files changed · +73 23
  • CHANGELOG.md+6 0 modified
    @@ -3,6 +3,12 @@
     All notable changes to this project will be documented in this file.
     This project adheres to [Semantic Versioning](http://semver.org/).
     
    +## 2.0.0
    +
    +- **Breaking change: The minimum supported Node version is now 10.16.0**
    +- Fix [CVE-2025-47935](https://www.cve.org/CVERecord?id=CVE-2025-47935) ([GHSA-44fp-w29j-9vj5](https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5))
    +- Fix [CVE-2025-47944](https://www.cve.org/CVERecord?id=CVE-2025-47944) ([GHSA-4pg4-qvpc-4q3h](https://github.com/expressjs/multer/security/advisories/GHSA-4pg4-qvpc-4q3h))
    +
     ## 1.4.5-lts.2
     
     - Fix out-of-band error event from busboy (#1177)
    
  • .github/workflows/ci.yml+2 18 modified
    @@ -11,8 +11,6 @@ jobs:
           fail-fast: false
           matrix:
             name:
    -        - Node.js 6.x
    -        - Node.js 8.x
             - Node.js 10.x
             - Node.js 11.x
             - Node.js 12.x
    @@ -30,14 +28,6 @@ jobs:
             - Node.js 24.x
     
             include:
    -        - name: Node.js 6.x
    -          node-version: "6.17"
    -          npm-i: mocha@6.2.2 nyc@14.1.1
    -
    -        - name: Node.js 8.x
    -          node-version: "8.17"
    -          npm-i: mocha@7.1.2 nyc@14.1.1
    -
             - name: Node.js 10.x
               node-version: "10.24"
               npm-i: mocha@8.4.0
    @@ -56,9 +46,11 @@ jobs:
               
             - name: Node.js 14.x
               node-version: "14.21"
    +          npm-i: mocha@9.2.2
               
             - name: Node.js 15.x
               node-version: "15.14"
    +          npm-i: mocha@9.2.2
               
             - name: Node.js 16.x
               node-version: "16.20"
    @@ -107,14 +99,6 @@ jobs:
             fi
             dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH"
     
    -    - name: Configure npm
    -      run: |
    -        if [[ "$(npm config get package-lock)" == "true" ]]; then
    -          npm config set package-lock false
    -        else
    -          npm config set shrinkwrap false
    -        fi
    -
         - name: Remove npm module(s) ${{ matrix.npm-rm }}
           run: npm rm --silent --save-dev ${{ matrix.npm-rm }}
           if: matrix.npm-rm != ''
    
  • lib/make-middleware.js+13 1 modified
    @@ -8,6 +8,12 @@ var MulterError = require('./multer-error')
     var FileAppender = require('./file-appender')
     var removeUploadedFiles = require('./remove-uploaded-files')
     
    +function drainStream (stream) {
    +  stream.on('readable', () => {
    +    while (stream.read() !== null) {}
    +  })
    +}
    +
     function makeMiddleware (setup) {
       return function multerMiddleware (req, res, next) {
         if (!is(req, ['multipart'])) return next()
    @@ -22,6 +28,10 @@ function makeMiddleware (setup) {
     
         req.body = Object.create(null)
     
    +    req.on('error', function (err) {
    +      abortWithError(err)
    +    })
    +
         var busboy
     
         try {
    @@ -41,7 +51,9 @@ function makeMiddleware (setup) {
           if (isDone) return
           isDone = true
           req.unpipe(busboy)
    -      process.nextTick(() => {
    +      drainStream(req)
    +      req.resume()
    +      setImmediate(() => {
             busboy.removeAllListeners()
           })
           next(err)
    
  • .npmrc+1 0 added
    @@ -0,0 +1 @@
    +package-lock=false
    
  • package.json+4 3 modified
    @@ -1,7 +1,7 @@
     {
       "name": "multer",
       "description": "Middleware for handling `multipart/form-data`.",
    -  "version": "1.4.5-lts.2",
    +  "version": "2.0.0",
       "contributors": [
         "Hage Yaapa <captain@hacksparrow.com> (http://www.hacksparrow.com)",
         "Jaret Pfluger <https://github.com/jpfluger>",
    @@ -32,13 +32,13 @@
         "express": "^4.13.1",
         "form-data": "^1.0.0-rc1",
         "fs-temp": "^1.1.2",
    -    "mocha": "^3.5.3",
    +    "mocha": "^11.3.0",
         "rimraf": "^2.4.1",
         "standard": "^14.3.3",
         "testdata-w3c-json-form": "^1.0.0"
       },
       "engines": {
    -    "node": ">= 6.0.0"
    +    "node": ">= 10.16.0"
       },
       "files": [
         "LICENSE",
    @@ -48,6 +48,7 @@
       ],
       "scripts": {
         "lint": "standard",
    +    "lint:fix": "standard --fix",
         "test": "mocha --reporter spec --exit --check-leaks test/",
         "test-ci": "nyc --reporter=lcov --reporter=text npm test",
         "test-cov": "nyc --reporter=html --reporter=text npm test"
    
  • README.md+1 1 modified
    @@ -1,4 +1,4 @@
    -# Multer [![Build Status](https://travis-ci.org/expressjs/multer.svg?branch=master)](https://travis-ci.org/expressjs/multer) [![NPM version](https://badge.fury.io/js/multer.svg)](https://badge.fury.io/js/multer) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)
    +# Multer [![Build Status](https://badgen.net/github/checks/expressjs/multer/master?label=ci)](https://github.com/expressjs/multer/actions/workflows/ci.yml) [![Test Coverage](https://badgen.net/coveralls/c/github/expressjs/multer/master)](https://coveralls.io/r/expressjs/multer?branch=master) [![NPM version](https://badge.fury.io/js/multer.svg)](https://badge.fury.io/js/multer) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)
     
     Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
     on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
    
  • test/express-integration.js+46 0 modified
    @@ -150,4 +150,50 @@ describe('Express Integration', function () {
         req.write(body)
         req.end()
       })
    +
    +  it('should not crash on malformed request that causes two errors to be emitted by busboy', function (done) {
    +    var upload = multer()
    +
    +    app.post('/upload2', upload.single('file'), function (req, res) {
    +      res.status(500).end('Request should not be processed')
    +    })
    +
    +    app.use(function (err, req, res, next) {
    +      assert.strictEqual(err.message, 'Malformed part header')
    +      res.status(200).end('Correct error')
    +    })
    +
    +    var boundary = 'AaB03x'
    +    // this payload causes two errors to be emitted by busboy: `Malformed part header` and `Unexpected end of form`
    +    var body = [
    +      '--' + boundary,
    +      'Content-Disposition: form-data; name="file"; filename="test.txt"',
    +      'Content-Type: text/plain',
    +      '',
    +      '--' + boundary + '--',
    +      ''
    +    ].join('\r\n')
    +    var options = {
    +      hostname: 'localhost',
    +      port,
    +      path: '/upload2',
    +      method: 'POST',
    +      headers: {
    +        'content-type': 'multipart/form-data; boundary=' + boundary,
    +        'content-length': body.length
    +      }
    +    }
    +
    +    var req = http.request(options, (res) => {
    +      assert.strictEqual(res.statusCode, 200)
    +      done()
    +    })
    +
    +    req.on('error', (err) => {
    +      done(err)
    +    })
    +
    +    req.write(body)
    +    req.end()
    +  })
     })
    

Vulnerability mechanics

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

References

5

News mentions

0

No linked articles in our index yet.