> 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).

# GitBook AI Assistant Replay PoC

Кейс GitBook AI Assistant server action replay PoC, охватывающий риск обхода фиксированных прав доступа, воспроизведение в режиме предварительного просмотра, влияние, заметки по обнаружению и исправление.

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

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

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

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

<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 представлен как часть ценообразования GitBook Ultimate.</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>Режим предварительного просмотра Assistant отображается в интерфейсе настройки GitBook.</p></figcaption></figure>

## Видео PoC

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

## Краткое изложение находки

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

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

## Влияние

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

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

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

## Первопричина

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

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

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

## Поток PoC

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

```bash
npm start
```

Общая схема:

1. Укажите страницу GitBook или URL предпросмотра.
2. Скачайте HTML страницы.
3. Скачайте JavaScript-чанки GitBook.
4. Извлеките текущий `streamAIChatResponse` идентификатор server action.
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: <обнаруженный идентификатор действия streamAIChatResponse>
next-router-state-tree: <состояние router>
origin: <целевой origin GitBook>
referer: <целевой URL GitBook>
cookie: <захваченные cookie GitBook>
```

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

## Общие сигналы

| Ответ                 | Значение                                                   |
| --------------------- | ---------------------------------------------------------- |
| `400 Неверный запрос` | Идентификатор server action устарел или неверен.           |
| Поток 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` как метаданные маршрутизации                    | Не путайте идентификаторы действий с авторизацией.                          |
| Привязывайте вызовы предпросмотра к краткоживущим токенам, выданным сервером | Держите доступ к предпросмотру в пределах области предпросмотра.            |
| Предотвращайте воспроизведение токена предпросмотра                          | Не допускайте внешнего повторного использования вне предполагаемого сеанса. |
| Проверяйте `spaceId` и `pageId` на стороне сервера                           | Убедитесь, что запрошенный контекст принадлежит авторизованной области.     |
| Отклоняйте несоответствующий контекст, предоставленный клиентом              | Не допускайте подмену контекста.                                            |
| Обеспечивайте проверки CSRF и строгие `Origin` проверки                      | Снижайте межсайтовое и скриптовое злоупотребление.                          |
| Ограничивайте частоту по пользователю, организации, сайту, IP и сеансу       | Ограничивайте автоматизацию и злоупотребление затратами.                    |
| Отслеживайте автоматизированное воспроизведение server action                | Выявляйте не браузерные или необычные шаблоны воспроизведения.              |

## Выводы

1. Функции предпросмотра являются границами безопасности, когда они затрагивают платные или производственные бэкенды.
2. Клиентские ограничения полезны для UX, но это не авторизация.
3. Идентификаторы server action в 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 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/useful-resources/bug-bounty/gitbook-ai-assistant-replay-poc.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.
