Skip to main content

Prototype Pollution

 In client-side JavaScript, this commonly leads to DOM XSS, while server-side prototype pollution can even result in remote code execution.

Prototype pollution is often unexploitable as a standalone vulnerability. If the application subsequently handles an attacker-controlled property in an unsafe way, this can potentially be chained with other vulnerabilities.

Let’s first learn what is a prototype and __proto__:

In JavaScript, a prototype is an object that is associated with every constructor function and object in the language. It serves as a blueprint for creating new instances of objects with predefined properties and methods.

When you create a constructor function or an object literal in JavaScript, an internal property called [[Prototype]] (also referred to as __proto__) is automatically assigned to it. This [[Prototype]] property references the prototype object associated with the constructor function or the object.

The prototype object contains properties and methods that are shared among all instances created from the constructor function or the object. When you access a property or method on an instance, JavaScript first looks for it on the instance itself. If it doesn’t find it, it then looks for it in the prototype object ([[Prototype]]). If it still doesn't find it, it continues to search up the prototype chain until it reaches the top-level Object.prototype.

Here’s an example to illustrate this concept:

// Constructor function
function Person(name) {
this.name = name;
}

// Adding a method to the prototype
Person.prototype.greet = function() {
console.log('Hello, my name is ' + this.name);
};

// Creating an instance
var person1 = new Person('Alice');

// Accessing instance property
console.log(person1.name); // Output: Alice

// Accessing instance method
person1.greet(); // Output: Hello, my name is Alice

// Accessing property/method via prototype
console.log(person1.__proto__ === Person.prototype); // Output: true

In the example above, the Person constructor function creates instances with a name property. The greet method is added to the prototype of Person. When you create a new instance (person1) and access its properties or methods, JavaScript first checks the instance itself. If the property or method is not found, it looks up the prototype chain ([[Prototype]]) and finds it in Person.prototype.

__proto__
The best I have seen on the Internet

Now let’s see “What is prototype pollution?”:

In JavaScript, objects are created based on a prototype, which serves as a template for defining the object’s properties and methods. When a property or method is accessed on an object, JavaScript looks up the prototype chain to find the appropriate definition.

Prototype pollution occurs when an attacker is able to inject or modify properties on an object’s prototype, thereby affecting all instances and future instances of that object. This pollution can lead to various security issues, such as:

  1. Property overriding: By modifying the prototype, an attacker can add or modify properties of an object that may impact the object’s intended behavior. This can lead to unexpected or insecure behavior when the object is used elsewhere in the codebase.
  2. Property shadowing: An attacker can add properties to the prototype with the same name as existing properties in the object. This can cause the properties in the prototype to shadow the original properties, leading to unintended behavior when accessing those properties.
  3. Denial of Service (DoS): By polluting certain properties or methods, an attacker can manipulate the behavior of the affected code to cause excessive memory consumption or infinite loops, resulting in a denial of service condition.

Prototype pollution attacks typically rely on user-controlled input that is not properly validated or sanitized. For example, if a JavaScript application processes external data without adequate checks, it may inadvertently allow an attacker to manipulate the prototype and exploit the vulnerability.

When a JavaScript function recursively merges an object containing user-controllable properties into an existing object, without first sanitizing the keys. This can allow an attacker to inject a property with a key like __proto__, along with arbitrary nested properties.

It’s possible to pollute any prototype object, but this most commonly occurs with the built-in global Object.prototype.

Client-side prototype pollution via browser APIs:

This may initially seem like a reasonable mitigation attempt as this prevents the vulnerable object from inheriting a malicious version of the gadget property via the prototype chain. However, this approach is inherently flawed.

Object.defineProperty() accepts an options object, known as a "descriptor". Among other things, developers can use this descriptor object to set an initial value for the property that’s being defined. However, if the only reason that they’re defining this property is to protect against prototype pollution, they might not bother setting a value at all.

In this case, the code is targeting the transport_url property of the config object. It sets the configurable attribute to false, which means that the property cannot be deleted, and the writable attribute to false, which means that the value of the property cannot be changed.

The code doesn’t define a value for the transport_url property. In JavaScript, if you don't provide a value when defining a property using Object.defineProperty(), the property's value is set to undefined by default.

In this case, an attacker may be able to bypass this defense by polluting Object.prototype with a malicious value property. If this is inherited by the descriptor object passed to Object.defineProperty(), the attacker-controlled value may be assigned to the gadget property after all.

prototype pollution possible

The payload uses a data URL as the value for the __proto__[value] parameter. The data URL scheme allows you to include data directly in the URL itself. In this case, the payload is utilizing a data URL to inject JavaScript code for an XSS (Cross-Site Scripting) proof-of-concept.

The data URL scheme allows you to specify the data directly after the data: prefix. By injecting the data URL payload as the value for this parameter, the JavaScript code alert(1) gets executed within the application's context, causing the pop-up alert to appear.

DOM Invader

DOM Invader is a browser-based tool that helps you test for DOM XSS vulnerabilities using a variety of sources and sinks, including both web message and prototype pollution vectors. It is available exclusively via Burp’s built-in browser, where it comes preinstalled as an extension.


Comments

Popular posts from this blog

Bug Boundy Methodology, Tools & Resources

Start by defining a clear objective, such as exploiting a remote code execution (RCE) vulnerability or bypassing authentication on your target. Then, consider how you can achieve this goal using various attack vectors like XSS, SSRF, or others - these are simply tools to help you reach your objective. Use the target as how a normal user would, while browsing keep these questions in mind: 1)How does the app pass data? 2)How/where does the app talk about users? 3)Does the app have multi-tenancy or user levels? 4)Does the app have a unique threat model? 5)Has there been past security research & vulnerabilities? 6)How does the app handle XSS, CSRF, and code injection?

Install & set up mitmweb or mitmproxy in Linux

Step 1: Go to the mitmproxy page and download the binaries. Step 2: Install the downloaded tar file with the command " tar -xzf <filename>.tar.gz " Step 3: In the FoxyProxy add the proxy 127.0.0.1:8080  and turn it on. Step 4 : In the terminal run command " ./mitmweb " Step 5: Go to the page  http://mitm.it/   and download the mitmproxy's Certificate. Step 6: If you downloaded the certificate for Firefox, then go to " settings -> Privacy & Security -> Click View Certificates -> Click  Import ", then import the certificate.  Step 7: Now you are ready to capture the web traffic. Step 8 : In terminal run " ./mitmweb"

pip error in Kali Linux: error: externally-managed-environment : SOLVED

 error: externally-managed-environment × This environment is externally managed ╰─> To install Python packages system-wide, try apt install     python3-xyz, where xyz is the package you are trying to     install.     If you wish to install a non-Kali-packaged Python package,     create a virtual environment using python3 -m venv path/to/venv.     Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make     sure you have pypy3-venv installed.     If you wish to install a non-Kali-packaged Python application,     it may be easiest to use pipx install xyz, which will manage a     virtual environment for you. Make sure you have pipx installed.     For more information, refer to the following:     * https://www.kali.org/docs/general-use/python3-external-packages/     * /usr/share/doc/python3.12/README.venv note: If you believe this is a mistake, please contac...