Prototype Pollution
Description
The set-in npm package before 2.0.3 allows Prototype Pollution via the setIn method due to an incomplete fix of CVE-2020-28273.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
The set-in npm package before 2.0.3 allows Prototype Pollution via the setIn method due to an incomplete fix of CVE-2020-28273.
Vulnerability
The set-in package [4] before version 2.0.3 is vulnerable to Prototype Pollution via the setIn method. The method allows an attacker to merge object prototypes into the target object by passing a path array containing keys such as __proto__, constructor, or prototype. This vulnerability is an incomplete fix of CVE-2020-28273, which only blocked __proto__ and the specific sequence ["constructor", "prototype"] but not individual occurrences of constructor or prototype [1][3].
Exploitation
An attacker can exploit this by providing a crafted path argument to setIn that includes any of the forbidden keys (__proto__, constructor, prototype). For example, calling setIn(obj, ['__proto__', 'polluted'], value) would set Object.prototype.polluted to the given value, polluting all objects. No special privileges are required; the attacker only needs to control the path and value arguments passed to the vulnerable function [2][3].
Impact
Successful exploitation allows an attacker to inject arbitrary properties into the global Object.prototype. This can lead to denial of service (via exceptions), property injection that alters application behavior, and in some contexts, remote code execution if the polluted properties are used in unsafe operations (e.g., dynamic code execution) [2].
Mitigation
Upgrade to set-in version 2.0.3 or later, which includes a comprehensive check in the set function that rejects any key in the set ['__proto__', 'constructor', 'prototype'] [3]. No workaround is available for earlier versions. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of publication.
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 |
|---|---|---|
set-innpm | < 2.0.3 | 2.0.3 |
Affected products
2- set-in/set-indescription
Patches
16bad255961d3better fix for prototype pollution vulnerability
3 files changed · +3359 −27
index.js+9 −12 modified@@ -5,6 +5,10 @@ module.exports = setIn function setIn (object, path, value) { assert.equal(typeof object, 'object', 'setIn: expected object as first argument.') assert.ok(Array.isArray(path), 'setIn: expected array path as second argument.') + assert.ok( + path.every(p => typeof p === 'number' || typeof p === 'string'), + 'setIn: expected array path (of strings and numbers) as second argument.' + ) return recursivelySetIn(object, path, value, 0) } @@ -16,18 +20,6 @@ function recursivelySetIn (object, path, value, index) { object = object || {} - // https://stackoverflow.com/a/60850027 - assert.ok( - path[index] !== '__proto__', - 'setIn: "__proto__" is disallowed in path due to possible prototype pollution attack.' - ) - if (index < path.length - 1) { - assert.ok( - path[index] !== 'constructor' && path[index + 1] !== 'prototype', - 'setIn: ["constructor", "prototype"] is disallowed in path due to possible prototype pollution attack.' - ) - } - var key = path[index] if (key === '-') { @@ -40,7 +32,12 @@ function recursivelySetIn (object, path, value, index) { return set(object, key, next) } +const POLLUTED_KEYS = ['__proto__', 'constructor', 'prototype'] + function set (object, key, value) { + // CVE-2020-28273 + assert.ok(!POLLUTED_KEYS.includes(key), `setIn: ${key} is disallowed in path due to possible prototype pollution attack.`) + object[key] = value return object }
package-lock.json+3344 −13 modifiedtest/index.js+6 −2 modified@@ -178,12 +178,16 @@ test('object with custom get function', function (t) { test('prototype pollution', function (t) { t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['__proto__'], { a: 'x' })) + t.throws(() => setIn({ 'a': { 'b': 'c' }}, [['__proto__']], { a: 'x' })) t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['__proto__', 'a'], 'x')) + t.throws(() => setIn({ 'a': { 'b': 'c' }}, [['__proto__'], 'a'], 'x')) t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['a', '__proto__'], 'x')) + t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['a', ['__proto__']], 'x')) t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['constructor', 'prototype'], { a: 'x' })) t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['constructor', 'prototype', 'a'], 'x')) - setIn({ 'a': { 'b': 'c' }}, ['prototype', 'a'], 'x') - setIn({ 'a': { 'b': 'c' }}, ['constructor'], 'x') + t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['prototype', 'a'], 'x')) + t.throws(() => setIn({ 'a': { 'b': 'c' }}, ['constructor'], 'x')) + t.end() })
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-6956-83fg-5wc5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-25354ghsaADVISORY
- github.com/ahdinosaur/set-in/blob/dfc226d95cce8129de6708661e06e0c2c06f3490/index.js%23L5ghsax_refsource_MISCWEB
- github.com/ahdinosaur/set-in/commit/6bad255961d379e4b1f5fbc52ef9dc8420816f24ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-SETIN-2388571ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.