jQuery Prototype Pollution Demo

Ben Berkowitz and Phil Sofia
WithSecure, 2022

We intentionally designed this page to be vulnerable to DOM-based XSS and prototype pollution.
Visiting links to page in the browser can result in the execution of arbitrary JavaScript.
This page was intended for educational and research purposes only.
Interact with it at your own risk.

This page is part of an article published on WithSecure Labs.
See the full article at https://labs.withsecure.com/publications/prototype-pollution-primer-for-pentesters-and-programmers

Big Thanks to Sergey Bobrov, Mohan Sri Rama Krishna P, and the rest of their team,
whose client-side Prototype Pollution repository and research
were the source of all the payloads we used on this page.

Proto Pollution Payloads Table

Function(s) Affected Payload
$.ajax on objects, $.get. $.post, etc. #__proto__[url][]=data:,alert(123)//&__proto__[dataType]=script
(x).off(...) #__proto__[preventDefault]=x&__proto__[handleObj]=x&__proto__[delegateTarget]=<img/src/onerror%3dalert(456)>
$(html) #__proto__[div][1]=<img src onerror%3dalert(789)>

This page is vulnerable to multiple exploitation gadgets that affect jQuery
v.3.6.0, the most recent version at the time of writing. We've selected three
payloads and included them in the table above. All three payloads produce
DOM-based Cross-Site Scripting and show a harmless alert window for
demonstrative purposes.

To see each one in action, append the respective payloads one at a time to
the URL bar, including the # character, like so:


Paste the payload into the URL bar, then refresh the page.

How does this work?

Prototype pollution occurs when user-supplied data is insecurely handled by
client-side code in such a way that data prototypes are affected.
This pollution of data prototypes can result in a security impact, often Cross-Site scripting.

There are two components to impactful prototype pollution. First, an application
needs to execute code that pollutes the prototype. Next, it must call a function
that processes a polluted object in a way that produces exploitation.

Polluting the Prototype

The pollution on this page occurs due to jQueryBBQ, a third-party jQuery extension library
which provides Back Button and Query (BBQ) features. While this library was last
updated in 2010, it can still be found in applications to this day.
BBQ's $.deparam() function converts the page's URL hash parameters into objects.
When a user supplies this function with the right payloads, deparam() will alter Object.prototype.

The line that causes prototype pollution via URL hash in the <script> tags below is:

var urlHash = $.deparam(location.hash.slice(1));

Calling Vulnerable Functions

This page calls three functions from jQuery that execute the code injected into
Object.prototype during pollution. These three functions are present and vulnerable
in the most recent version of jQuery (3.6.0 at the time of this writing).

Each of the three functions shown in the table above has a purpose, but in our
blog post we went into detail on $.ajax and a few of its related
functionalities in the context of prototype pollution.