CVE-2020-7608
Description
yargs-parser could be tricked into adding or modifying properties of Object.prototype using a "__proto__" payload.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
CVE-2020-7608 is a prototype pollution vulnerability in yargs-parser that allows remote code execution via a crafted `__proto__` payload.
CVE-2020-7608 is a prototype pollution vulnerability in the yargs-parser library, a popular command-line argument parser used by thousands of Node.js projects. The bug resides in how the parser handles property keys: it does not properly check for dangerous keys like __proto__, allowing an attacker to inject properties into Object.prototype when parsing crafted input [1][2].
Exploitation
To exploit this, an attacker can supply a --__proto__.polluted=true argument or embed __proto__ in a JSON-like string passed to the parser [1]. Authentication is not required — any application that exposes user-controlled command-line arguments or configuration strings to yargs-parser is at risk. This includes scenarios where server-side scripts process client-supplied arguments indirectly [2][3].
Impact
Successful prototype pollution can lead to denial of service (via exceptions) or, more critically, remote code execution. By polluting Object.prototype with properties that alter the application’s runtime behavior, an attacker may force the code down a malicious path. The vulnerability was assigned CVSSv3 score 9.8 (Critical) because it can be exploited remotely without user interaction [2][3].
Mitigation
The fix was released in yargs-parser version 13.1.2 and 15.0.1 (and later). Users should update to the latest patched version. The GitHub commit [4] and Snyk advisory [3] provide details. No workaround is available for older versions; updating is the only reliable mitigation.
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 |
|---|---|---|
yargs-parsernpm | >= 6.0.0, < 13.1.2 | 13.1.2 |
yargs-parsernpm | >= 14.0.0, < 15.0.1 | 15.0.1 |
yargs-parsernpm | >= 16.0.0, < 18.1.1 | 18.1.1 |
yargs-parsernpm | < 5.0.1 | 5.0.1 |
Affected products
4- yargs-parser/yargs-parserdescription
- ghsa-coords3 versions
>= 6.0.0, < 13.1.2+ 2 more
- (no CPE)range: >= 6.0.0, < 13.1.2
- (no CPE)range: < 1.18.3-1.module_el8.3.0+2023+d2377ea3
- (no CPE)range: < 17-3.module_el8.4.0+2224+b07ac28e
Patches
21c417bd0b42bfix(security): address GHSA-p9pc-299p-vxgp (#362)
1 file changed · +15 −0
.github/workflows/release-please.yml+15 −0 added@@ -0,0 +1,15 @@ +on: + push: + branches: + - v5.x.x +name: release-please +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: google-github-actions/release-please-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + release-type: node + package-name: yargs-parser + default-branch: v5.x.x
63810ca1ae1afix: __proto__ will now be replaced with ___proto___ in parse (#258)
3 files changed · +70 −2
index.js+15 −1 modified@@ -697,6 +697,10 @@ function parse (args, opts) { if (!configuration['dot-notation']) keys = [keys.join('.')] keys.slice(0, -1).forEach(function (key, index) { + // TODO(bcoe): in the next major version of yargs, switch to + // Object.create(null) for dot notation: + key = sanitizeKey(key) + if (typeof o === 'object' && o[key] === undefined) { o[key] = {} } @@ -716,7 +720,10 @@ function parse (args, opts) { } }) - const key = keys[keys.length - 1] + // TODO(bcoe): in the next major version of yargs, switch to + // Object.create(null) for dot notation: + const key = sanitizeKey(keys[keys.length - 1]) + const isTypeArray = checkAllAliases(keys.join('.'), flags.arrays) const isValueArray = Array.isArray(value) let duplicate = configuration['duplicate-arguments-array'] @@ -1001,4 +1008,11 @@ Parser.detailed = function (args, opts) { return parse(args.slice(), opts) } +// TODO(bcoe): in the next major version of yargs, switch to +// Object.create(null) for dot notation: +function sanitizeKey (key) { + if (key === '__proto__') return '___proto___' + return key +} + module.exports = Parser
test/fixtures/config.json+9 −1 modified@@ -4,5 +4,13 @@ "foo": "baz", "version": "1.0.2", "truthy": true, - "toString": "method name" + "toString": "method name", + "__proto__": { + "aaa": 99 + }, + "bar": { + "__proto__": { + "bbb": 100 + } + } }
test/yargs-parser.js+46 −0 modified@@ -727,6 +727,25 @@ describe('yargs-parser', function () { argv.error.message.should.equal('someone set us up the bomb') }) + + it('should not pollute the prototype', function () { + const argv = parser(['--foo', 'bar'], { + alias: { + z: 'zoom' + }, + default: { + settings: jsonPath + }, + config: 'settings' + }) + + argv.should.have.property('herp', 'derp') + argv.should.have.property('zoom', 55) + argv.should.have.property('foo').and.deep.equal('bar') + + expect({}.bbb).to.equal(undefined) + expect({}.aaa).to.equal(undefined) + }) }) describe('config objects', function () { @@ -974,6 +993,13 @@ describe('yargs-parser', function () { argv.f.foo.should.eql(99) argv.f.bar.should.eql(true) }) + + it('should not pollute the prototype', function () { + parser(['-f.__proto__.foo', '99', '-x.y.__proto__.bar', '100', '--__proto__', '200']) + Object.keys({}.__proto__).length.should.equal(0) // eslint-disable-line + expect({}.foo).to.equal(undefined) + expect({}.bar).to.equal(undefined) + }) }) it('should set boolean and alias using explicit true', function () { @@ -3702,4 +3728,24 @@ describe('yargs-parser', function () { argv._.should.eql([101, 102]) }) }) + + it('should replace the key __proto__ with the key ___proto___', function () { + const argv = parser(['-f.__proto__.foo', '99', '-x.y.__proto__.bar', '100', '--__proto__', '200']) + argv.should.eql({ + _: [], + ___proto___: 200, + f: { + ___proto___: { + foo: 99 + } + }, + x: { + y: { + ___proto___: { + bar: 100 + } + } + } + }) + }) })
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-p9pc-299p-vxgpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-7608ghsaADVISORY
- github.com/yargs/yargs-parser/commit/1c417bd0b42b09c475ee881e36d292af4fa2cc36ghsaWEB
- github.com/yargs/yargs-parser/commit/63810ca1ae1a24b08293a4d971e70e058c7a41e2ghsaWEB
- snyk.io/vuln/SNYK-JS-YARGSPARSER-560381ghsax_refsource_MISCWEB
- www.npmjs.com/advisories/1500ghsaWEB
News mentions
0No linked articles in our index yet.