Prototype Pollution
Description
Prototype Pollution in doc-path before 2.1.2 allows attackers to modify object prototypes, potentially leading to denial of service or remote code execution.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Prototype Pollution in doc-path before 2.1.2 allows attackers to modify object prototypes, potentially leading to denial of service or remote code execution.
What the vulnerability is
The vulnerability, tracked as CVE-2020-7772, affects the doc-path JavaScript library before version 2.1.2. The issue is a Prototype Pollution flaw [1][3]. The setPath function in path.js did not properly sanitize key paths that start with __proto__ or constructor, allowing an attacker to inject properties into Object.prototype [2][3]. The commit that fixes the issue explicitly adds a check: if (keyPath.startsWith('__proto__') || keyPath.startsWith('constructor')) { return document; } [2].
How it is exploited
Attackers can exploit this vulnerability by providing a crafted keyPath argument to the setPath function that targets __proto__ or constructor [2][3]. Since prior to the patch these paths were not blocked, the function would traverse the prototype chain and set properties on Object.prototype. The Snyk advisory notes that such prototype pollution typically occurs through "Property definition by path" or unsafe recursive merges [3]. No authentication or special privileges are required if the application accepts user-controlled path inputs.
Impact
Successful exploitation allows an attacker to pollute the base Object prototype in the JavaScript runtime. This can lead to denial of service (by triggering JavaScript exceptions) or remote code execution (by forcing the application into a malicious code path) [3]. Because Object.prototype is shared by all objects, the pollution can affect the entire application.
Mitigation
The vulnerability has been patched in version 2.1.2 [2]. Users should upgrade to this version or later. No workarounds are available; the fix adds input validation to reject prototype-polluting keys [2].
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.
| Package | Affected versions | Patched versions |
|---|---|---|
doc-pathnpm | < 2.1.2 | 2.1.2 |
Affected products
2- doc-path/doc-pathdescription
Patches
13e2bb168cf30Fix issue presented in #14
5 files changed · +32 −15
package.json+2 −2 modified@@ -2,7 +2,7 @@ "author": "mrodrig", "name": "doc-path", "description": "A document path library for Node", - "version": "2.1.1", + "version": "2.1.2", "repository": { "type": "git", "url": "http://github.com/mrodrig/doc-path.git" @@ -37,7 +37,7 @@ "should": "13.2.3" }, "engines": { - "node": ">=6.0" + "node": ">=10" }, "license": "MIT" }
package-lock.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "doc-path", - "version": "2.1.1", + "version": "2.1.2", "lockfileVersion": 1, "requires": true, "dependencies": {
src/path.js+19 −8 modified@@ -30,29 +30,40 @@ function evaluatePath(document, keyPath) { } function setPath(document, keyPath, value) { + if (!document) { + throw new Error('No document was provided.'); + } else if (!keyPath) { + throw new Error('No keyPath was provided.'); + } + + // If this is clearly a prototype pollution attempt, then refuse to modify the path + if (keyPath.startsWith('__proto__') || keyPath.startsWith('constructor')) { + return document; + } + + return _setPath(document, keyPath, value); +} + +function _setPath(document, keyPath, value) { if (!document) { throw new Error('No document was provided.'); } let {indexOfDot, currentKey, remainingKeyPath} = computeStateInformation(keyPath); - // if (currentKey === '__proto__' || currentKey === 'prototype' && Object.prototype.hasOwnProperty.call(document, currentKey)) { - if (currentKey === '__proto__') { - // Refuse to modify anything on __proto__, return the document - return document; - } else if (indexOfDot >= 0) { + if (indexOfDot >= 0) { // If there is a '.' in the keyPath, recur on the subdoc and ... if (!document[currentKey] && Array.isArray(document)) { // If this is an array and there are multiple levels of keys to iterate over, recur. - return document.forEach((doc) => setPath(doc, keyPath, value)); + return document.forEach((doc) => _setPath(doc, keyPath, value)); } else if (!document[currentKey]) { // If the currentKey doesn't exist yet, populate it document[currentKey] = {}; } - setPath(document[currentKey], remainingKeyPath, value); + _setPath(document[currentKey], remainingKeyPath, value); } else if (Array.isArray(document)) { // If this "document" is actually an array, then we can loop over each of the values and set the path - return document.forEach((doc) => setPath(doc, remainingKeyPath, value)); + return document.forEach((doc) => _setPath(doc, remainingKeyPath, value)); } else { // Otherwise, we can set the path directly document[keyPath] = value;
test/tests.js+10 −1 modified@@ -218,11 +218,20 @@ describe('doc-path Module', function() { it('should protect against prototype pollution via __proto__', (done) => { doc = {}; - path.setPath(doc, '__proto__.polluted', 'yes'); + path.setPath(doc, '__proto__.polluted', 'prototype-polluted'); assert.equal(doc.__proto__.polluted, undefined); assert.equal(doc.polluted, undefined); assert.equal({}.polluted, undefined); done(); }); + + it('should protect against prototype pollution via constructor', (done) => { + doc = {}; + path.setPath(doc, 'constructor', 'prototype-polluted'); + assert.equal(doc.constructor, Object); + path.setPath(doc, 'constructor.prototype.test', 'prototype-polluted'); + assert.equal(doc.test, undefined); + done(); + }); }); });
.travis.yml+0 −3 modified@@ -5,10 +5,7 @@ language: node_js node_js: - "14" - "12" - - "11" - "10" - - "9" - - "8" sudo: false before_script: - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-gm8g-xhh8-rmwrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-7772ghsaADVISORY
- github.com/mrodrig/doc-path/blob/stable/src/path.js%23L54ghsax_refsource_MISCWEB
- github.com/mrodrig/doc-path/commit/3e2bb168cf303bffcd7fae5f8d05e5300c1541c7ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-DOCPATH-1011952ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.