Vulnerability GHSA-gg4r-jv3p-qx3c

High Risk
HIGH RISK
CVSS Score: 7.5
Score Range: 7.0–8.9
High severity vulnerabilities (CVSS 7.0–8.9). Serious vulnerabilities that should be prioritized soon after critical fixes.
9 hours ago
November 10, 2026 at 07:56 PM UTC
Mongoose: Connection-level sanitizeFilter not applied
>=6.0.0 <6.13.12, >=7.0.0 <7.8.13, >=8.0.0 <8.24.7, >=9.0.0 <9.11.4
>=6.0.0 <6.13.12, >=7.0.0 <7.8.13, >=8.0.0 <8.24.7, >=9.0.0 <9.11.4

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

View all vulnerabilities for these packages

Impacted packages

Timeline

Published
9 hours ago
November 10, 2026 at 07:56 PM UTC
Fixed (6.13.12)
18 days ago
October 23, 2026 at 04:24 PM UTC
Fixed (7.8.13)
18 days ago
October 23, 2026 at 04:39 PM UTC
Fixed (8.24.7)
18 days ago
October 23, 2026 at 04:54 PM UTC
Fixed (9.11.4)
18 days ago
October 23, 2026 at 05:05 PM UTC
Last Modified
9 hours ago
November 10, 2026 at 08:00 PM UTC