diff --git a/lib/document.js b/lib/document.js index 81d51a2ce3e..8d35993da8a 100644 --- a/lib/document.js +++ b/lib/document.js @@ -741,6 +741,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; schemaType = docSchema.path(path); diff --git a/test/document.test.js b/test/document.test.js index 1e6c9ef7afd..5a5945cd57e 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -12212,6 +12212,24 @@ describe('document', function() { const fromDb = await Test.findById(x._id).lean(); assert.equal(fromDb.c.x.y, 1); }); + + it('avoids prototype pollution on init', async function() { + const Example = db.model('Example', new Schema({ hello: String })); + + const example = await new Example({ hello: 'world!' }).save(); + await Example.findByIdAndUpdate(example._id, { + $rename: { + hello: '__proto__.polluted' + } + }); + + // this is what causes the pollution + await Example.find(); + + const test = {}; + assert.strictEqual(test.polluted, undefined); + assert.strictEqual(Object.prototype.polluted, undefined); + }); }); describe('Check if instance function that is supplied in schema option is availabe', function() {