From 99d8a14df682b2a93a26216b0fab7d7c4bef1100 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Tue, 5 Dec 2023 09:08:09 +0100 Subject: [PATCH 1/2] fix: only emit prototype pollution error when there's metadata emitted --- src/index.test.ts | 7 ++++++- src/plainer.ts | 22 ++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/index.test.ts b/src/index.test.ts index e314728..7fa8ebf 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1059,7 +1059,7 @@ test.each(['__proto__', 'prototype', 'constructor'])( forbidden => { expect(() => { SuperJSON.serialize({ - [forbidden]: 1, + [forbidden]: NaN, }); }).toThrowError(/This is a prototype pollution risk/); } @@ -1229,3 +1229,8 @@ test('dedupe=true on a large complicated schema', () => { expect(nondedupedOut).toEqual(deserialized); expect(dedupedOut).toEqual(deserialized); }); + +test("prototype pollution detector doesn't trigger when there's no meta", () => { + const { meta } = SuperJSON.serialize({ constructor: { name: 'hello' } }); + expect(meta).toBeUndefined(); +}); diff --git a/src/plainer.ts b/src/plainer.ts index 114d76a..3c3c2ae 100644 --- a/src/plainer.ts +++ b/src/plainer.ts @@ -216,16 +216,6 @@ export const walker = ( const innerAnnotations: Record> = {}; forEach(transformed, (value, index) => { - if ( - index === '__proto__' || - index === 'constructor' || - index === 'prototype' - ) { - throw new Error( - `Detected property ${index}. This is a prototype pollution risk, please remove it from your object.` - ); - } - const recursiveResult = walker( value, identities, @@ -236,6 +226,18 @@ export const walker = ( seenObjects ); + const emitsMeta = recursiveResult.annotations !== undefined; + if ( + emitsMeta && + (index === '__proto__' || + index === 'constructor' || + index === 'prototype') + ) { + throw new Error( + `Detected property ${index}. This is a prototype pollution risk, please remove it from your object.` + ); + } + transformedValue[index] = recursiveResult.transformedValue; if (isArray(recursiveResult.annotations)) { From 5fa55b76a742540f1b00dc1951418a4880608171 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 6 Dec 2023 12:08:06 +0100 Subject: [PATCH 2/2] fix: add repro for https://github.com/blitz-js/superjson/issues/279#issuecomment-1842647002 --- src/index.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/index.test.ts b/src/index.test.ts index 7fa8ebf..af7f484 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -686,6 +686,21 @@ describe('stringify & parse', () => { }, }, }, + 'repro #281': { + input: { + schema: { constructor: { type: 'string' } }, + createdAt: new Date('2023-12-06T10:49:28.911Z'), + }, + output: { + schema: { constructor: { type: 'string' } }, + createdAt: '2023-12-06T10:49:28.911Z', + }, + outputAnnotations: { + values: { + createdAt: ['Date'], + }, + }, + }, }; function deepFreeze(object: any, alreadySeenObjects = new Set()) {