> 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/useful-resources/bug-bounty/gitbook-ai-assistant-replay-poc.md).

# PoC повторного воспроизведения GitBook AI Assistant

[Jordanmacia/gitbook-ai-chat-replay-poc](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc) документирует исправленную проблему GitBook AI Assistant, при которой поток запросов для серверного действия Next.js можно было восстановить по доступным на клиенте данным времени выполнения и воспроизвести через внешний локальный клиент.

{% hint style="success" %}
Статус: исправлено. Уязвимость была сообщена GitBook, и теперь серверная часть принудительно проверяет права, область действия и сеансовые ограничения на стороне сервера. Сохраняйте эту страницу как историческое исследование случая bug bounty, а не как живое руководство по эксплуатации уязвимости.
{% endhint %}

## Почему это важно

GitBook представляет AI Assistant как платную функцию тарифа Ultimate. Если в режиме предварительного просмотра или настройки раскрываются воспроизводимые метаданные боевого backend, а backend не проверяет права и область действия на сервере, проблема становится не просто обходом интерфейса: она может превратиться в злоупотребление платной функцией, автоматизацию и потенциально злоупотребление затратами ресурсов.

<figure><img src="https://raw.githubusercontent.com/Jordanmacia/gitbook-ai-chat-replay-poc/main/ultimate-pricing.png" alt="GitBook Ultimate pricing showing AI Assistant"><figcaption><p>AI Assistant представлен как часть тарифа Ultimate GitBook.</p></figcaption></figure>

<figure><img src="https://raw.githubusercontent.com/Jordanmacia/gitbook-ai-chat-replay-poc/main/preview-assistant.png" alt="GitBook Assistant preview mode"><figcaption><p>Режим предварительного просмотра ассистента доступен в интерфейсе настройки GitBook.</p></figcaption></figure>

## Видео PoC

{% embed url="<https://github.com/user-attachments/assets/2c265d4a-e3c7-4438-841d-d129600980e0>" %}

## Краткое описание находки

| Область            | Примечания                                                                      |
| ------------------ | ------------------------------------------------------------------------------- |
| Product            | GitBook AI Assistant.                                                           |
| Тип исследования   | Ответственное раскрытие / исследование в стиле bug bounty.                      |
| Основной примитив  | Повтор запроса серверного действия.                                             |
| Серверное действие | `streamAIChatResponse`.                                                         |
| Основной риск      | Проверки прав доступа и области действия должны выполняться на стороне сервера. |
| Статус             | Исправлено GitBook.                                                             |

Важный урок прост: ID серверного действия может быть виден в клиентском JavaScript, но он не должен выступать в роли авторизации. Серверная часть по-прежнему должна независимо проверять права по тарифу, владение сайтом, границы предварительного просмотра/сеанса, ограничения CSRF/origin и лимиты частоты запросов.

## Влияние

| Область воздействия                        | Что могло пойти не так                                                                                           |
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| Обход платной функции                      | AI Assistant можно было использовать вне предполагаемого пути через UI тарифа Ultimate.                          |
| Злоупотребление предварительным просмотром | Режим настройки или предварительного просмотра мог раскрывать метаданные backend, пригодные для воспроизведения. |
| Автоматизация                              | Запросы к ассистенту можно было скриптовать из пользовательского клиента.                                        |
| Злоупотребление затратами                  | Ресурсы ИИ можно было расходовать без ожидаемого ограничения по правам доступа.                                  |
| Обход интерфейса                           | Можно было обойти только фронтенд-контроли, подсказки или продуктовые ограничения.                               |

Предлагаемая серьезность зависит от того, что именно разрешает серверная часть:

| Подтвержденное поведение                                                            | Предлагаемая серьезность |
| ----------------------------------------------------------------------------------- | ------------------------ |
| Повтор работает только для уже авторизованных пользователей                         | Средняя                  |
| Повтор работает из режима предварительного просмотра/настройки без платной подписки | Высокая                  |
| Повтор работает для любых публичных сайтов GitBook без подписки                     | Критическая              |
| Повтор раскрывает частную документацию без авторизации                              | Критическая              |

## Корневая причина

Уязвимый шаблон — это ошибка на границе доверия. Доступные на клиенте данные времени выполнения могут помочь восстановить запрос:

| Раскрываемые данные          | Почему это важно                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------ |
| ID серверного действия       | Направляет запрос к серверному действию.                                                         |
| `spaceId`                    | Идентифицирует пространство GitBook.                                                             |
| `pageId`                     | Идентифицирует контекст страницы.                                                                |
| Состояние RSC/маршрутизатора | Помогает сопоставить ожидаемую форму запроса Next.js.                                            |
| Структура тела запроса       | Показывает, как структурирован вызов ассистента.                                                 |
| Файлы cookie сеанса браузера | Переносят пользовательский сеанс, если они были захвачены во время авторизованного тестирования. |

