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.
| Package | Affected versions | Patched versions |
|---|---|---|
multernpm | < 2.0.0 | 2.0.0 |
Patches
22c8505f207d9🐛 drain stream. fixes regression in node 18, remove old CI, set minimum node version, fix readme badges, add .npmrc
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 [](https://travis-ci.org/expressjs/multer) [](https://badge.fury.io/js/multer) [](https://github.com/feross/standard) +# Multer [](https://github.com/expressjs/multer/actions/workflows/ci.yml) [](https://coveralls.io/r/expressjs/multer?branch=master) [](https://badge.fury.io/js/multer) [](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() + }) })
5341f114a3a4Vulnerability 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- github.com/advisories/GHSA-44fp-w29j-9vj5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-47935ghsaADVISORY
- github.com/expressjs/multer/commit/2c8505f207d923dd8de13a9f93a4563e59933665nvdWEB
- github.com/expressjs/multer/pull/1120nvdWEB
- github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5nvdWEB
News mentions
0No linked articles in our index yet.