Skip to content

Commit

Permalink
fix: prototype pollution
Browse files Browse the repository at this point in the history
  • Loading branch information
yeikos committed Feb 22, 2021
1 parent 8686d85 commit 7b0ddc2
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 4 deletions.
2 changes: 1 addition & 1 deletion dist/merge.browser.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion dist/merge.browser.test.js
Expand Up @@ -62,10 +62,13 @@ exports.isPlainObject = isPlainObject;
function _recursiveMerge(base, extend) {
if (!isPlainObject(base))
return extend;
for (var key in extend)
for (var key in extend) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype')
continue;
base[key] = (isPlainObject(base[key]) && isPlainObject(extend[key])) ?
_recursiveMerge(base[key], extend[key]) :
extend[key];
}
return base;
}
function _merge(isClone, isRecursive, items) {
Expand Down Expand Up @@ -194,6 +197,9 @@ describe('merge.recursive', function () {
});
it('prototype pollution attack', function () {
chai_1.assert.deepEqual(index_1.default.recursive({}, JSON.parse('{"__proto__": {"a": true}}')), {});
chai_1.assert.equal({}['a'], undefined);
chai_1.assert.deepEqual(index_1.default.recursive({ deep: {} }, JSON.parse('{ "deep": { "__proto__": {"b": true} }}')), { deep: {} });
chai_1.assert.equal({}['b'], undefined);
});
});

Expand Down
5 changes: 4 additions & 1 deletion lib/src/index.js
Expand Up @@ -55,10 +55,13 @@ exports.isPlainObject = isPlainObject;
function _recursiveMerge(base, extend) {
if (!isPlainObject(base))
return extend;
for (var key in extend)
for (var key in extend) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype')
continue;
base[key] = (isPlainObject(base[key]) && isPlainObject(extend[key])) ?
_recursiveMerge(base[key], extend[key]) :
extend[key];
}
return base;
}
function _merge(isClone, isRecursive, items) {
Expand Down
3 changes: 3 additions & 0 deletions lib/test/index.js
Expand Up @@ -99,5 +99,8 @@ describe('merge.recursive', function () {
});
it('prototype pollution attack', function () {
chai_1.assert.deepEqual(index_1.default.recursive({}, JSON.parse('{"__proto__": {"a": true}}')), {});
chai_1.assert.equal({}['a'], undefined);
chai_1.assert.deepEqual(index_1.default.recursive({ deep: {} }, JSON.parse('{ "deep": { "__proto__": {"b": true} }}')), { deep: {} });
chai_1.assert.equal({}['b'], undefined);
});
});
4 changes: 3 additions & 1 deletion src/index.ts
Expand Up @@ -61,10 +61,12 @@ function _recursiveMerge(base: any, extend: any) {
if (!isPlainObject(base))
return extend

for (const key in extend)
for (const key in extend) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue
base[key] = (isPlainObject(base[key]) && isPlainObject(extend[key])) ?
_recursiveMerge(base[key], extend[key]) :
extend[key]
}

return base

Expand Down
9 changes: 9 additions & 0 deletions test/index.ts
Expand Up @@ -219,6 +219,15 @@ describe('merge.recursive', function () {
{}
)

assert.equal(({} as any)['a'], undefined)

assert.deepEqual(
merge.recursive({ deep: {} }, JSON.parse('{ "deep": { "__proto__": {"b": true} }}')),
{ deep: {} }
)

assert.equal(({} as any)['b'], undefined)

})

})

0 comments on commit 7b0ddc2

Please sign in to comment.