Prototype pollution
Prototype pollution is a vulnerability where an attacker is able to inject properties into the top level JavaScript prototype. This basically adds an attacker defined property to all JavaScript objects. While this might seem unimportant, the impacts of this are quite severe.
What is prototype pollution?
In JavaScripts, inheritance is implemented via prototypes. Each object has a __proto__ property that is another object. The object inherits all properties in its __proto__. In JS, almost all objects are subclasses of Object, thus share its prototype. This means that if we set a value on a.__proto__ it will most likely affect other objects as well. Here's an example:
a = {name: "jro"}
b = {name: "sus"}
b.__proto__.sus = "yes"
console.log(a.sus)
// => yesHowever, prototype pollution is unable to overwrite existing properties:
a = {name: "jro", sus:"no"}
b = {name: "sus"}
b.__proto__.sus = "yes"
console.log(a.sus)
// => noImpacts of prototype pollution
While prototype pollution might be viewed as a low severity vulnerability, the right conditions can enable prototype pollution to have severe impacts.
Authentication bypass
Consider this code:
a = {name: "jro"}
b = {name: "sus"}
b.__proto__.admin = true
console.log(a.admin)
// truePrototype pollution can also occur on the client side
RCE
When prototype pollution occurs in server side code and a templating engine is used, an attacker is often able to set internal properties in the templating engine, resulting in RCE.
See gunship.
Identifying prototype pollution
Libraries such as certain versions of lodash and the flat library perform unsafe object unpacking that enable prototype pollution. Suspiciously written code that assigns arbitrary values to arbitrary properties could be indicative of prototype pollution.