VYPR
Critical severity9.8OSV Advisory· Published Nov 12, 2020· Updated May 19, 2026

CVE-2020-28271

CVE-2020-28271

Description

Prototype pollution in deephas 1.0.0–1.0.5 allows DoS and possible RCE by setting arbitrary properties on Object.prototype.

AI Insight

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

Prototype pollution in deephas 1.0.0–1.0.5 allows DoS and possible RCE by setting arbitrary properties on Object.prototype.

Vulnerability

Overview

CVE-2020-28271 is a prototype pollution vulnerability in the deephas npm library, affecting versions 1.0.0 through 1.0.5. The add function in the library's source code does not validate whether the input path contains __proto__, allowing an attacker to pollute the prototype of global objects. This is a classic JavaScript prototype pollution bug that can lead to denial of service (DoS) and potentially remote code execution (RCE) [1].

Attack

Vector and Prerequisites

The vulnerability can be triggered by passing a crafted path string (e.g., __proto__.polluted) to the set() or add() functions. No authentication is required, and the attack can be performed over the network. The library does not sanitize the path or check for prototype property modifications, as seen in the patch where a throw is added for __proto__ [2]. An attacker only needs to control the input to one of these functions in any application that uses deephas.

Impact

A successful exploit allows an attacker to set arbitrary properties on Object.prototype, affecting all objects in the runtime. This can lead to unexpected behavior, denial of service (e.g., crashes or infinite loops), and potentially remote code execution if the polluted property is later used in a security-sensitive context (e.g., as a function or property in a template engine). The CVSS v3 score is 9.8, indicating critical severity [1].

Mitigation