Проблема не в том, что серверные действия видны. Проблема возникает, когда backend принимает повторно воспроизведенный запрос, собранный из наблюдаемых на клиенте метаданных, без повторной проверки прав доступа, владения, области предварительного просмотра, действительности сеанса, CSRF/origin и ограничений по частоте.

## Поток PoC

В репозитории есть локальный PoC на Node.js, который обнаруживает метаданные времени выполнения и запускает локальный HTTPS-прокси.

```bash
npm start
```

Общий поток:

1. Запросите страницу GitBook или URL предварительного просмотра.
2. Скачайте HTML страницы.
3. Скачайте фрагменты JavaScript GitBook.
4. Извлеките текущий `streamAIChatResponse` ID серверного действия.
5. Извлеките `spaceId` и `pageId`.
6. Откройте Chrome, Chromium или Edge для аутентификации.
7. Сохраните необходимые значения времени выполнения в `.env`.
8. Запустите локальный HTTPS-прокси.

Затем откройте:

```
https://localhost:3001
```

Локальный интерфейс обращается к:

```http
POST /api/chat
```

Прокси воссоздает запрос GitBook AI Assistant с заголовками, эквивалентными:

```http
accept: text/x-component
content-type: text/plain;charset=UTF-8
next-action: <обнаруженный id действия streamAIChatResponse>
next-router-state-tree: <состояние маршрутизатора>
origin: <целевой origin GitBook>
referer: <целевой URL GitBook>
cookie: <захваченные cookie GitBook>
```

Успешное воспроизведение возвращает поток React Server Components, содержащий события ответа ИИ. Локальный прокси разбирает итоговый ответ и возвращает обычный JSON-ответ для UI PoC.

## Типичные признаки

| Ответ                 | Значение                                                           |
| --------------------- | ------------------------------------------------------------------ |
| `400 Неверный запрос` | ID серверного действия устарел или неверен.                        |
| Поток RSC с `digest`  | Действие существует, но тело запроса или контекст недействительны. |
| `401` / `403`         | Сеанс или авторизация отклонены.                                   |
| `text/x-component`    | Ожидаемый тип контента потока React Server Components.             |

## Требования

| Требование | Примечания                                       |
| ---------- | ------------------------------------------------ |
| Node.js    | Версия 18 или новее.                             |
| Браузер    | Chrome, Chromium или Microsoft Edge.             |
| OpenSSL    | Требуется `PATH` для локальных HTTPS-материалов. |
| ОС         | PoC поддерживает Windows, Linux и macOS.         |

## Очистка

Используйте команду очистки репозитория после тестирования:

```bash
npm run stop
```

Она очищает запущенные процессы PoC, чувствительные `.env` значения, сгенерированные локальные TLS-файлы и выделенный профиль браузера для аутентификации.

## Устранение

Рекомендуемые меры:

| Мера                                                                                        | Назначение                                                                  |
| ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Принудительно проверяйте права тарифа внутри `streamAIChatResponse`                         | Предотвратить обход платной функции.                                        |
| Рассматривайте `next-action` как метаданные маршрутизации                                   | Не путайте ID действий с авторизацией.                                      |
| Привязывайте вызовы предварительного просмотра к краткоживущим токенам, выдаваемым сервером | Сохраняйте доступ к предварительному просмотру в пределах его области.      |
| Предотвращайте повторное использование токена предварительного просмотра                    | Не допускайте внешнего повторного использования вне предполагаемого сеанса. |
| Проверяйте `spaceId` и `pageId` на стороне сервера                                          | Убедитесь, что запрошенный контекст принадлежит авторизованной области.     |
| Отклоняйте несовпадающий контекст, переданный клиентом                                      | Предотвращайте подмену контекста.                                           |
| Обеспечивайте CSRF и строгие `Origin` проверки                                              | Снижайте риск межсайтового и скриптового злоупотребления.                   |
| Ограничивайте частоту по пользователю, организации, сайту, IP и сеансу                      | Ограничьте автоматизацию и злоупотребление затратами.                       |
| Отслеживайте скриптовое воспроизведение серверных действий                                  | Обнаруживайте не-браузерные или необычные шаблоны воспроизведения.          |

## Извлеченные уроки

1. Функции предварительного просмотра являются границами безопасности, когда они взаимодействуют с платными или боевыми backend-системами.
2. Проверки на стороне клиента полезны для UX, но это не авторизация.
3. ID серверных действий Next.js следует рассматривать как публичные детали маршрутизации.
4. Для ИИ-функций нужны контроль затрат и прав доступа не меньше, чем контроль доступа к данным.
5. Отчеты bug bounty сильнее, когда они разделяют наблюдаемое поведение, возможное влияние и рекомендуемые меры устранения.

## Ссылки

* [Jordanmacia/gitbook-ai-chat-replay-poc](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc)
* [README репозитория](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc/blob/main/README.md)
* [Запуск PoC](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc/tree/main/scripts)
* [Локальный прокси](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc/blob/main/server.js)


---

# 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/ru/useful-resources/bug-bounty/gitbook-ai-assistant-replay-poc.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.
