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

# PoC de relecture de l'assistant IA de GitBook

[Jordanmacia/gitbook-ai-chat-replay-poc](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc) documente un problème corrigé de GitBook AI Assistant où le flux de requête d’une action serveur Next.js pouvait être reconstruit à partir de données d’exécution visibles côté client et rejoué via un client local externe.

{% hint style="success" %}
Statut : corrigé. La vulnérabilité a été signalée à GitBook, et le backend applique désormais des contrôles d’habilitation, de portée et de session côté serveur. Conservez cette page comme étude de cas historique de bug bounty, et non comme guide d’exploitation en direct.
{% endhint %}

## Pourquoi c’est important

GitBook présente AI Assistant comme une fonctionnalité payante du plan Ultimate. Si une vue d’aperçu ou de personnalisation expose des métadonnées de backend de production rejouables, et que le backend ne vérifie pas l’habilitation et la portée côté serveur, le problème devient plus qu’un contournement de l’interface : il peut devenir un abus de fonctionnalité payante, un abus d’automatisation et potentiellement un abus des coûts en ressources.

<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 présenté comme faisant partie de la tarification Ultimate de 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>Mode d’aperçu de l’assistant exposé dans l’interface de personnalisation de GitBook.</p></figcaption></figure>

## Vidéo de preuve de concept

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

## Résumé de la découverte

| Domaine              | Notes                                                                          |
| -------------------- | ------------------------------------------------------------------------------ |
| Product              | GitBook AI Assistant.                                                          |
| Type de recherche    | Divulgation responsable / étude de cas de type bug bounty.                     |
| Primitive principale | Rejeu d’une requête d’action serveur.                                          |
| Action backend       | `streamAIChatResponse`.                                                        |
| Risque principal     | Les contrôles d’habilitation et de portée doivent être effectués côté serveur. |
| Statut               | Corrigé par GitBook.                                                           |

La leçon importante est simple : un identifiant d’action serveur peut être visible dans du JavaScript côté client, mais il ne doit pas servir d’autorisation. Le backend doit toujours vérifier indépendamment le droit au plan, la propriété du site, les limites d’aperçu/de session, les contraintes CSRF/origin et les limites de débit.

## Impact

| Zone d’impact                           | Ce qui pourrait mal tourner                                                                |
| --------------------------------------- | ------------------------------------------------------------------------------------------ |
| Contournement de fonctionnalité payante | AI Assistant pourrait être utilisé en dehors du chemin d’interface prévu du plan Ultimate. |
| Abus de l’aperçu                        | Le mode personnalisation ou aperçu pourrait exposer des métadonnées de backend rejouables. |
| Automatisation                          | Les requêtes de l’assistant pourraient être scriptées depuis un client personnalisé.       |
| Abus des coûts                          | Les ressources IA pourraient être consommées sans le contrôle d’habilitation attendu.      |
| Contournement de l’interface            | Les contrôles, invites ou verrous produit côté frontend בלבד pourraient être ignorés.      |

La gravité suggérée dépend de ce que le backend autorise réellement :

| Comportement confirmé                                                             | Gravité suggérée |
| --------------------------------------------------------------------------------- | ---------------- |
| Le rejeu ne fonctionne que pour des utilisateurs déjà habilités                   | Moyenne          |
| Le rejeu fonctionne depuis l’aperçu/la personnalisation sans habilitation payante | Élevée           |
| Le rejeu fonctionne pour n’importe quel site public GitBook sans habilitation     | Critique         |
| Le rejeu expose une documentation privée sans autorisation                        | Critique         |

## Cause racine

Le schéma vulnérable est une erreur de frontière de confiance. Les données d’exécution visibles côté client peuvent aider à reconstruire la requête :

| Matériel exposé                  | Pourquoi c’est important                                                         |
| -------------------------------- | -------------------------------------------------------------------------------- |
| Identifiant de l’action serveur  | Oriente la requête vers l’action backend.                                        |
| `spaceId`                        | იდენტifie l’espace GitBook.                                                      |
| `pageId`                         | Identifie le contexte de la page.                                                |
| État RSC/routeur                 | Aide à faire correspondre la forme attendue de la requête Next.js.               |
| Structure du corps de la requête | Montre comment l’appel de l’assistant est structuré.                             |
| Cookies de session du navigateur | Transportent la session utilisateur s’ils sont capturés lors d’un test autorisé. |

Le bug ne consiste pas en « les actions serveur sont visibles ». Le bug apparaît lorsque le backend accepte une requête rejouée assemblée à partir de métadonnées observables côté client sans revérifier l’habilitation, la propriété, la portée de l’aperçu, la validité de la session, le CSRF/origin et les limites de débit.

## Flux de PoC

