Skip to content

Commit

Permalink
fix(utils): avoid copying special properties like __proto__ when me…
Browse files Browse the repository at this point in the history
…rging and cloning
  • Loading branch information
vkarpov15 committed Dec 10, 2020
1 parent 2268a48 commit 792e69f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
11 changes: 11 additions & 0 deletions lib/utils.js
Expand Up @@ -7,6 +7,8 @@
var Buffer = require('safe-buffer').Buffer;
var RegExpClone = require('regexp-clone');

var specialProperties = ['__proto__', 'constructor', 'prototype'];

/**
* Clones objects
*
Expand Down Expand Up @@ -69,6 +71,12 @@ exports.cloneObject = function cloneObject(obj, options) {
var k;

for (k in obj) {
// Not technically prototype pollution because this wouldn't merge properties
// onto `Object.prototype`, but avoid properties like __proto__ as a precaution.
if (specialProperties.indexOf(k) !== -1) {
continue;
}

val = clone(obj[k], options);

if (!minimize || ('undefined' !== typeof val)) {
Expand Down Expand Up @@ -133,6 +141,9 @@ exports.merge = function merge(to, from) {

while (i--) {
key = keys[i];
if (specialProperties.indexOf(key) !== -1) {
continue;
}
if ('undefined' === typeof to[key]) {
to[key] = from[key];
} else {
Expand Down
18 changes: 18 additions & 0 deletions test/utils.test.js
Expand Up @@ -140,5 +140,23 @@ describe('lib/utils', function() {

done();
});

it('skips __proto__', function() {
var payload = JSON.parse('{"__proto__": {"polluted": "vulnerable"}}');
var res = utils.clone(payload);

assert.strictEqual({}.polluted, void 0);
assert.strictEqual(res.__proto__, Object.prototype);
});
});

describe('merge', function() {
it('avoids prototype pollution', function() {
var payload = JSON.parse('{"__proto__": {"polluted": "vulnerable"}}');
var obj = {};
utils.merge(obj, payload);

assert.strictEqual({}.polluted, void 0);
});
});
});

0 comments on commit 792e69f

Please sign in to comment.