Beginner’s Guide to Client Prototype Pollution vulnerabilities

The perfect introduction for those wanting to understand Prototype Pollution vulnerabilities and exploits. Because not everyone knows how Objects in JavaScript work, but we are about to change that! Are you up for the challenge?

· 5 min read
Beginner’s Guide to Client Prototype Pollution vulnerabilities
💡
We invite you to follow along by using your Browser's Console to execute JavaScript code. Just open your favorite browser, press F12, and go to the 'Console' tab. Happy coding!

First of all, what is a JavaScript Object?

JavaScript objects are used to store various key:value pairs. They can be seen as collections of properties, where each property is an association between a key and a value. These values can be a function, an array, another object, or any other data type available in JavaScript, including numbers, strings, and booleans.

What is surprising is that all of the data structures are Objectsunder the hood, even functions!

What is a Prototype in JavaScript?

Let's use a student and teacher analogy.

Imagine a Classroom

  1. Student (Object): knows some things, may not know others.
  2. Teacher (Prototype): knows a lot of things and can teach students.

Example

If you ask the student to solve a multiplication problem:

  1. The student first tries to solve it on their own.
  2. If they can't, they ask the teacher.
  3. The teacher explains how to do multiplication.
  4. Now, the student can solve multiplication problems too.

Objects (students) like strings, functions, arrays are linked to other objects (teachers) through prototypes.

For example, all strings are assigned the String.prototype, where they inherit the toUpperCase() method. As a result, all strings automatically have a ready-to-use method for converting them to uppercase, amongst others.

How Prototype Inheritance works

In programming terms, when we reference a property of an object (asking the student to solve a multiplication problem), JavaScript tries to access it directly first (step 1 of our analogy). But if said object doesn't have a matching property to return, then it will start to look (ask the teacher) for it on the object's prototype instead.

That's why we could call toUpperCase function on input variable without defining it first.

The Prototype Chain 😱

  • Everything is an Object in JavaScript
  • Every Object gets assigned a Prototype from where it inherits properties and methods
  • Then... every Prototype is an Object
  • Therefore... every Prototype has a Prototype assigned to it. And so on

This madness is called "The Prototype Chain" and it ultimately leads back to the top-level Object.prototype, whose prototype is simply null. (Don't look at us like that, alright? It's not our fault.)

Most importantly, objects inherit properties and methods from all the objects' prototypes above them in the chain. This means that our input object has access to the properties and methods of both String.prototype and Object.prototype.

Modifying Prototypes

You can access an object's prototype by using its __proto__ property. And you can use it to read or reassign any prototype's properties. (You can also play around the prototype chain)

Understanding Client Prototype Pollution Vulnerabilities

Prototype Pollution vulnerabilities arise when a JavaScript function recursively merges an object containing user-controllable data into an existing object, without first sanitizing the keys. This may allow a bad actor to inject the __proto__ key along with arbitrary nested properties.

Then, the merge operation may assign these nested properties to the object's prototype instead of the target object itself, allowing the bad actor to pollute prototypes with harmful values.

For successful exploitation of Prototype Pollution you require three key components:

  • A prototype pollution source --> This is any input that enables you to poison prototype objects with arbitrary properties.
  • An exploitable gadget -->This is any property that is passed into a sink without proper filtering or sanitization.
  • A sink --> A JavaScript function or DOM element that enables arbitrary code execution.

But don't worry about those for now, we'll learn more about them in a future blog post. Stay tuned for more experienced exploits!

Exploiting Client Prototype Pollution Vulnerabilities

On your web application add the ?__proto__[vulnerable]=true parameter as follows:

https://website.com/?__proto__[vulnerable]=true

In this case, the JS engine will treat __proto__ as a getter for the object's prototype and assign the vulnerable key to it. Assuming that the target object uses the default Object.prototype, all objects in the JavaScript runtime will now inherit vulnerable, unless they already have a property of their own with a matching key.

In our analogy terms, we showed the teacher the vulnerable payload, so all the students will now learn the same. Making the whole classroom vulnerable.

In practice, injecting a property called vulnerable is unlikely to have any effect on the web app. However, a bad actor can use the same technique to pollute the prototype with properties that are used by the application, or any imported libraries.

💡
But for you, our beginner friend, this is enough to start playing around checking which applications you can pollute. After sending the URL parameter, open the Browser's Console and create a new object. Then check if that new object of yours has the vulnerable property into it (or any other property name you tested).

Other useful tips

  • If the property was not added to the prototype, try switching to dot notation rather than bracket notation, or vice versa: https://website.com/?__proto__.vulnerable=true
  • If neither of these techniques is successful, you may still be able to pollute the prototype via its constructor. We'll cover this in a future blog post, but have in mind that myObject.constructor.prototype is equivalent to myObject.__proto__.
  • So https://website.com/?constructor.prototype.vulnerable=true or https://website.com/?constructor[prototype][vulnerable]=true provide an alternative vector for Prototype Pollution.

Conclusion

We have shared some insights about Prototype Pollution vulnerabilities so you can start looking for them in the wild. That way, we are part of your Cyber Security journey. We would love to see you succeed.

That's why we invite you to experience the VIDOC tool firsthand by trying our platform are free. There are several vulnerability modules so you can sit back and wait for vulnerabilities to arise. Check them out here.

_________________________________________________________


Check our other social media platforms to stay connected:‎

Website | www.vidocsecurity.com
Linkedin | www.linkedin.com/company/vidoc-security-lab
X (formerly Twitter) | twitter.com/vidocsecurity
YouTube | www.youtube.com/@vidocsecuritylab
Facebook | www.facebook.com/vidocsec
Instagram | www.instagram.com/vidocsecurity