VYPR
Critical severityNVD Advisory· Published Jul 17, 2023· Updated Oct 30, 2024

Prototype Pollution in automattic/mongoose

CVE-2023-3696

Description

Prototype pollution vulnerability in Mongoose before 7.3.4 allows attackers to pollute Object.prototype via crafted database documents.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Prototype pollution vulnerability in Mongoose before 7.3.4 allows attackers to pollute Object.prototype via crafted database documents.

Vulnerability

Details

CVE-2023-3696 is a prototype pollution vulnerability in the Mongoose MongoDB ODM library for Node.js, affecting versions prior to 7.3.4. The flaw resides in the init function used to hydrate documents from the database. When processing document fields, the function does not filter out dangerous property names such as __proto__ or constructor, allowing an attacker to inject properties into the global Object.prototype [2][4].

Exploitation

An attacker with write access to the MongoDB database can exploit this by using MongoDB operations like $rename to rename a field to __proto__.polluted. When Mongoose later fetches and initializes that document (e.g., via Model.find()), the init function iterates over the document keys and assigns them to the new object, inadvertently setting Object.prototype.polluted [4]. No special authentication or network position is required beyond database write access.

Impact

Successful prototype pollution can affect all objects in the Node.js process, leading to property injection, denial of service, or potentially remote code execution depending on how the application uses polluted properties. The vulnerability is rated with a CVSS score (as per NVD) indicating significant risk [2].

Mitigation

The issue was patched in Mongoose version 7.3.4 by adding a check in the init function to skip keys that are __proto__ or constructor [4]. Users should upgrade to 7.3.4 or later. No official workaround is documented.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
mongoosenpm
>= 7.0.0, < 7.3.37.3.3
mongoosenpm
>= 6.0.0, < 6.11.36.11.3
mongoosenpm
< 5.13.205.13.20

Affected products

3

Patches

3
e29578d2ec18

fix: avoid prototype pollution on init

https://github.com/Automattic/mongooseValeri KarpovJul 9, 2023via ghsa
2 files changed · +22 0
  • lib/document.js+4 0 modified
    @@ -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);
     
    
  • test/document.test.js+18 0 modified
    @@ -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() {
    
f1efabf35052

fix: avoid prototype pollution on init

https://github.com/Automattic/mongooseValeri KarpovJul 9, 2023via ghsa
2 files changed · +24 0
  • lib/document.js+4 0 modified
    @@ -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);
     
    
  • test/document.test.js+20 0 modified
    @@ -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);
    +    });
    +  });
     });
    
305ce4ff7892

fix: avoid prototype pollution on init

https://github.com/Automattic/mongooseValeri KarpovJul 9, 2023via ghsa
2 files changed · +22 0
  • lib/document.js+4 0 modified
    @@ -740,6 +740,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);
     
    
  • test/document.test.js+18 0 modified
    @@ -12278,6 +12278,24 @@ describe('document', function() {
         assert.equal(fromDb.obj.subArr.length, 1);
         assert.equal(fromDb.obj.subArr[0].str, 'subArr.test1');
       });
    +
    +  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() {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.