Prototype Pollution
Description
A type confusion in mpath before 0.8.4 allows bypass of prototype pollution protections, enabling potential remote code execution.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A type confusion in mpath before 0.8.4 allows bypass of prototype pollution protections, enabling potential remote code execution.
Vulnerability
The mpath package before version 0.8.4 contains a type confusion vulnerability that bypasses the fix for CVE-2018-16490. When processing path parts, the condition ignoreProperties.indexOf(parts[i]) !== -1 returns -1 if parts[i] is an array ['__proto__'] because Array.prototype.indexOf() is called instead of String.prototype.indexOf(), allowing __proto__ to be used as a property path [1].
Exploitation
An attacker can provide a crafted path with an array element containing ['__proto__'] to set properties on the prototype chain. The attacker needs the ability to supply path values to mpath.set() or similar functions. No authentication or network position is specified; typically this could be via user input in a web application using mpath to set object properties [3][4].
Impact
Successful exploitation allows prototype pollution, enabling the attacker to inject properties into the base object prototype. This can lead to denial of service, property tampering, or remote code execution depending on the application context [3][4].
Mitigation
Upgrade to mpath version 0.8.4 or later, which fixes the type confusion issue. The fix was released on 2021-09-01. For applications using the package via npm, update to the latest version. No workaround is available [1][2].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
mpathnpm | < 0.8.4 | 0.8.4 |
Affected products
2- mpath/mpathdescription
Patches
289402d2880d4fix: throw error if `parts` contains an element that isn't a string or number
1 file changed · +12 −0
lib/index.js+12 −0 modified@@ -64,6 +64,9 @@ exports.get = function(path, o, special, map) { for (var i = 0; i < parts.length; ++i) { part = parts[i]; + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `get()` must be a string or number, got ' + typeof parts[i]); + } if (Array.isArray(obj) && !/^\d+$/.test(part)) { // reading a property from the array items @@ -112,6 +115,9 @@ exports.has = function(path, o) { var len = parts.length; var cur = o; for (var i = 0; i < len; ++i) { + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `has()` must be a string or number, got ' + typeof parts[i]); + } if (cur == null || typeof cur !== 'object' || !(parts[i] in cur)) { return false; } @@ -143,6 +149,9 @@ exports.unset = function(path, o) { if (cur == null || typeof cur !== 'object' || !(parts[i] in cur)) { return false; } + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `unset()` must be a string or number, got ' + typeof parts[i]); + } // Disallow any updates to __proto__ or special properties. if (ignoreProperties.indexOf(parts[i]) !== -1) { return false; @@ -193,6 +202,9 @@ exports.set = function(path, val, o, special, map, _copying) { if (null == o) return; for (var i = 0; i < parts.length; ++i) { + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `set()` must be a string or number, got ' + typeof parts[i]); + } // Silently ignore any updates to `__proto__`, these are potentially // dangerous if using mpath with unsanitized data. if (ignoreProperties.indexOf(parts[i]) !== -1) {
89402d2880d4fix: throw error if `parts` contains an element that isn't a string or number
1 file changed · +12 −0
lib/index.js+12 −0 modified@@ -64,6 +64,9 @@ exports.get = function(path, o, special, map) { for (var i = 0; i < parts.length; ++i) { part = parts[i]; + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `get()` must be a string or number, got ' + typeof parts[i]); + } if (Array.isArray(obj) && !/^\d+$/.test(part)) { // reading a property from the array items @@ -112,6 +115,9 @@ exports.has = function(path, o) { var len = parts.length; var cur = o; for (var i = 0; i < len; ++i) { + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `has()` must be a string or number, got ' + typeof parts[i]); + } if (cur == null || typeof cur !== 'object' || !(parts[i] in cur)) { return false; } @@ -143,6 +149,9 @@ exports.unset = function(path, o) { if (cur == null || typeof cur !== 'object' || !(parts[i] in cur)) { return false; } + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `unset()` must be a string or number, got ' + typeof parts[i]); + } // Disallow any updates to __proto__ or special properties. if (ignoreProperties.indexOf(parts[i]) !== -1) { return false; @@ -193,6 +202,9 @@ exports.set = function(path, val, o, special, map, _copying) { if (null == o) return; for (var i = 0; i < parts.length; ++i) { + if (typeof parts[i] !== 'string' && typeof parts[i] !== 'number') { + throw new TypeError('Each segment of path to `set()` must be a string or number, got ' + typeof parts[i]); + } // Silently ignore any updates to `__proto__`, these are potentially // dangerous if using mpath with unsanitized data. if (ignoreProperties.indexOf(parts[i]) !== -1) {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-p92x-r36w-9395ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-23438ghsaADVISORY
- github.com/aheckmann/mpath/commit/89402d2880d4ea3518480a8c9847c541f2d824fcghsax_refsource_MISCWEB
- github.com/mongoosejs/mpath/commit/89402d2880d4ea3518480a8c9847c541f2d824fcghsaWEB
- snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1579548ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-MPATH-1577289ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.