Une faille du décodeur Brotli livre Node.js et Python à un serveur malveillant
Un bug dans le décodeur Brotli de Google permet à un flux compressé piégé d'écrire au-delà de la fin d'un tampon en mémoire. Suivie sous la référence CVE-2026-111497 et notée 9,2 sur 10 dans l'avis de GitHub, la faille touche les versions 1.0.3 à 1.2.0 de Brotli. Brotli compresse une grande partie du trafic web actuel, si bien que le problème dépasse largement une seule bibliothèque : Node.js, Bun, Envoy, Istio et les paquets Python que requests et aiohttp utilisent d'eux-mêmes embarquent ou chargent le code vulnérable. Les correctifs sont sortis du 21 au 23 octobre.
Ce qui ne va pas
Un flux Brotli est découpé en blocs, et le décodeur passe d'un type de bloc à l'autre au fil de la lecture. Selon l'avis de Node.js, un changement de bloc invalide était traité comme un simple besoin de données supplémentaires plutôt que comme une erreur de format. Le décodeur continuait alors d'ajouter les octets de l'attaquant dans un tampon interne de huit octets et écrivait au-delà de sa fin. Selon ce qui est écrasé, cela provoque un plantage, une fuite de mémoire du processus ou une exécution de code à distance.
La faille a été signalée à Node.js par Khai Tran et Sylvie Mayer d'OpenAI Codex Security. Google a publié les versions corrigées 1.0.10, 1.1.1 et 1.2.1 de Brotli, et Node.js les versions 22.23.4, 24.22.1 et 26.12.1 le 21 octobre. Node.js 20 et les autres branches en fin de vie ne recevront pas de correctif.
L'attaque marche dans les deux sens
Le décodeur tourne partout où arrivent des données compressées, donc chaque côté d'une connexion peut être visé. Un serveur malveillant peut attaquer un client : le fetch() intégré à Node décompresse automatiquement les réponses Brotli, tout comme les bibliothèques Python requests, urllib3 et aiohttp dès qu'un paquet Brotli est installé. L'application n'a même pas besoin d'importer ce paquet. Webhooks, aperçus de liens, robots d'indexation et fonctions « importer depuis une URL » récupèrent sans cesse du contenu sur des serveurs tiers.
Dans l'autre sens, un client peut attaquer un serveur qui décompresse le corps des requêtes. Express 5.0.0 à 5.3.0 et body-parser 2.0.0 à 2.3.0 décompressent le Brotli dans leurs parseurs raw() et json(). L'équipe Imperva Red Team a exécuté son propre code sur l'image officielle de Node.js 24.22.0 par les deux voies : une réponse récupérée et un corps de requête Express. Il a fallu plusieurs tentatives, et Imperva n'a pas publié l'exploit.
Jusqu'où cela va
Le bug se trouve dans le décodeur de référence en C de Google, dont de nombreux projets livrent leur propre copie. Un recensement publié sur broccoli2shell.com indique des correctifs pour Bun 1.4.4, Envoy, Istio, Chromium, Firefox, ngx_brotli et les paquets Python Brotli 1.2.1 et brotlicffi 1.2.1.0. Au 24 octobre, il listait encore des copies non corrigées dans .NET, les extensions brotli pour PHP et Ruby, DuckDB, ClickHouse, Apache Arrow, la bibliothèque JPEG XL, des forks de 7-Zip et MuPDF.
Les distributions Linux corrigent la bibliothèque partagée libbrotli séparément. Debian, par exemple, l'a fait dans ses mises à jour de sécurité pour bookworm et trixie. Une preuve de concept publique est apparue sur GitHub le 22 octobre, mais elle n'exécuterait du code que sur une version volontairement affaiblie. Aucune attaque réelle n'avait alors été signalée.
Ce qu'il faut vérifier
- Navigateurs : Chrome, Edge et Firefox décompressent du Brotli sur presque chaque page. Installez la dernière mise à jour et redémarrez le navigateur.
- Node.js et Bun : lancez node --version. Tout ce qui est inférieur à 22.23.4, 24.22.1 ou 26.12.1, ou une branche en fin de vie comme la 20, doit être mis à jour. Bun doit être en 1.4.4 au minimum.
- Python : lancez pip show Brotli brotlicffi. Si l'un d'eux est antérieur à 1.2.1, mettez-le à jour ou désinstallez-le : requests repassera alors sur gzip.
- Serveurs : appliquez la mise à jour libbrotli de la distribution, puis redémarrez chaque service qui la charge. Un processus en cours garde l'ancien décodeur en mémoire jusqu'à son redémarrage.
Ce dernier point passe facilement inaperçu. Le gestionnaire de paquets peut installer le correctif dans la nuit, tandis que PHP, Python et d'autres processus de longue durée continuent pendant des semaines avec l'ancienne copie. Pour qui gère son propre serveur, c'est le deuxième « mettre à jour puis redémarrer » du mois, après les failles de NGINX.