Skip to content

Commit

Permalink
fix: __proto__ property merge
Browse files Browse the repository at this point in the history
  • Loading branch information
vlad-tkachenko committed Feb 24, 2021
1 parent 9842609 commit 321f75a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
17 changes: 9 additions & 8 deletions src/utils/CollideUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function collide(arg1: any, arg2: any, modifiers?: ICollideModifiers, sta
* @param startPath the entry path to start modifier path generation. Default value: $
* @returns collide result
*/
export function collideUnsafe(arg1: any, arg2: any, modifiers?: ICollideModifiers, startPath: string = '$'): any {
export function collideUnsafe(arg1: any, arg2: any, modifiers?: ICollideModifiers, startPath = '$'): any {
if (arg2 === undefined) {
return arg1;
}
Expand Down Expand Up @@ -78,14 +78,15 @@ function collideObjects(obj1: any, obj2: any, path: string, modifiers?: ICollide

for (const key of Object.keys(obj2)) {
const subPath = path + '.' + key;

if (obj1[key] === undefined) {
obj1[key] = obj2[key];
} else {
if (modifiers && modifiers[subPath]) {
obj1[key] = modifiers[subPath](obj1[key], obj2[key]);
if (key !== '__proto__') {
if (obj1[key] === undefined) {
obj1[key] = obj2[key];
} else {
obj1[key] = collideUnsafe(obj1[key], obj2[key], modifiers, subPath);
if (modifiers && modifiers[subPath]) {
obj1[key] = modifiers[subPath](obj1[key], obj2[key]);
} else {
obj1[key] = collideUnsafe(obj1[key], obj2[key], modifiers, subPath);
}
}
}
}
Expand Down
49 changes: 35 additions & 14 deletions test/unit/CollideUtilTestSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,17 @@ class CollideUtilTestSuite {
override: 11,
};

collideUnsafe(
obj1,
{
array: [3, 4],
obj: {
b: false,
d: 'd',
e: 1,
n: null,
array: [12, 13, 14],
},
override: 111,
collideUnsafe(obj1, {
array: [3, 4],
obj: {
b: false,
d: 'd',
e: 1,
n: null,
array: [12, 13, 14],
},
);
override: 111,
});

assert.deepStrictEqual(obj1, {
array: [1, 2, 3, 4],
Expand Down Expand Up @@ -164,7 +161,7 @@ class CollideUtilTestSuite {
'#.custom.obj': (a: any, b: any) => Object.assign(a, b),
'#.custom.override': (a: any) => a,
},
'#.custom'
'#.custom',
);

assert.deepStrictEqual(result, {
Expand Down Expand Up @@ -259,4 +256,28 @@ class CollideUtilTestSuite {
collide({ a: [1, 2] }, { a: true });
}).to.throw('Unable to collide. Collide value at path $.a is not an array.');
}

@test()
async testWithPrototypePollution(): Promise<void> {
const collideWith = JSON.parse(`{
"__proto__": {
"vulnerable": "yes"
},
"array": [3, 4]
}`);

console.log(collideWith);

const result = collide(
{
array: [1, 2],
},
collideWith,
);

assert.ok(!result.vulnerable);
assert.deepStrictEqual(result, {
array: [1, 2, 3, 4],
});
}
}

1 comment on commit 321f75a

@abergmann
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CVE-2021-25914 was assigned to this commit.

Please # to comment.