# Prototype Pollution

## Javascript

JavaScript is the most popular programming language for the web. It makes websites interactive by adding features like form checks, animations, pop-ups, and dynamic content. Over time, JavaScript has grown beyond just the browser. With tools like **Node.js**, it can also be used on servers, allowing developers to build full websites and applications using the same language.

## Object:

Objects in JavaScript are **dynamic, prototype-based reference types** that can hold both data and behavior.

```javascript
var my_object={
			"name":"0x51B1",
			"age":24,
			"isAdmin":true
}

//{name: '0x51B1', age: 24, isAdmin: true}
```

in JavaScript, practically everything is an object, and inherits from parent object.

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FQul8Wor52IxxFqYB05ht%2Fimage.png?alt=media&#x26;token=9a8f0189-11d3-45fa-b90c-be167edd7e92" alt=""><figcaption></figcaption></figure>

JavaScript is not a conventional object-oriented language. It’s a *prototype-based object-oriented language*, which is how this inheritance works.

JavaScript doesn’t have objects that other languages like Java might use, with features like inheritance and classes – instead, these JavaScript objects rely on a special property called **proto** (or prototype), which points to that object’s ‘prototype’, allowing it to inherit properties and methods.

All the ‘**class**’ and ‘**extends**’ type syntax that you might see in modern JavaScript is just a kind of wrapper around prototype-based inheritance.&#x20;

## Prototype chain:

The **prototype chain** in JavaScript is the mechanism that allows objects to inherit properties and methods from other objects.

**Here’s how it works:**

* Every JavaScript object has an internal link (called **`[[`**`Prototype`**`]]`**, often accessed with `__proto__`) to another object, known as its **prototype**.
* If you try to access a property or method on an object and it doesn’t exist there, JavaScript automatically looks for it in the object’s prototype.
* This lookup continues up the chain until it reaches the top-level `Object.prototype`. If it’s not found there, JavaScript returns `undefined`.

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2Fjgf8HEJ4sUiScAsv8ksN%2Fimage.png?alt=media&#x26;token=7e04fe8c-ba20-4843-b2df-7253fdcbad68" alt=""><figcaption></figcaption></figure>

```jsx
> let obj={"name":"sibi","age":24}

> obj

// {name: 'sibi', age: 24}

> obj.__proto__.isAdmin=True

> obj

// {name: 'sibi', age: 24}

> obj.isAdmin

//True
```

`isAdmin` is added to the base object using the `__proto__`

## Polluting the prototype

Prototype pollution is an injection attack aimed at JavaScript runtimes, where an attacker manipulates an object's prototype to alter its default property values. This can disrupt the application's logic, potentially leading to denial of service or, in extreme cases, remote code execution.

```jsx
> var SomeObject = {}

> var obj = {}

> console.assert(user.isAdmin === true)
//Assertion failed

> SomeObject.__proto__.isAdmin === true
//true

> console.assert(user.isAdmin == true)
//undefied

> user.isAdmin
//true
```

## Demo:

{% embed url="<https://prototype-pollution-51b1.vercel.app/>" %}

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FaDbE94bI6dE8nMzkanIt%2Fimage.png?alt=media&#x26;token=18a3c6d9-706f-4b16-9c42-0214c86fd252" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FOnNyhdZnT5qTqU9MnNqB%2Fimage.png?alt=media&#x26;token=6befca4b-1d3d-432e-9a80-0771784ed9e8" alt=""><figcaption></figcaption></figure>

* **Since `innerHTML` is used to embed HTML into the page, it can be escalated into an XSS vulnerability.**
* **Ensure that the code block executes only if the user has `isAdmin` privileges.**

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FHF6cOniXQK0DEaKyph17%2Fimage.png?alt=media&#x26;token=2ea2d612-57f1-4172-b1e0-593a6cf5e73d" alt=""><figcaption></figcaption></figure>

In `mergeObjects`, the default settings and custom settings are combined using `mergeObjects(defaultSettings, customSettings);`

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FzhM2CC1XLeAubUAHmv6V%2Fimage.png?alt=media&#x26;token=7cc1a685-19de-4642-997f-e64630128674" alt=""><figcaption></figcaption></figure>

Exploiting prototype pollution via the `__proto__` property to set `isAdmin` to true.

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FSdICOPIYZmu5pk732Gp4%2Fimage.png?alt=media&#x26;token=d135bf90-8068-40ad-814e-a1f9067f647c" alt=""><figcaption></figcaption></figure>

Gained access to the variables: ID, Name, and Address info.

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FfpZfxAhcw9f5cKmSteyJ%2Fimage.png?alt=media&#x26;token=8d9c5ed9-2d9c-41f4-ac4b-b9d4670eb32e" alt=""><figcaption></figcaption></figure>

Injecting HTML through the `id` parameter.

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FaqKNGSeBWOOYpzH9cWaS%2Fimage.png?alt=media&#x26;token=f6d37bda-614c-4a34-a1e5-4f93edf0b6ee" alt=""><figcaption></figcaption></figure>

Since the sink is in `innerHTML`, we can use an `<img>` tag to execute JavaScript.

<figure><img src="https://3344709158-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAKWt8bTbHl7puA2dEZ5w%2Fuploads%2FDlrTBiM8xDuD6ir5j0Wm%2Fimage.png?alt=media&#x26;token=bc67e653-cabd-4de8-be53-624ee41eac20" alt=""><figcaption></figcaption></figure>

## Mitigation:

* Block `__proto__`, `constructor`, `prototype` in user input.
* Use `Object.create(null)` for safe objects.
* Keep libraries updated and avoid unsafe merge functions.
