From 3c0c11cade045c4412c242b5727308cff9897a0e Mon Sep 17 00:00:00 2001 From: Dmitriy Mozgovoy Date: Wed, 3 Jan 2024 21:37:32 +0200 Subject: [PATCH] fix(security): fixed formToJSON prototype pollution vulnerability; (#6167) --- lib/helpers/formDataToJSON.js | 3 +++ test/specs/helpers/formDataToJSON.spec.js | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/helpers/formDataToJSON.js b/lib/helpers/formDataToJSON.js index f4581df468..906ce60258 100644 --- a/lib/helpers/formDataToJSON.js +++ b/lib/helpers/formDataToJSON.js @@ -49,6 +49,9 @@ function arrayToObject(arr) { function formDataToJSON(formData) { function buildPath(path, value, target, index) { let name = path[index++]; + + if (name === '__proto__') return true; + const isNumericKey = Number.isFinite(+name); const isLast = index >= path.length; name = !name && utils.isArray(target) ? target.length : name; diff --git a/test/specs/helpers/formDataToJSON.spec.js b/test/specs/helpers/formDataToJSON.spec.js index 9fc9fa1e05..d49177e9bd 100644 --- a/test/specs/helpers/formDataToJSON.spec.js +++ b/test/specs/helpers/formDataToJSON.spec.js @@ -47,4 +47,25 @@ describe('formDataToJSON', function () { foo: ['1', '2'] }); }); + + it('should resist prototype pollution CVE', () => { + const formData = new FormData(); + + formData.append('foo[0]', '1'); + formData.append('foo[1]', '2'); + formData.append('__proto__.x', 'hack'); + formData.append('constructor.prototype.y', 'value'); + + expect(formDataToJSON(formData)).toEqual({ + foo: ['1', '2'], + constructor: { + prototype: { + y: 'value' + } + } + }); + + expect({}.x).toEqual(undefined); + expect({}.y).toEqual(undefined); + }); });