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.
| Package | Affected versions | Patched versions |
|---|---|---|
@eivifj/dotnpm | < 1.0.3 | 1.0.3 |
Affected products
1- Range: 0.1.0, 0.2.0, 1.0.0, …
Patches
1774e4b0c97caPrevent prototype pollution
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- github.com/advisories/GHSA-wfwq-xc57-fq7vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-7639ghsaADVISORY
- github.com/eivindfjeldstad/dot/commit/774e4b0c97ca35d2ae40df2cd14428d37dd07a0bghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-EIVIFJDOT-564435ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.