Skip to content

Commit 5ce8afd

Browse files
authored
fix: deny modifying the object prototype (#1698)
1 parent 837a3cc commit 5ce8afd

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

src/shared/object.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ export function deepAssign<T, S>(target: T, source: S): T & S;
1414
export function deepAssign<S>(target: {}, source: S): S;
1515
export function deepAssign(target: any, ...sources: any[]): any {
1616
sources.forEach((source) => {
17-
Object.getOwnPropertyNames(source).forEach((key) => assign(key, target, source));
17+
Object.getOwnPropertyNames(source).forEach(
18+
(key) =>
19+
!['__proto__', 'constructor', 'prototype'].includes(key) && assign(key, target, source)
20+
);
1821
/* istanbul ignore next */
1922
if (Object.getOwnPropertySymbols) {
2023
Object.getOwnPropertySymbols(source).forEach((key) => assign(key, target, source));

test/specs/utils/object.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { expect } from 'chai';
22
import { deepAssign } from '../../../src/shared/object';
3+
import { addScopeOptions } from '../../../src/scopes/scope-service';
34

45
describe('utils', () => {
56
describe('object', () => {
@@ -109,6 +110,14 @@ describe('utils', () => {
109110
expect(copy.test).to.have.property('protoFn').that.is.a('function');
110111
});
111112

113+
it('ignore prototype property', () => {
114+
const BAD_JSON = JSON.parse('{"__proto__":{"polluted":true}}');
115+
const empty_scope = {};
116+
117+
addScopeOptions(empty_scope, BAD_JSON);
118+
expect(empty_scope).not.to.have.property('polluted');
119+
});
120+
112121
if (Object.getOwnPropertySymbols) {
113122
it('should copy symbol based objects', () => {
114123
const symbol = Symbol('test');

0 commit comments

Comments
 (0)