VYPR
High severityNVD Advisory· Published Jan 7, 2022· Updated Sep 16, 2024

Prototype Pollution

CVE-2021-23568

Description

The extend2 npm package before 1.0.1 is vulnerable to Prototype Pollution via unsafe recursive merge in the extend function, allowing property injection into Object.prototype.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

The extend2 npm package before 1.0.1 is vulnerable to Prototype Pollution via unsafe recursive merge in the extend function, allowing property injection into Object.prototype.

Vulnerability

The extend2 package version before 1.0.1 is vulnerable to Prototype Pollution through its extend function, which performs an unsafe recursive merge of object properties. The vulnerability exists because the merge logic does not filter out special properties like __proto__ during iteration, allowing an attacker to pollute the base Object.prototype. The affected code path is specifically in the for (name in options) loop within index.js, where properties are copied without checking for __proto__ [2][4]. Versions prior to 1.0.1 are affected, and the fix was applied in commit aa332a59116c8398976434b57ea477c6823054f8 [4] and released in version 1.0.1 [1].

Exploitation

An attacker can exploit this vulnerability by crafting a JavaScript object that contains a __proto__ property defined with Object.defineProperty(). When this malicious object is passed as a source to the vulnerable extend function, the recursive merge will traverse into __proto__, effectively merging properties directly into Object.prototype. This occurs because the merge logic checks if the property exists and is an object on both the target and source, and the __proto__ property passes this check, allowing the recursion to pollute the global prototype [3]. No special network position or authentication is required—only the ability to provide input to the merge function.

Impact

Successful exploitation allows an attacker to inject arbitrary properties into Object.prototype, which are then inherited by all JavaScript objects in the application. This can lead to denial of service (by triggering unexpected exceptions), tampering with application logic to force code execution paths, and in severe cases remote code execution. The attack alters the behavior of all objects sharing the polluted prototype, potentially leading to privilege escalation or data corruption across the entire application [3].

Mitigation

The vulnerability is fixed in extend2 version 1.0.1, released in 2022. The fix adds a guard to skip the __proto__ property during iteration, as seen in the commit [4] (adding if (name === '__proto__') continue;). Users should upgrade to version 1.0.1 or later immediately. No workaround is available for earlier versions. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of the publication date.

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
extend2npm
< 1.0.11.0.1

Affected products

2

Patches

1
aa332a59116c

fix: __proto__ copy (#2)

https://github.com/eggjs/extend2Haoliang GaoDec 31, 2021via ghsa
6 files changed · +65 30
  • appveyor.yml+0 16 removed
    @@ -1,16 +0,0 @@
    -environment:
    -  matrix:
    -    - nodejs_version: '4'
    -    - nodejs_version: '6'
    -    - nodejs_version: '7'
    -
    -install:
    -  - ps: Install-Product node $env:nodejs_version
    -  - npm i npminstall && node_modules\.bin\npminstall
    -
    -test_script:
    -  - node --version
    -  - npm --version
    -  - npm run ci
    -
    -build: off
    
  • .github/workflows/nodejs.yml+46 0 added
    @@ -0,0 +1,46 @@
    +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
    +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
    +
    +name: Node.js CI
    +
    +on:
    +  push:
    +    branches:
    +      - main
    +      - master
    +  pull_request:
    +    branches:
    +      - main
    +      - master
    +  schedule:
    +    - cron: '0 2 * * *'
    +
    +jobs:
    +  build:
    +    runs-on: ${{ matrix.os }}
    +
    +    strategy:
    +      fail-fast: false
    +      matrix:
    +        node-version: [6, 8, 10, 12, 14, 16]
    +        os: [ubuntu-latest, windows-latest, macos-latest]
    +
    +    steps:
    +    - name: Checkout Git Source
    +      uses: actions/checkout@v2
    +
    +    - name: Use Node.js ${{ matrix.node-version }}
    +      uses: actions/setup-node@v1
    +      with:
    +        node-version: ${{ matrix.node-version }}
    +
    +    - name: Install Dependencies
    +      run: npm i -g npminstall@latest-3 && npminstall
    +
    +    - name: Continuous Integration
    +      run: npm run ci
    +
    +    - name: Code Coverage
    +      uses: codecov/codecov-action@v1
    +      with:
    +        token: ${{ secrets.CODECOV_TOKEN }}
    
  • index.js+2 0 modified
    @@ -47,6 +47,8 @@ module.exports = function extend() {
     
         // Extend the base object
         for (name in options) {
    +      if (name === '__proto__') continue;
    +
           src = target[name];
           copy = options[name];
     
    
  • package.json+2 2 modified
    @@ -25,7 +25,6 @@
       "dependencies": {},
       "devDependencies": {
         "covert": "^1.1.0",
    -    "egg-ci": "^1.5.0",
         "eslint": "^3.2.2",
         "eslint-config-egg": "^3.2.0",
         "tape": "^4.6.0"
    @@ -35,6 +34,7 @@
         "index.js"
       ],
       "ci": {
    -    "version": "4, 6, 7"
    +    "type": "github",
    +    "version": "6, 8, 10, 12, 14, 16"
       }
     }
    
  • test/index.js+15 0 modified
    @@ -619,3 +619,18 @@ test('works without Array.isArray', function (t) {
       Array.isArray = savedIsArray;
       t.end();
     });
    +
    +test('fix __proto__ copy', function (t) {
    +  var r = extend(true, {}, JSON.parse('{"__proto__": {"polluted": "yes"}}'));
    +  t.deepEqual(
    +    JSON.stringify(r),
    +    '{}',
    +    'It should not copy __proto__'
    +  );
    +  t.deepEqual(
    +    ''.polluted,
    +    undefined,
    +    'It should not affect object prototype'
    +  );
    +  t.end();
    +});
    
  • .travis.yml+0 12 removed
    @@ -1,12 +0,0 @@
    -sudo: false
    -language: node_js
    -node_js:
    -  - '4'
    -  - '6'
    -  - '7'
    -install:
    -  - npm i npminstall && npminstall
    -script:
    -  - npm run ci
    -after_script:
    -  - npminstall codecov && codecov
    

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.