diff --git a/packages/cli/src/utils/deepMerge.test.ts b/packages/cli/src/utils/deepMerge.test.ts index ee6cc7169c..3310924795 100644 --- a/packages/cli/src/utils/deepMerge.test.ts +++ b/packages/cli/src/utils/deepMerge.test.ts @@ -152,13 +152,27 @@ describe('customDeepMerge', () => { }); it('should not pollute the prototype', () => { - const maliciousSource = JSON.parse('{"__proto__": {"polluted": "true"}}'); + const maliciousSource = JSON.parse('{"__proto__": {"polluted1": "true"}}'); const getMergeStrategy = () => undefined; - const result = customDeepMerge(getMergeStrategy, {}, maliciousSource); + let result = customDeepMerge(getMergeStrategy, {}, maliciousSource); expect(result).toEqual({}); // eslint-disable-next-line @typescript-eslint/no-explicit-any - expect(({} as any).polluted).toBeUndefined(); + expect(({} as any).polluted1).toBeUndefined(); + + const maliciousSource2 = JSON.parse( + '{"constructor": {"prototype": {"polluted2": "true"}}}', + ); + result = customDeepMerge(getMergeStrategy, {}, maliciousSource2); + expect(result).toEqual({}); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect(({} as any).polluted2).toBeUndefined(); + + const maliciousSource3 = JSON.parse('{"prototype": {"polluted3": "true"}}'); + result = customDeepMerge(getMergeStrategy, {}, maliciousSource3); + expect(result).toEqual({}); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect(({} as any).polluted3).toBeUndefined(); }); it('should use additionalProperties merge strategy for dynamic properties', () => { diff --git a/packages/cli/src/utils/deepMerge.ts b/packages/cli/src/utils/deepMerge.ts index 740021361f..2eef3b4ada 100644 --- a/packages/cli/src/utils/deepMerge.ts +++ b/packages/cli/src/utils/deepMerge.ts @@ -30,7 +30,7 @@ function mergeRecursively( for (const key of Object.keys(source)) { // JSON.parse can create objects with __proto__ as an own property. // We must skip it to prevent prototype pollution. - if (key === '__proto__') { + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { continue; } const srcValue = source[key];