From 6c63f04ba37174021082a5b5c4ba1556dcc954f4 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 9 Nov 2022 20:32:26 +0000 Subject: [PATCH] fix: Prototype pollution via Cloud Code Webhooks; fixes security vulnerability [GHSA-93vw-8fm5-p2jf](https://github.com/parse-community/parse-server/security/advisories/GHSA-93vw-8fm5-p2jf) (#8306) --- spec/vulnerabilities.spec.js | 11 +++++++++++ src/Controllers/DatabaseController.js | 6 +++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spec/vulnerabilities.spec.js b/spec/vulnerabilities.spec.js index 957277772f..5c83493c94 100644 --- a/spec/vulnerabilities.spec.js +++ b/spec/vulnerabilities.spec.js @@ -109,6 +109,17 @@ describe('Vulnerabilities', () => { ); }); + it('denies expanding existing object with polluted keys', async () => { + const obj = await new Parse.Object('RCE', { a: { foo: [] } }).save(); + await reconfigureServer({ + requestKeywordDenylist: ['foo'], + }); + obj.addUnique('a.foo', 'abc'); + await expectAsync(obj.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Prohibited keyword in request data: "foo".`) + ); + }); + it('denies creating a cloud trigger with polluted data', async () => { Parse.Cloud.beforeSave('TestObject', ({ object }) => { object.set('obj', { diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index b3aa44efe5..4fb07ea1c0 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1701,7 +1701,11 @@ class DatabaseController { if (this.options && this.options.requestKeywordDenylist) { // Scan request data for denied keywords for (const keyword of this.options.requestKeywordDenylist) { - const match = Utils.objectContainsKeyValue({ firstKey: undefined }, keyword.key, undefined); + const match = Utils.objectContainsKeyValue( + { [firstKey]: true, [nextPath]: true }, + keyword.key, + true + ); if (match) { throw new Parse.Error( Parse.Error.INVALID_KEY_NAME,