diff --git a/lib/document.js b/lib/document.js index 7add115faf5..25e22cab0ab 100644 --- a/lib/document.js +++ b/lib/document.js @@ -689,6 +689,10 @@ function init(self, obj, doc, opts, prefix) { function _init(index) { i = keys[index]; + // avoid prototype pollution + if (i === '__proto__' || i === 'constructor') { + return; + } path = prefix + i; schema = self.$__schema.path(path); diff --git a/test/document.test.js b/test/document.test.js index e8b66176a1a..57a877cedf6 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -10528,4 +10528,24 @@ describe('document', function() { assert.ok(!band.embeddedMembers[0].member.name); }); }); + + it('avoids prototype pollution on init', function() { + const Example = db.model('Example', new Schema({ hello: String })); + + return co(function*() { + const example = yield new Example({ hello: 'world!' }).save(); + yield Example.findByIdAndUpdate(example._id, { + $rename: { + hello: '__proto__.polluted' + } + }); + + // this is what causes the pollution + yield Example.find(); + + const test = {}; + assert.strictEqual(test.polluted, undefined); + assert.strictEqual(Object.prototype.polluted, undefined); + }); + }); });