# Node.js et Brotli : une erreur de format devenue écriture hors limites

> Le décodeur Brotli de Node.js pouvait remplir sans borne un tampon de huit octets. Explication du streaming, de la corruption et de l’exposition.

Publié le: 2026-11-04  
Canonical: https://rootzero.eu/research/node-brotli-decodeur-hors-limites-2026/

**Publication Node.js du 21 octobre 2026.** Le [projet Node.js](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases) décrit **CVE-2026-111497** comme une écriture hors limites dans le décodeur Brotli embarqué. Un flux compressé malformé peut faire écrire au-delà d'un petit tampon interne, avec pour conséquences possibles crash, divulgation de mémoire ou exécution de code. L'affirmation « RCE possible » vient du projet ; son avis ne publie pas une chaîne d'exploitation fiable et universelle. La question technique est plutôt : comment une erreur de format censée arrêter le décodage peut-elle laisser le traitement continuer à écrire ?

## Un décodeur de flux doit savoir distinguer attente et échec

Brotli représente des données compressées sous forme de blocs et de commandes de décodage. Un décodeur appelé sur des morceaux successifs ne peut pas toujours finir immédiatement : lorsqu'il lui manque des octets valides, il retourne un état du type « besoin de plus de données ». En revanche, si les octets déjà lus forment une combinaison impossible selon le format, il doit rejeter le flux. Ces deux états semblent proches pour l'appelant, mais leur effet est opposé : le premier autorise l'ajout de données ; le second interdit de poursuivre.

Dans la faille décrite, un **changement de bloc invalide** a été signalé comme besoin temporaire d'entrée supplémentaire au lieu d'une erreur définitive. Le décodeur en streaming continuait donc d'ajouter des octets dans un tampon interne de **huit octets**. L'état logique « j'attends encore » devenait dangereux parce qu'il pouvait se répéter alors que l'espace physique était épuisé. Une vérification des seules tailles du flux d'entrée ou de sortie n'aurait pas nécessairement détecté ce problème : la limite violée est celle d'un buffer intermédiaire.

Le mécanisme est une mauvaise transition d'état suivie d'une écriture non bornée. Le type exact d'octets corrompus autour du tampon et la possibilité de contrôler le flot d'exécution dépendent du placement mémoire et du chemin de décodage. Un crash reproductible prouverait la corruption ; il ne prouverait pas, seul, la prise de contrôle. L'avis Node.js sépare implicitement ces résultats en les présentant comme effets **possibles**.

## Qui fournit les octets dangereux ?

La condition donnée par Node.js est que l'application décompresse, via `node:zlib`, des données Brotli que l'attaquant peut fournir. Cela peut être un fichier reçu, un corps HTTP ou un autre flux si l'application le transmet effectivement au décodeur ; la simple présence de Node.js dans un service ne démontre pas qu'il accepte du Brotli hostile. L'inventaire défensif doit donc repérer les appels de décompression et suivre la provenance des octets jusqu'à eux.

Une recherche autorisée peut générer des flux Brotli invalides, comparer le comportement des versions vulnérables et corrigées sous instrumentation mémoire, puis réduire le cas au changement de bloc minimal. L'analyse du correctif doit vérifier deux choses distinctes : le décodeur retourne une erreur de format lorsque l'état est impossible, et aucune branche d'attente ne peut écrire au-delà des huit octets. Le projet crédite deux rapporteurs et deux correcteurs dans [son avis](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases), mais ne publie pas dans ce bulletin le PoC original ; nous ne prétendons donc pas reproduire leur chemin de découverte.

## Corriger au bon niveau

Le projet a publié **Node.js 22.23.4, 24.22.1 et 26.12.1** pour les branches concernées. La mise à jour doit viser le runtime réellement utilisé en production, y compris les images de conteneur et les exécutables empaquetés qui embarquent leur propre Node.js. Un filtrage amont des tailles de fichier peut réduire certains abus, mais il ne remplace pas la correction de l'état de décodage : une entrée courte peut déjà porter une transition de format invalide.

Cette CVE illustre un principe de sûreté du code natif : « il manque des données » n'est pas une réponse acceptable à une contradiction déjà établie par le parseur. Si l'état d'erreur est confondu avec l'état d'attente, une boucle de streaming peut transformer quelques octets malformés en corruption mémoire.

**Source principale :** [publication de sécurité Node.js du 21 octobre 2026](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases).
