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

# GitBook AI Assistant 回放 PoC

GitBook AI Assistant 服务器操作回放 PoC 案例研究，涵盖已修复的权限绕过风险、预览模式回放、影响、检测笔记和修复措施。

[Jordanmacia/gitbook-ai-chat-replay-poc](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc) 记录了一个已修复的 GitBook AI Assistant 问题：Next.js server action 的请求流程可以从客户端可见的运行时数据中重建，并通过外部本地客户端重放。

{% hint style="success" %}
状态：已修复。该漏洞已向 GitBook 报告，后端现在会在服务器端强制执行权限、作用域和会话控制。请将此页面保留为历史性的漏洞赏金案例研究，而不是实时利用指南。
{% endhint %}

## 为什么这很重要

GitBook 将 AI Assistant 作为付费的 Ultimate 套餐功能来提供。如果预览或自定义视图暴露了可重放的生产后端元数据，而后端又没有在服务器端验证权限和作用域，这个问题就不仅仅是 UI 绕过：它还可能变成付费功能滥用、自动化滥用，以及潜在的资源成本滥用。

<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>GitBook 自定义界面中暴露了 Assistant 预览模式。</p></figcaption></figure>

## 视频 PoC

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

## 发现摘要

| 领域      | 说明                      |
| ------- | ----------------------- |
| Product | GitBook AI Assistant。   |
| 研究类型    | 负责任披露 / 漏洞赏金风格案例研究。     |
| 核心原语    | server action 请求重放。     |
| 后端动作    | `streamAIChatResponse`. |
| 主要风险    | 权限和作用域检查必须在服务器端进行。      |
| 状态      | 已由 GitBook 修复。          |

重要的教训很简单：server action ID 可以在客户端 JavaScript 中可见，但它不应充当授权依据。后端仍然需要独立检查套餐权限、站点所有权、预览/会话边界、CSRF/来源约束以及速率限制。

## 影响

| 影响范围   | 可能出什么问题                                      |
| ------ | -------------------------------------------- |
| 付费功能绕过 | AI Assistant 可能会在预期的 Ultimate 套餐 UI 路径之外被使用。 |
| 预览滥用   | 自定义或预览模式可能会暴露可重放的后端元数据。                      |
| 自动化    | Assistant 查询可能通过自定义客户端被脚本化。                  |
| 成本滥用   | AI 资源可能会在没有预期权限门控的情况下被消耗。                    |
| UI 绕过  | 仅前端控制、提示或产品门槛可能会被跳过。                         |

建议的严重性取决于后端实际上允许什么：

| 已确认的行为                      | 建议严重性 |
| --------------------------- | ----- |
| 仅对已拥有权限的用户有效的重放             | 中等    |
| 无需付费权限即可在预览/自定义中重放          | 高     |
| 可对任意公开的 GitBook 站点进行重放且无需权限 | 严重    |
| 重放在未授权情况下暴露了私有文档            | 严重    |

## 根本原因

存在漏洞的模式是一种信任边界错误。客户端可见的运行时数据可以帮助重建请求：

| 暴露的内容            | 为什么这很重要                |
| ---------------- | ---------------------- |
| Server action ID | 将请求路由到后端动作。            |
| `spaceId`        | 标识 GitBook 空间。         |
| `pageId`         | 标识页面上下文。               |
| RSC/路由器状态        | 有助于匹配预期的 Next.js 请求形状。 |
| 请求体形状            | 显示 assistant 调用是如何构造的。 |
| 浏览器会话 Cookie     | 如果在授权测试期间被捕获，则携带用户会话。  |

问题不在于“server actions 是可见的”。真正的问题在于：后端接受了由客户端可观察元数据拼装而成的重放请求，却没有重新检查权限、所有权、预览作用域、会话有效性、CSRF/来源以及速率限制。

## PoC 流程

该仓库包含一个本地 Node.js PoC，用于发现运行时元数据并启动本地 HTTPS 代理。

```bash
npm start
```

高级流程：

1. 输入一个 GitBook 页面或预览 URL。
2. 下载页面 HTML。
3. 下载 GitBook JavaScript 分块。
4. 提取当前 `streamAIChatResponse` server action ID。
5. 提取 `spaceId` 和 `pageId`.
6. 打开 Chrome、Chromium 或 Edge 进行身份验证。
7. 将所需的运行时值存储在 `.env`.
8. 启动本地 HTTPS 代理。

然后打开：

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

本地 UI 与以下接口通信：

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

代理会用以下等效头部重建 GitBook AI Assistant 请求：

```http
accept: text/x-component
content-type: text/plain;charset=UTF-8
next-action: <发现的 streamAIChatResponse 动作 ID>
next-router-state-tree: <路由状态>
origin: <目标 GitBook 源站>
referer: <目标 GitBook URL>
cookie: <捕获的 GitBook Cookie>
```

成功重放后会返回一个包含 AI 响应事件的 React Server Components 流。本地代理会解析最终答案，并为 PoC UI 返回普通 JSON 响应。

## 常见信号

| 响应                 | 含义                                 |
| ------------------ | ---------------------------------- |
| `400 无效请求`         | server action ID 已过期或不正确。          |
| 带有 `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 和会话进行速率限制       | 限制自动化和成本滥用。       |
| 监控脚本化的 server action 重放      | 检测非浏览器或异常的重放模式。   |

## 经验教训

1. 当预览功能接触付费或生产后端时，它们就是安全边界。
2. 客户端侧门槛对用户体验有帮助，但它们不是授权。
3. Next.js server action ID 应被视为公开的路由细节。
4. AI 功能需要成本和权限控制，就像需要数据访问控制一样。
5. 漏洞赏金报告如果能区分已观察到的行为、可能影响以及建议修复，就会更有说服力。

## 参考资料

* [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/zh/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.
