VYPR
Moderate severityNVD Advisory· Published Aug 27, 2021· Updated Sep 16, 2024

Prototype Pollution

CVE-2021-23434

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].

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.

PackageAffected versionsPatched versions
object-pathnpm
< 0.11.60.11.6

Affected products

2

Patches

1
7bdf4abefd10

Fix prototype pollution when path components are not strings

https://github.com/mariocasciaro/object-pathMario CasciaroAug 27, 2021via ghsa
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

News mentions

0

No linked articles in our index yet.