{"id":"CVE-2026-125119","kind":"vulnerability","aliases":["CVE-2026-125119","GHSA-gg4r-jv3p-qx3c"],"related":[],"title":"Mongoose: Connection-level sanitizeFilter not applied","description":"### Summary\n\nsanitizeFilter 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.\n\n### Details\n\n`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.\n\n### Proof of concept\n\n```javascript\nimport mongoose from 'mongoose'\n\nconst conn = await mongoose.createConnection('<MONGODB_URI>', { sanitizeFilter: true }).asPromise()\nconst User = conn.model('User', new mongoose.Schema({\n  username: String,\n  password: String,\n  marker: String\n}))\n\nawait User.create({\n  username: 'victim',\n  password: 'correct-password',\n  marker: 'PROTECTED_RECORD'\n})\n\nconst filter = { username: 'victim', password: { $ne: null } }\nconsole.log(conn.get('sanitizeFilter'))\nconsole.log((await User.findOne(filter).lean()).marker)\n```\n\nA control query with a literal wrong password returned no document in the same run, confirming the filter is otherwise enforced.\n\n### Impact\n\nConnection-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.","summary":"Mongoose's sanitizeFilter option, set when creating a connection, is reported as enabled but never applied to query filters. An attacker who sends an object such as { $ne: null } as a password can match the record without knowing the value and read the account data.","severity":"high","cvss":7.5,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"mongoose","fixed":["6.13.12"],"affected":">= 6.0.0, < 6.13.12","ecosystem":"npm"},{"name":"mongoose","fixed":["7.8.13"],"affected":">= 7.0.0, < 7.8.13","ecosystem":"npm"},{"name":"mongoose","fixed":["8.24.7"],"affected":">= 8.0.0, < 8.24.7","ecosystem":"npm"},{"name":"mongoose","fixed":["9.11.4"],"affected":">= 9.0.0, < 9.11.4","ecosystem":"npm"}],"ecosystems":["npm"],"tags":["cwe-943","express","mongodb","mongoose","node","package"],"not_affected_if":["global-sanitizefilter","no-user-controlled-filters","per-query-sanitizefilter"],"how_to_check":"- Check the installed version: `npm ls mongoose`\n- Search code for `sanitizeFilter` passed to `mongoose.connect()` or `createConnection()` rather than `mongoose.set('sanitizeFilter')` or `.sanitizeFilter()` on queries\n- Check whether user-supplied request bodies or query strings are passed directly into filter objects","fix":"- mongoose 6.x: `6.13.12`\n- mongoose 7.x: `7.8.13`\n- mongoose 8.x: `8.24.7`\n- mongoose 9.x: `9.11.4`","status":"open","published_at":"2026-11-09T23:17:22+00:00","first_seen_at":"2026-11-10T20:00:16+00:00","triaged_at":"2026-11-10T20:02:00+00:00","updated_at":"2026-11-10T20:15:32+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-11-10T20:02:00Z","model":"claude-haiku-5-5","output":{"fix":"- mongoose 6.x: `6.13.12`\n- mongoose 7.x: `7.8.13`\n- mongoose 8.x: `8.24.7`\n- mongoose 9.x: `9.11.4`","reach":"internet","title":"Mongoose: connection-level sanitizeFilter setting silently ignored in queries","impact":"medium","summary":"Mongoose's sanitizeFilter option, set when creating a connection, is reported as enabled but never applied to query filters. An attacker who sends an object such as { $ne: null } as a password can match the record without knowing the value and read the account data.","audience":"developers","category":"package","nicknames":[],"who_cares":["mongoose","node","mongodb","express"],"confidence":0.85,"fix_status":"available","needs_auth":"no","worst_case":"Attacker bypasses password check and reads account records","analyst_note":"","how_to_check":"- Check the installed version: `npm ls mongoose`\n- Search code for `sanitizeFilter` passed to `mongoose.connect()` or `createConnection()` rather than `mongoose.set('sanitizeFilter')` or `.sanitizeFilter()` on queries\n- Check whether user-supplied request bodies or query strings are passed directly into filter objects","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["global-sanitizeFilter","per-query-sanitizeFilter","no-user-controlled-filters"],"who_is_affected":"Applications that use the Mongoose ODM with MongoDB and turn on sanitizeFilter in the connection options rather than globally or per query. Affected only when attacker-controlled objects reach filter values. Applications that set sanitizeFilter globally with mongoose.set or per query with .sanitizeFilter() are not affected.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000886,"input_tokens":5523,"output_tokens":667,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-125119':10A,18A '-2026':9A,17A '-2423':184C '-272':169C '-943':24B '2413':183C '270':168C '6.0.0':218C '9.11.2':226C 'account':73B,158C 'affect':329C,347C 'appli':7A,45B,121C 'applic':124C 'aspromis':241C 'attack':50B,137C 'attacker-control':136C 'await':237C,254C,276C 'castcondit':180C 'check':185C 'concept':229C 'config':319C 'confirm':296C 'conn':236C 'conn.get':273C 'conn.model':244C 'connect':3A,38B,104C,113C,130C,207C,304C,317C 'connection-level':2A,129C,303C,316C 'connection.config':173C,198C 'connection.options':186C 'console.log':272C,275C 'const':235C,242C,265C 'control':138C,282C 'correct':260C 'correct-password':259C 'creat':36B 'createcli':165C 'createconnect':108C 'cve':8A,16A 'cwe':23B 'data':74B 'defend':323C 'defens':200C 'delet':175C 'detail':163C 'document':291C 'enabl':42B,117C 'enforc':301C 'eq':95C 'even':205C 'exist':77C 'express':25B 'filter':48B,92C,142C,266C,278C,298C 'get':208C 'gg4r':13A 'ghsa':12A 'ghsa-gg4r-jv3p-qx3c':11A 'global':188C,334C 'impact':302C 'import':231C 'inject':82C,148C,327C 'introduc':215C 'javascript':230C 'jv3p':14A 'know':67B 'lean':279C 'level':4A,131C,305C,318C 'lib/drivers/node-mongodb-native/connection.js':167C 'lib/query.js':182C 'liter':100C,286C 'marker':252C,262C,280C 'match':63B,99C 'mismatch':222C 'model.find':343C 'mongodb':26B 'mongoos':1A,27B,30B,217C,232C,234C 'mongoose':19A,20A,21A,22A 'mongoose.connect':106C 'mongoose.createconnection':238C 'mongoose.schema':247C 'mongoose.set':336C 'move':170C 'nativeconnect':164C 'ne':57B,89C,154C,270C 'never':44B,120C,197C 'new':246C 'node':28B 'null':58B,90C,155C,271C 'object':54B,86C,139C 'open':145C 'oper':85C 'option':33B,132C,178C,189C,195C,307C 'options.sanitizefilter':171C 'origin':177C 'otherwis':300C 'packag':29B 'pass':134C 'password':61B,151C,162C,250C,258C,261C,269C,288C 'per':193C 'per-queri':192C 'present':224C 'proof':227C 'protect':263C 'queri':47B,80C,119C,179C,194C,283C,325C,341C 'qx3c':15A 'read':71B 'record':65B,159C,264C 'reli':126C,314C 'remain':144C 'report':40B,114C 'respect':310C 'return':156C,210C,289C 'run':204C,295C 'sanitizefilt':5A,32B,76C,110C,209C,239C,274C,306C,321C,333C,337C,344C 'selector':81C,147C,326C 'send':52B 'set':34B,101C,332C 'specif':340C 'stop':79C 'storag':213C 'string':249C,251C,253C 'summari':75C 'therefor':143C,201C 'though':206C 'true':111C,211C,240C 'uri':109C 'use':335C,342C 'user':243C,245C,312C,330C 'user.create':255C 'user.findone':277C 'usernam':248C,256C,267C 'valu':69B,93C,152C 'victim':257C,268C 'without':66B,160C 'wrap':84C 'wrong':287C","nicknames":[],"mitigations":[],"who_affected":"Applications that use the Mongoose ODM with MongoDB and turn on sanitizeFilter in the connection options rather than globally or per query. Affected only when attacker-controlled objects reach filter values. Applications that set sanitizeFilter globally with mongoose.set or per query with .sanitizeFilter() are not affected.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["mongoose"],"ptokens":["mongoose"],"labels":["cwe943","express","high","mongodb","mongoose","node","npm","package"],"campaign_type":null,"search_a":"'-125119':10A,18A '-2026':9A,17A 'appli':7A 'connect':3A 'connection-level':2A 'cve':8A,16A 'gg4r':13A 'ghsa':12A 'ghsa-gg4r-jv3p-qx3c':11A 'jv3p':14A 'level':4A 'mongoos':1A 'mongoose':19A,20A,21A,22A 'qx3c':15A 'sanitizefilt':5A","search_b":"'-943':24B 'account':73B 'appli':45B 'attack':50B 'connect':38B 'creat':36B 'cwe':23B 'data':74B 'enabl':42B 'express':25B 'filter':48B 'know':67B 'match':63B 'mongodb':26B 'mongoos':27B,30B 'ne':57B 'never':44B 'node':28B 'null':58B 'object':54B 'option':33B 'packag':29B 'password':61B 'queri':47B 'read':71B 'record':65B 'report':40B 'sanitizefilt':32B 'send':52B 'set':34B 'valu':69B 'without':66B","search_c":"'-2423':184C '-272':169C '2413':183C '270':168C '6.0.0':218C '9.11.2':226C 'account':158C 'affect':329C,347C 'appli':121C 'applic':124C 'aspromis':241C 'attack':137C 'attacker-control':136C 'await':237C,254C,276C 'castcondit':180C 'check':185C 'concept':229C 'config':319C 'confirm':296C 'conn':236C 'conn.get':273C 'conn.model':244C 'connect':104C,113C,130C,207C,304C,317C 'connection-level':129C,303C,316C 'connection.config':173C,198C 'connection.options':186C 'console.log':272C,275C 'const':235C,242C,265C 'control':138C,282C 'correct':260C 'correct-password':259C 'createcli':165C 'createconnect':108C 'defend':323C 'defens':200C 'delet':175C 'detail':163C 'document':291C 'enabl':117C 'enforc':301C 'eq':95C 'even':205C 'exist':77C 'filter':92C,142C,266C,278C,298C 'get':208C 'global':188C,334C 'impact':302C 'import':231C 'inject':82C,148C,327C 'introduc':215C 'javascript':230C 'lean':279C 'level':131C,305C,318C 'lib/drivers/node-mongodb-native/connection.js':167C 'lib/query.js':182C 'liter':100C,286C 'marker':252C,262C,280C 'match':99C 'mismatch':222C 'model.find':343C 'mongoos':217C,232C,234C 'mongoose.connect':106C 'mongoose.createconnection':238C 'mongoose.schema':247C 'mongoose.set':336C 'move':170C 'nativeconnect':164C 'ne':89C,154C,270C 'never':120C,197C 'new':246C 'null':90C,155C,271C 'object':86C,139C 'open':145C 'oper':85C 'option':132C,178C,189C,195C,307C 'options.sanitizefilter':171C 'origin':177C 'otherwis':300C 'pass':134C 'password':151C,162C,250C,258C,261C,269C,288C 'per':193C 'per-queri':192C 'present':224C 'proof':227C 'protect':263C 'queri':80C,119C,179C,194C,283C,325C,341C 'record':159C,264C 'reli':126C,314C 'remain':144C 'report':114C 'respect':310C 'return':156C,210C,289C 'run':204C,295C 'sanitizefilt':76C,110C,209C,239C,274C,306C,321C,333C,337C,344C 'selector':81C,147C,326C 'set':101C,332C 'specif':340C 'stop':79C 'storag':213C 'string':249C,251C,253C 'summari':75C 'therefor':143C,201C 'though':206C 'true':111C,211C,240C 'uri':109C 'use':335C,342C 'user':243C,245C,312C,330C 'user.create':255C 'user.findone':277C 'usernam':248C,256C,267C 'valu':93C,152C 'victim':257C,268C 'without':160C 'wrap':84C 'wrong':287C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-02T19:29:03+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-gg4r-jv3p-qx3c","url":"https://github.com/advisories/GHSA-gg4r-jv3p-qx3c","severity":"high","published_at":"2026-11-10T19:56:12+00:00","modified_at":"2026-11-10T19:56:12+00:00","first_seen_at":"2026-11-10T20:00:16+00:00","fetched_at":"2026-11-10T20:56:29+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-125119","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-125119","severity":null,"published_at":"2026-11-09T23:17:22+00:00","modified_at":"2026-11-09T23:17:22+00:00","first_seen_at":"2026-11-10T20:15:32+00:00","fetched_at":"2026-11-10T20:15:32+00:00","note":null}],"documents":[{"id":117728,"url":"https://api.github.com/repos/Automattic/mongoose/security-advisories/GHSA-gg4r-jv3p-qx3c","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":117729,"url":"https://github.com/Automattic/mongoose/security/advisories/GHSA-gg4r-jv3p-qx3c","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-11-02T19:29:03+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":117730,"url":"https://github.com/Automattic/mongoose/commit/4bb659478be2f30655a7bdd78bc251bdf111cd29","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":117731,"url":"https://github.com/Automattic/mongoose/commit/4f4f9a79f860786a54133bee2c9af967ec691491","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":117732,"url":"https://github.com/Automattic/mongoose/commit/83eda6af1489e9ef60bb8eee8cf9ee005771b9d5","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":117733,"url":"https://github.com/Automattic/mongoose/commit/b8970c25998c23fbccd17f76c0398b902ff4911d","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":117734,"url":"https://github.com/Automattic/mongoose/releases/tag/6.13.12","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"},{"id":117735,"url":"https://github.com/Automattic/mongoose/releases/tag/7.8.13","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"},{"id":117736,"url":"https://github.com/Automattic/mongoose/releases/tag/8.24.7","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"},{"id":117737,"url":"https://github.com/Automattic/mongoose/releases/tag/9.11.4","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}