VYPR
Moderate severityOSV Advisory· Published Apr 6, 2020· Updated Aug 4, 2024

CVE-2020-7639

CVE-2020-7639

Description

eivindfjeldstad-dot below 1.0.3 is vulnerable to Prototype Pollution.The function 'set' could be tricked into adding or modifying properties of 'Object.prototype' using a '__proto__' payload.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@eivifj/dotnpm
< 1.0.31.0.3

Affected products

1

Patches

1
774e4b0c97ca

Prevent prototype pollution

https://github.com/eivindfjeldstad/dotEivind FjeldstadFeb 22, 2020via ghsa
3 files changed · +65 12
  • index.js+31 5 modified
    @@ -8,18 +8,21 @@
      * @api public
      */
     
    -exports.set = function (obj, path, val) {
    +exports.set = function(obj, path, val) {
       var segs = path.split('.');
       var attr = segs.pop();
       var src = obj;
     
       for (var i = 0; i < segs.length; i++) {
         var seg = segs[i];
    +    if (!isSafe(obj, seg)) return src;
         obj[seg] = obj[seg] || {};
         obj = obj[seg];
       }
     
    -  obj[attr] = val;
    +  if (isSafe(obj, attr)) {
    +    obj[attr] = val;
    +  }
     
       return src;
     };
    @@ -33,7 +36,7 @@ exports.set = function (obj, path, val) {
      * @api public
      */
     
    -exports.get = function (obj, path) {
    +exports.get = function(obj, path) {
       var segs = path.split('.');
       var attr = segs.pop();
     
    @@ -55,19 +58,42 @@ exports.get = function (obj, path) {
      * @api public
      */
     
    -exports.delete = function (obj, path) {
    +exports.delete = function(obj, path) {
       var segs = path.split('.');
       var attr = segs.pop();
     
       for (var i = 0; i < segs.length; i++) {
         var seg = segs[i];
         if (!obj[seg]) return;
    +    if (!isSafe(obj, seg)) return;
         obj = obj[seg];
       }
     
    +  if (!isSafe(obj, attr)) return;
    +
       if (Array.isArray(obj)) {
    -    obj.splice(path, 1);
    +    obj.splice(attr, 1);
       } else {
         delete obj[attr];
       }
     };
    +
    +function isSafe(obj, prop) {
    +  if (isObject(obj)) {
    +    return obj[prop] === undefined || hasOwnProperty(obj, prop);
    +  }
    +
    +  if (Array.isArray(obj)) {
    +    return !isNaN(parseInt(prop, 10));
    +  }
    +
    +  return false;
    +}
    +
    +function hasOwnProperty(obj, prop) {
    +  return Object.prototype.hasOwnProperty.call(obj, prop);
    +}
    +
    +function isObject(obj) {
    +  return Object.prototype.toString.call(obj) === '[object Object]';
    +}
    
  • package.json+1 1 modified
    @@ -3,7 +3,7 @@
       "publishConfig": {
         "access": "public"
       },
    -  "version": "1.0.2",
    +  "version": "1.0.3",
       "description": "Get and set object properties with dot notation",
       "main": "index.js",
       "scripts": {
    
  • test/index.js+33 6 modified
    @@ -1,33 +1,60 @@
     var assert = require('assert');
     var dot = require('..');
     
    -var tests = module.exports = {
    -  'test set': function () {
    +var tests = (module.exports = {
    +  'test set': function() {
         var obj = {};
         var ret = dot.set(obj, 'cool.aid', 'rocks');
         assert(obj.cool.aid === 'rocks');
         assert(obj === ret);
       },
     
    -  'test get': function () {
    +  'test get': function() {
         var obj = {};
         obj.cool = {};
         obj.cool.aid = 'rocks';
         var value = dot.get(obj, 'cool.aid');
         assert(value === 'rocks');
       },
     
    -  'test delete': function () {
    +  'test delete': function() {
         var obj = {};
         obj.cool = {};
         obj.cool.aid = 'rocks';
         obj.cool.hello = ['world'];
         dot.delete(obj, 'cool.aid');
         dot.delete(obj, 'cool.hello.0');
    -    assert(!obj.cool.hasOwnProperty('aid'))
    +    assert(!obj.cool.hasOwnProperty('aid'));
         assert(obj.cool.hello.length == 0);
    +  },
    +
    +  'test prototype pollution': function() {
    +    var obj = {};
    +    obj.cool = {};
    +    obj.cool.aid = 'rocks';
    +    obj.cool.hello = ['world'];
    +    dot.set(obj, '__proto__', 'test');
    +    dot.set(obj, '__proto__.toString', 'test');
    +    dot.set(obj, 'toString', 'test');
    +    dot.set(obj, 'cool.hello.__proto__', 'test');
    +    dot.set(obj, 'cool.hello.__proto__.toString', 'test');
    +    dot.set(obj, 'cool.hello.toString', 'test');
    +    assert(obj.__proto__ === {}.__proto__);
    +    assert(obj.toString === Object.prototype.toString);
    +    assert(obj.cool.hello.__proto__ === [].__proto__);
    +    assert(obj.cool.hello.toString === Array.prototype.toString);
    +    dot.delete(obj, '__proto__.toString', 'test');
    +    dot.delete(obj, '__proto__', 'test');
    +    dot.delete(obj, 'toString', 'test');
    +    dot.delete(obj, 'cool.hello.__proto__.toString', 'test');
    +    dot.delete(obj, 'cool.hello.__proto__', 'test');
    +    dot.delete(obj, 'cool.hello.toString', 'test');
    +    assert(obj.__proto__ === {}.__proto__);
    +    assert(obj.toString === Object.prototype.toString);
    +    assert(obj.cool.hello.__proto__ === [].__proto__);
    +    assert(obj.cool.hello.toString === Array.prototype.toString);
       }
    -}
    +});
     
     for (var t in tests) {
       tests[t]();
    

Vulnerability mechanics

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

References

4

News mentions

0

No linked articles in our index yet.