The issue was fixed in commit 2fe0117 by adding a check that throws an exception if the path contains __proto__ [2]. Users should update deephas to version 1.0.6 or later. No workarounds are available other than patching. The vulnerability was reported by WhiteSource (now Mend) and is tracked in their vulnerability database [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
deephasnpm
>= 1.0.0, <= 1.0.5

Affected products

2

Patches

1
2fe011713a61

fix vulnerability reported by whitesource software

https://github.com/sharpred/deepHasPaul RyanOct 27, 2020via ghsa
6 files changed · +80 14
  • deepHas.js+17 12 modified
    @@ -8,7 +8,7 @@ var indexFalse,
         set;
     
     function indexer(set) {
    -    return function(obj, i) {
    +    return function (obj, i) {
             "use strict";
             try {
                 if (obj && i && obj.hasOwnProperty(i)) {
    @@ -18,7 +18,7 @@ function indexer(set) {
                     return obj[i];
                 }
                 return;
    -        } catch(ex) {
    +        } catch (ex) {
                 console.error(ex);
                 return;
             }
    @@ -31,15 +31,15 @@ indexFalse = indexer(false);
     function reduce(obj, str) {
         "use strict";
         try {
    -        if ( typeof str !== "string") {
    +        if (typeof str !== "string") {
                 return;
             }
    -        if ( typeof obj !== "object") {
    +        if (typeof obj !== "object") {
                 return;
             }
             return str.split('.').reduce(indexFalse, obj);
     
    -    } catch(ex) {
    +    } catch (ex) {
             console.error(ex);
             return;
         }
    @@ -49,21 +49,26 @@ function reduce(obj, str) {
     function add(obj, str, val) {
         "use strict";
         try {
    -        if ( typeof str !== "string") {
    +        if (typeof str !== "string") {
                 return;
             }
    -        if ( typeof obj !== "object") {
    +        if (str.indexOf('__proto__') != -1) {
    +            throw "cannot modify prototype property";
    +        }
    +        if (typeof obj !== "object") {
                 return;
             }
             if (!val) {
                 return;
             }
             var items = str.split('.');
    +        console.log(str);
             var initial = items.slice(0, items.length - 1);
             var last = items.slice(items.length - 1);
             var test = initial.reduce(indexTrue, obj);
             test[last] = val;
    -    } catch(ex) {
    +
    +    } catch (ex) {
             console.error(ex);
             return;
         }
    @@ -73,11 +78,11 @@ function has(target, path) {
         "use strict";
         try {
             var test = reduce(target, path);
    -        if ( typeof test !== "undefined") {
    +        if (typeof test !== "undefined") {
                 return true;
             }
             return false;
    -    } catch(ex) {
    +    } catch (ex) {
             console.error(ex);
             return;
         }
    @@ -87,7 +92,7 @@ function get(target, path) {
         "use strict";
         try {
             return reduce(target, path);
    -    } catch(ex) {
    +    } catch (ex) {
             console.error(ex);
             return;
         }
    @@ -97,7 +102,7 @@ function set(target, path, val) {
         "use strict";
         try {
             return add(target, path, val);
    -    } catch(ex) {
    +    } catch (ex) {
             console.error(ex);
             return;
         }
    
  • package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "deephas",
    -  "version": "1.0.5",
    +  "version": "1.0.6",
       "description": "get, set or test for a value in a javascript object",
       "main": "deepHas.js",
       "scripts": {
    
  • package-lock.json+45 0 added
    @@ -0,0 +1,45 @@
    +{
    +  "name": "deephas",
    +  "version": "1.0.5",
    +  "lockfileVersion": 1,
    +  "requires": true,
    +  "dependencies": {
    +    "should": {
    +      "version": "8.0.1",
    +      "resolved": "https://registry.npmjs.org/should/-/should-8.0.1.tgz",
    +      "integrity": "sha1-OjpxF9RfKaNnvBKch4owPsHvZAo=",
    +      "dev": true,
    +      "requires": {
    +        "should-equal": "0.5.0",
    +        "should-format": "0.3.1",
    +        "should-type": "0.2.0"
    +      },
    +      "dependencies": {
    +        "should-equal": {
    +          "version": "0.5.0",
    +          "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-0.5.0.tgz",
    +          "integrity": "sha1-x5fxNfMGf+tp6+zbMGscP+IbPm8=",
    +          "dev": true,
    +          "requires": {
    +            "should-type": "0.2.0"
    +          }
    +        },
    +        "should-format": {
    +          "version": "0.3.1",
    +          "resolved": "https://registry.npmjs.org/should-format/-/should-format-0.3.1.tgz",
    +          "integrity": "sha1-LLt4JGFnCs5CkrKx7EaNuM+Z4zA=",
    +          "dev": true,
    +          "requires": {
    +            "should-type": "0.2.0"
    +          }
    +        },
    +        "should-type": {
    +          "version": "0.2.0",
    +          "resolved": "https://registry.npmjs.org/should-type/-/should-type-0.2.0.tgz",
    +          "integrity": "sha1-ZwfvlVKdmJ3MCY/gdTqx+RNrt/Y=",
    +          "dev": true
    +        }
    +      }
    +    }
    +  }
    +}
    
  • poc.js+5 0 added
    @@ -0,0 +1,5 @@
    +var dh = require("./deepHas");
    +var obj = {};
    +console.log(obj.isAdmin);
    +dh.set(obj,'__proto__.isAdmin','true');
    +console.log(obj.isAdmin);
    \ No newline at end of file
    
  • runTests.sh+2 1 modified
    @@ -2,4 +2,5 @@
     node tests/testHas.js
     node tests/testGet.js
     node tests/testExports.js
    -node tests/testSet.js
    \ No newline at end of file
    +node tests/testSet.js
    +node tests/testVulnerability.js
    \ No newline at end of file
    
  • tests/testVulnerability.js+10 0 added
    @@ -0,0 +1,10 @@
    +var dh = require("../deepHas"),
    +    should = require("should"),
    +    obj;
    +
    +obj = {};
    +
    +dh.set(obj,'__proto__.isAdmin',true);
    +
    +should.not.exist(obj.isAdmin);
    +obj.hasOwnProperty('isAdmin').should.equal(false);
    \ No newline at end of file
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.