Le dépôt contient un PoC local Node.js qui découvre les métadonnées d’exécution et lance un proxy HTTPS local.

```bash
npm start
```

Flux de haut niveau :

1. Demandez une page GitBook ou une URL d’aperçu.
2. Téléchargez le HTML de la page.
3. Téléchargez les fragments JavaScript de GitBook.
4. Extrayez l’ `streamAIChatResponse` identifiant de l’action serveur.
5. Extrayez `spaceId` et `pageId`.
6. Ouvrez Chrome, Chromium ou Edge pour l’authentification.
7. Stockez les valeurs d’exécution requises dans `.env`.
8. Démarrez un proxy HTTPS local.

Puis ouvrez :

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

L’interface locale communique avec :

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

Le proxy recrée la requête de GitBook AI Assistant avec des en-têtes équivalents à :

```http
accept: text/x-component
content-type: text/plain;charset=UTF-8
next-action: <identifiant découvert de l’action streamAIChatResponse>
next-router-state-tree: <état du routeur>
origin: <origine GitBook cible>
referer: <URL GitBook cible>
cookie: <cookies GitBook capturés>
```

Un rejeu réussi renvoie un flux React Server Components contenant des événements de réponse IA. Le proxy local analyse la réponse finale et renvoie une réponse JSON normale pour l’interface du PoC.

## Signaux courants

| Réponse                | Signification                                                   |
| ---------------------- | --------------------------------------------------------------- |
| `400 Requête invalide` | L’identifiant de l’action serveur est obsolète ou incorrect.    |
| Flux RSC avec `digest` | L’action existe, mais le corps ou le contexte n’est pas valide. |
| `401` / `403`          | Session ou autorisation refusée.                                |
| `text/x-component`     | Type de contenu attendu pour un flux React Server Components.   |

## Prérequis

| Exigence               | Notes                                                   |
| ---------------------- | ------------------------------------------------------- |
| Node.js                | Version 18 ou plus récente.                             |
| Navigateur             | Chrome, Chromium ou Microsoft Edge.                     |
| OpenSSL                | Requis dans `PATH` pour les éléments HTTPS locaux.      |
| Système d'exploitation | Windows, Linux et macOS sont pris en charge par le PoC. |

## Nettoyage

Utilisez la commande de nettoyage du dépôt après les tests :

```bash
npm run stop
```

Elle efface les processus PoC en cours, les valeurs sensibles, `.env` les fichiers TLS locaux générés et le profil de navigateur dédié à l’authentification.

## Remédiation

Contrôles recommandés :

| Contrôle                                                                        | Objectif                                                             |
| ------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Appliquer l’habilitation du plan dans `streamAIChatResponse`                    | Empêcher le contournement de la fonctionnalité payante.              |
| Traiter `next-action` comme des métadonnées de routage                          | Éviter de confondre les identifiants d’action avec une autorisation. |
| Lier les appels d’aperçu à des jetons à courte durée de vie émis par le serveur | Conserver l’accès d’aperçu dans la portée de l’aperçu.               |
| Empêcher le rejeu du jeton d’aperçu                                             | Bloquer la réutilisation externe en dehors de la session prévue.     |
| Valider `spaceId` et `pageId` côté serveur                                      | S’assurer que le contexte demandé appartient à la portée autorisée.  |
| Rejeter les contextes fournis par le client qui ne correspondent pas            | Empêcher l’échange de contexte.                                      |
| Appliquer le CSRF et des `Origin` vérifications strictes                        | Réduire les abus intersites et scriptés.                             |
| Limiter le débit par utilisateur, organisation, site, IP et session             | Limiter l’automatisation et les abus de coûts.                       |
| Surveiller le rejeu scripté des actions serveur                                 | Détecter les schémas de rejeu non navigateur ou inhabituels.         |

## Leçons apprises

1. Les fonctionnalités d’aperçu sont des frontières de sécurité lorsqu’elles touchent à des backends payants ou de production.
2. Les verrous côté client sont utiles pour l’UX, mais ils ne constituent pas une autorisation.
3. Les identifiants d’action serveur Next.js doivent être traités comme des détails de routage publics.
4. Les fonctionnalités IA ont besoin de contrôles de coûts et d’habilitation autant que de contrôles d’accès aux données.
5. Les rapports de bug bounty sont plus solides lorsqu’ils séparent le comportement observé, l’impact possible et la remédiation recommandée.

## Références

* [Jordanmacia/gitbook-ai-chat-replay-poc](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc)
* [README du dépôt](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc/blob/main/README.md)
* [Lanceur de PoC](https://github.com/Jordanmacia/gitbook-ai-chat-replay-poc/tree/main/scripts)
* [Proxy local](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/fr/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.
