# Prototype pollution attack (lodash)

lodash zipObjectDeep (and merge/mergeWith/defaultsDeep) allows prototype pollution via __proto__ keys, letting attackers inject properties onto Object.prototype.

- Payout: hidden
- Severity: high
- Program: Node.js third-party modules
- Found by: posix
- Disclosed: 2020-04-27
- CVE: CVE-2020-8203
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/712065
- Library page: https://bugbountylibrary.com/r/h1%3A712065
- Tags: area:oss domain:oss impact:dos impact:rce kind:bounty platform:hackerone sev:high tech:nodejs technique:source-review vuln:prototype-pollution

**Target:** lodash npm module (zipObjectDeep/merge/mergeWith/defaultsDeep)
**Root cause:** Deep-path setters in zipObjectDeep, merge, mergeWith, and defaultsDeep do not block __proto__ keys, so crafted paths write onto Object.prototype.
**Steps:**
1. Install lodash 4.17.15.
2. Run `const _ = require('lodash'); _.zipObjectDeep(['__proto__.z'],[123])`.
3. Observe `console.log(z)` prints `123`, confirming Object.prototype.z was set.
**How found:** Noticed zipObjectDeep shares the deep-path assignment logic with merge/mergeWith/defaultsDeep (referencing prior report 380873) and tested a __proto__ path.
**Exploitation:** Attacker supplies a crafted object/path to a lodash deep-merge or zipObjectDeep call reachable from user input, polluting Object.prototype with attacker-controlled properties that then appear on all objects, potentially crashing the server or enabling further impact such as RCE.
**Insight:** Audit every lodash deep-path setter (zipObjectDeep, set, merge, mergeWith, defaultsDeep) for __proto__/constructor.prototype keys, not just the well-known merge sink.

