From 60f371f6b37b6744ffdbbeb50d1e7e8463a68146 Mon Sep 17 00:00:00 2001 From: Vinayak Mishra Date: Wed, 18 Feb 2026 11:13:20 +0545 Subject: [PATCH] fix: set maxFiles default to 1000 to match maxFields maxFiles defaulted to Infinity, making _setUpMaxFiles() a no-op. An attacker could send thousands of tiny files in a single multipart request, each creating a temp file via fs.createWriteStream(), crashing the process with EMFILE on default ulimit -n (1024). Closes #1064 --- src/Formidable.js | 2 +- test/unit/formidable.test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Formidable.js b/src/Formidable.js index 581e7080..5ea964e0 100644 --- a/src/Formidable.js +++ b/src/Formidable.js @@ -22,7 +22,7 @@ const createId = cuid2init({ length: 25, fingerprint: CUID2_FINGERPRINT.toLowerC const DEFAULT_OPTIONS = { maxFields: 1000, maxFieldsSize: 20 * 1024 * 1024, - maxFiles: Infinity, + maxFiles: 1000, maxFileSize: 200 * 1024 * 1024, maxTotalFileSize: undefined, minFileSize: 1, diff --git a/test/unit/formidable.test.js b/test/unit/formidable.test.js index 8a36cbc4..6efc6f1e 100644 --- a/test/unit/formidable.test.js +++ b/test/unit/formidable.test.js @@ -302,6 +302,32 @@ function makeHeader(originalFilename) { }); }); + test(`${name}: maxFiles exceeded emits error`, (done) => { + const form = getForm(name, { maxFiles: 1 }); + form.req = requestStub(); + + form.on('error', (error) => { + expect(error.message.includes('maxFiles')).toBe(true); + done(); + }); + + const part1 = new Stream(); + part1.mimetype = 'text/plain'; + const part2 = new Stream(); + part2.mimetype = 'text/plain'; + + form.onPart(part1).then(() => { + part1.emit('data', Buffer.alloc(1)); + part1.emit('end'); + form.onPart(part2); + }); + }); + + test(`${name}: maxFiles defaults to 1000`, () => { + const form = getForm(name); + expect(form.options.maxFiles).toBe(1000); + }); + // test(`${name}: use custom options.originalFilename instead of form._uploadPath`, () => { // const form = getForm(name, { // originalFilename: (_) => path.join(__dirname, 'sasa'),