Prototype Pollution
Description
A type confusion in object-path < 0.11.6 bypasses the prototype pollution fix of CVE-2020-15256 when path components are arrays.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A type confusion in object-path < 0.11.6 bypasses the prototype pollution fix of CVE-2020-15256 when path components are arrays.
Vulnerability
A type confusion vulnerability exists in the object-path JavaScript package before version 0.11.6. When a path component is passed as an array (e.g., ['__proto__'] instead of the string '__proto__'), the strict equality check currentPath === '__proto__' fails because the operands are of different types (array vs string). This allows the protection added in CVE-2020-15256 to be bypassed, enabling prototype pollution through functions like set() when using the inherited props mode (e.g., instances created with includeInheritedProps: true or the withInheritedProps default instance) [1][2][3].
Exploitation
An attacker must be able to supply crafted path arguments to an object-path instance operating in inherited props mode. The attack involves passing an array containing '__proto__' (e.g., [['__proto__'], 'property', 'value']) as the path to functions such as set(), del(), empty(), push(), or insert(). The developer must have explicitly opted into the inherited props mode, as the default objectPath instance is not vulnerable in versions >= 0.11.0 [2][3].
Impact
Successful exploitation results in prototype pollution, where properties can be injected into Object.prototype. This can lead to denial of service (e.g., triggering JavaScript exceptions), tampering with application logic, and potentially remote code execution depending on how the polluted properties are used by the application [4].
Mitigation
Upgrade to object-path version 0.11.6 or later. Version 0.11.6 specifically fixes the array-based bypass of the CVE-2020-15256 patch [2][3]. Subsequent versions (0.11.8) also extend the fix to additional functions and throw exceptions when magic properties are accessed via get() [2][3]. If upgrading is not immediately possible, avoid using the inherited props mode (e.g., do not pass includeInheritedProps: true or use the withInheritedProps instance) [2][3].
- NVD - CVE-2021-23434
- GitHub - mariocasciaro/object-path: A tiny JavaScript utility to access deep properties using a path (for Node and the Browser)
- GitHub - mariocasciaro/object-path: A tiny JavaScript utility to access deep properties using a path (for Node and the Browser)
- Snyk Vulnerability Database | Snyk
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 |
|---|---|---|
object-pathnpm | < 0.11.6 | 0.11.6 |
Affected products
2- object-path/object-pathdescription
Patches
17bdf4abefd10Fix prototype pollution when path components are not strings
2 files changed · +19 −2
index.js+3 −0 modified@@ -111,6 +111,9 @@ return set(obj, path.split('.').map(getKey), value, doNotReplace); } var currentPath = path[0]; + if (typeof currentPath !== 'string' && typeof currentPath !== 'number') { + currentPath = String(currentPath) + } var currentValue = getShallowProperty(obj, currentPath); if (options.includeInheritedProps && (currentPath === '__proto__' || (currentPath === 'constructor' && typeof currentValue === 'function'))) {
test.js+16 −2 modified@@ -241,12 +241,18 @@ describe('set', function () { objectPath.set({}, '__proto__.injected', 'this is bad') expect(Object.prototype.injected).to.be.undefined + objectPath.set({}, [['__proto__'], 'injected'], 'this is bad') + expect(Object.prototype.injected).to.be.undefined + function Clazz() {} Clazz.prototype.test = 'original' objectPath.set(new Clazz(), '__proto__.test', 'this is bad') expect(Clazz.prototype.test).to.be.equal('original') + objectPath.set(new Clazz(), [['__proto__'], 'test'], 'this is bad') + expect(Clazz.prototype.test).to.be.equal('original') + objectPath.set(new Clazz(), 'constructor.prototype.test', 'this is bad') expect(Clazz.prototype.test).to.be.equal('original') }) @@ -256,6 +262,11 @@ describe('set', function () { .to.throw('For security reasons') expect(Object.prototype.injected).to.be.undefined + expect(function() { + objectPath.withInheritedProps.set({}, [['__proto__'], 'injected'], 'this is bad') + expect(Object.prototype.injected).to.be.undefined + }).to.throw('For security reasons') + function Clazz() {} Clazz.prototype.test = 'original' @@ -267,8 +278,11 @@ describe('set', function () { .to.throw('For security reasons') expect(Clazz.prototype.test).to.be.equal('original') - const obj = {} - expect(function() {objectPath.withInheritedProps.set(obj, 'constructor.prototype.injected', 'this is OK')}) + expect(function() {objectPath.withInheritedProps.set({}, 'constructor.prototype.injected', 'this is OK')}) + .to.throw('For security reasons') + expect(Object.prototype.injected).to.be.undefined + + expect(function() {objectPath.withInheritedProps.set({}, [['constructor'], 'prototype', 'injected'], 'this is bad')}) .to.throw('For security reasons') expect(Object.prototype.injected).to.be.undefined })
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-v39p-96qg-c8rfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-23434ghsaADVISORY
- github.com/mariocasciaro/object-path/commit/7bdf4abefd102d16c163d633e8994ef154cab9ebghsaWEB
- lists.debian.org/debian-lts-announce/2023/01/msg00031.htmlghsamailing-listWEB
- snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1570423ghsaWEB
- snyk.io/vuln/SNYK-JS-OBJECTPATH-1569453ghsaWEB
News mentions
0No linked articles in our index yet.