Node2Shell, aussi appelée HTTP2Shell, est le surnom de la CVE-2026-111497 : un dépassement de tampon (écriture hors limites) dans le décodeur Brotli de Google, la bibliothèque de compression utilisée par Node.js, Python, .NET, Bun, Envoy, curl et la plupart des distributions Linux. Notée 9.2 en CVSS v4.0 (9.8 en CVSS 3.1 par le NVD), elle est exploitée activement et figure depuis le 27 octobre 2026 au catalogue KEV de la CISA. Voici ce qu’elle touche vraiment, comment savoir si votre serveur est concerné, et le retour d’expérience d’un correctif appliqué sur un serveur de production.
CVE-2026-111497 : ce qu’il faut retenir
- Composant : le décodeur de la bibliothèque Google Brotli (
c/dec/decode.c), et toutes les copies qui en sont embarquées - Type : écriture hors limites (CWE-787) liée à une valeur de retour non vérifiée (CWE-252). Un flux compressé piégé peut faire planter le processus, faire fuiter de la mémoire, voire exécuter du code
- Sévérité : CVSS v4.0 = 9.2 (critique), vecteur
AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H; NVD : CVSS 3.1 = 9.8 - Versions vulnérables : Brotli 1.0.3 à 1.2.0
- Versions corrigées : Brotli 1.0.10, 1.1.1 et 1.2.1 ; Node.js 22.23.4, 24.22.1, 26.12.1 ; Bun 1.4.4 ; Python
Brotli1.2.1 etbrotlicffi1.2.1.0 ; .NET 8.0.33, 9.0.22, 10.0.14 - Pas de correctif pour Node.js 20, 23 et 25, en fin de vie
- Découverte : OpenAI Codex Security (Khai Tran et Sylvie Mayer) ; correctif côté Node.js par Matteo Collina et Antoine du Hamel
Node2Shell, HTTP2Shell, Python2Shell : une seule faille
Le nom a changé trois fois en une semaine, ce qui a semé la confusion. La faille a d’abord été révélée par la release de sécurité de Node.js le 21 octobre, d’où « Node2Shell ». Le 23 octobre, des chercheurs ont montré que les paquets Python Brotli et brotlicffi embarquaient le même décodeur (« Python2Shell »), puis Aikido a proposé « HTTP2Shell », plus juste puisque le défaut se trouve dans une bibliothèque partagée et pas dans un runtime en particulier. Bun a repris ce nom le 24 octobre.
Attention en revanche à « html2shell » : ce nom ne correspond à aucune vulnérabilité réelle. Il vient d’une coquille dans un titre de blog et d’une blague sur X. Il n’existe qu’un seul identifiant à suivre : CVE-2026-111497.
Chronologie de la faille Brotli
| Date (2026) | Événement |
|---|---|
| 14/10 | Node.js préannonce une release de sécurité pour le 21 octobre |
| 21/10 | Node.js 22.23.4, 24.22.1 et 26.12.1 corrigent dix CVE, dont celle-ci. Google publie le soir même Brotli 1.0.10, 1.1.1 et 1.2.1. Vercel déploie des règles WAF |
| 22/10 | Google, CNA de Brotli, publie l’enregistrement CVE (CVSS 4.0 : 9.2). Imperva publie son analyse « Node2Shell » avec une exécution de code sur l’image officielle Node.js 24.22.0 arm64. Avis CERT-FR CERTFR-2026-AVI-1367 |
| 23-24/10 | Le périmètre s’élargit : Python, puis Bun (1.4.4 le 22/10) et Envoy. Les noms Python2Shell et HTTP2Shell apparaissent |
| 25/10 | Microsoft publie son avis pour .NET (dotnet/announcements #494). Ubuntu prépare ses correctifs |
| 26/10 | ELLIO observe un premier trafic d’exploitation réel sur ses capteurs. Ubuntu publie l’USN-8956-1. Annonce sur oss-security |
| 27/10 | La CISA ajoute la CVE au catalogue KEV (échéance fédérale : 10 novembre) |
| 28/10 | Le NVD finalise son analyse : CVSS 3.1 = 9.8. Alerte AL26-027 du Centre canadien pour la cybersécurité. Les images Docker officielles (wordpress, etc.) sont reconstruites |
Node2Shell est-il exploité ? Le point au 30 octobre 2026
Oui, mais encore timidement. La CISA a inscrit la faille au KEV « sur la base de preuves d’exploitation active », sans dire qui est visé. Les observations publiques restent rares :
- ELLIO a enregistré le 26 octobre une requête d’exploitation de 23 Mo visant Node.js 24.22.0 sur x86-64. Dans ses tests, cette chaîne « de première génération » fait planter le processus sans obtenir de shell. ELLIO a aussi repéré un scanner de reconnaissance (
node2shell-check/1.0) - Imperva et ELLIO ont reproduit une exécution de code sur des builds officiels non modifiés de Node.js 24.22.0, après plusieurs tentatives
- Des preuves de concept circulent sur GitHub depuis le 22 octobre. Les versions publiques font surtout planter les builds standards
Un détail compte pour la suite : l’exploitation exige une valeur propre à chaque build. Mais un processus qui plante est souvent relancé automatiquement (systemd, PM2, Kubernetes), ce qui offre à l’attaquant autant de nouvelles tentatives. Un simple crash n’est donc pas anodin.
Le bug, expliqué simplement
Brotli découpe les données en blocs et peut « changer de type de bloc » en cours de flux. La fonction chargée de ce changement renvoyait la même réponse (« il me faut plus de données ») dans deux cas très différents : quand le flux était réellement incomplet, et quand il était invalide. Dans le second cas, le décodeur continuait d’accumuler des octets dans un petit tampon interne de 8 octets qui n’était jamais vidé… et finissait par écrire au-delà.
Le correctif amont (commit 0ed4268a) ajoute un code d’erreur dédié, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17) : un flux invalide est désormais rejeté immédiatement. C’est aussi ce code qui permet de vérifier simplement qu’un Node.js est corrigé (voir plus bas).
Qui est concerné par la CVE-2026-111497 ?
Le risque n’existe que si un programme décompresse des données Brotli contrôlées par un attaquant. Avoir la bibliothèque installée ne suffit pas à être exposé, mais c’est la bibliothèque qu’il faut corriger. Il y a trois portes d’entrée :
- Les requêtes entrantes envoyées avec
Content-Encoding: br, si l’application les décode : Express 5 avecexpress.json()ouexpress.raw(), body-parser 2, Koa avec@koa/bodyparser, Envoy/Istio. Un serveur HTTP Node.js nu ne décode pas les corps de requête de lui-même - Les réponses sortantes :
fetch(), axios, got,requests/httpx/aiohttpen Python, curl/libcurl… décompressent automatiquement une réponsebr. Il suffit alors que votre application interroge un serveur malveillant ou compromis (webhook, flux RSS, API tierce, scraping) - Les appels directs au décodeur sur des données fournies par un client (
node:zlib, traitement de fichiers, FFmpeg, Apache Arrow, ClickHouse, DuckDB…)
| Logiciel | Versions corrigées | Remarque |
|---|---|---|
| Google Brotli (libbrotli) | 1.0.10, 1.1.1, 1.2.1 | Les distributions rétroportent le correctif sans changer de version (voir ci-dessous) |
| Node.js | 22.23.4, 24.22.1, 26.12.1 | Brotli embarqué. 20.x, 23.x et 25.x : aucun correctif |
| Bun | 1.4.4 | Penser aussi aux exécutables bun build --compile |
Python Brotli / brotlicffi | 1.2.1 / 1.2.1.0 | GHSA-9v8h-qqgm-4m35. Concerne urllib3, requests, httpx, aiohttp, Scrapy |
| .NET | 8.0.33, 9.0.22, 10.0.14 | Windows, Linux et macOS |
Ubuntu (libbrotli1) | 22.04 : 1.0.9-2ubuntu0.1 ; 24.04 : 1.1.0-2ubuntu0.1 ; 26.04 : 1.2.0-3ubuntu0.1 | USN-8956-1 et -2. Le paquet nodejs d’Ubuntu 20.04 reste vulnérable (Brotli embarqué) |
Debian (libbrotli1) | 12 : 1.0.9-2+deb12u1 ; 13 : 1.1.0-2+deb13u1 | DLA-4855-1 et DSA-6582-1. Le paquet nodejs Debian n’est pas encore corrigé |
Et PHP ou WordPress ? PHP n’utilise Brotli que de façon indirecte, via libcurl, lorsqu’il télécharge quelque chose (mises à jour, appels d’API d’extensions). C’est donc l’image Docker ou le système qui doit être à jour, pas WordPress. Les modules mod_brotli d’Apache et ngx_brotli de nginx servent surtout à compresser les réponses. La faille est dans le décodeur.
Retour d’expérience : ce que l’audit d’un vrai serveur a révélé
J’ai audité et corrigé ce 30 octobre un serveur de production : Ubuntu 22.04, plusieurs sites WordPress en Docker, un serveur mail docker-mailserver, de la supervision Zabbix et quelques outils Node.js. Quatre constats, dont trois pièges :
- Le système était déjà corrigé… sur le disque. Les mises à jour automatiques avaient installé
libbrotli1 1.0.9-2ubuntu0.1. Ubuntu a rétroporté le correctif sans changer de version : un scanner qui ne regarde que le « 1.0.9 » vous dira à tort que vous êtes vulnérable. Seul le changelog fait foi. - Mais pas en mémoire. Le serveur Zabbix, démarré une semaine plus tôt, utilisait toujours l’ancienne bibliothèque, effacée du disque mais encore chargée. Or Zabbix décompresse les réponses de ses scénarios de supervision web. Un simple redémarrage a suffi, encore fallait-il le voir.
- Les conteneurs ont leur propre copie. Les images
wordpress:php8.xet docker-mailserver embarquaientlibbrotli1 1.1.0-2+b7(Debian 13), vulnérable. Les images WordPress officielles avaient été reconstruites le 28 octobre : il a suffi de recréer les conteneurs, environ 10 secondes de coupure par site. Celle de docker-mailserver ne l’était pas encore : correctif appliqué à l’intérieur du conteneur en attendant, en sachant qu’il disparaîtra à la prochaine recréation. - Le Node.js était en fin de vie. Une version 20 installée via NodeSource pour des outils internes ne sera jamais corrigée. Migration vers la 22.23.4. Autre piège :
process.versions.brotliaffiche la même version avant et après le correctif, ce n’est pas un indicateur fiable.
Bonne nouvelle : aucune trace des indicateurs publiés (IP, User-Agent du scanner) dans les journaux. Les commandes qui suivent sont celles qui ont servi à cet audit.
Étape 1 : inventorier toutes les copies de Brotli
La bibliothèque système, et la preuve que le correctif est bien présent :
# Debian / Ubuntu
dpkg -l | grep -i brotli
apt changelog libbrotli1 | grep -m1 CVE-2026-111497 # une ligne = correctif présent
# RHEL / Fedora / Alma / Rocky
rpm -qa | grep -i brotli
rpm -q --changelog brotli | grep -m1 CVE-2026-111497
Les processus qui tournent encore avec l’ancienne version (le piège n°2) :
sudo grep -l 'libbrotli.*(deleted)' /proc/[0-9]*/maps 2>/dev/null \
| cut -d/ -f3 | xargs -r ps -o pid,lstart,comm -p
# ou, sur Debian/Ubuntu :
sudo needrestart -r l
Les conteneurs Docker, un par un :
for c in $(docker ps --format '{{.Names}}'); do
echo "$c : $(docker exec "$c" sh -c 'dpkg-query -W -f="\${Version}" libbrotli1 2>/dev/null || apk info -v 2>/dev/null | grep brotli' 2>/dev/null)"
done
Node.js, Python et .NET :
node -v
# -17 = corrigé ; "undefined" = vulnérable (constante ajoutée par le correctif)
node -p "require('zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH"
pip list 2>/dev/null | grep -iE '^(brotli|brotlicffi) '
dotnet --list-runtimes
Pensez aussi aux copies qu’on oublie : runners CI, fonctions serverless, exécutables Bun compilés, environnements virtuels Python, images de base de vos propres builds.
Étape 2 : appliquer le correctif CVE-2026-111497
Système : mettez à jour le paquet, puis redémarrez les services qui l’utilisent. C’est l’étape la plus souvent oubliée :
sudo apt update && sudo apt install --only-upgrade libbrotli1
sudo needrestart -r a # ou redémarrage ciblé : systemctl restart <service>
Conteneurs : téléchargez l’image, vérifiez qu’elle contient bien le correctif, puis recréez le conteneur. Un simple docker restart ne change pas l’image :
docker pull wordpress:php8.3
docker run --rm --entrypoint sh wordpress:php8.3 -c 'dpkg-query -W libbrotli1'
# attendu (Debian 13) : 1.1.0-2+deb13u1
docker compose up -d --force-recreate wordpress
Si l’éditeur n’a pas encore reconstruit son image, un correctif provisoire est possible à l’intérieur du conteneur. Il sera perdu à la prochaine recréation, donc à noter et à surveiller :
docker exec <conteneur> sh -c 'apt-get update && apt-get install -y --only-upgrade libbrotli1'
Node.js : passez à 22.23.4, 24.22.1 ou 26.12.1 minimum. Si vous êtes en 20.x (fin de vie), changez de branche. Avec NodeSource, il suffit de modifier le dépôt (node_20.x → node_22.x) puis de réinstaller nodejs. Vérifiez au préalable que vos dépendances n’ont pas de modules natifs à recompiler (find node_modules -name '*.node'). Mettre à jour Express ou body-parser ne corrige pas la faille : elle est dans le runtime.
Python : pip install -U 'brotli>=1.2.1' (ou 'brotlicffi>=1.2.1.0') dans chaque environnement, puis regénérez vos fichiers de verrouillage. .NET : runtimes 8.0.33, 9.0.22 ou 10.0.14, puis recompilez les applications autonomes (self-contained).
Les contournements si vous ne pouvez pas patcher tout de suite
Rejetez les corps de requête compressés en Brotli au niveau du reverse proxy. Rares sont les applications légitimes qui en reçoivent :
# Apache (dans le VirtualHost du reverse proxy)
<If "%{HTTP:Content-Encoding} =~ /br/i">
Require all denied
</If>
# nginx (dans le bloc server)
if ($http_content_encoding ~* "br") { return 415; }
Côté Express/body-parser, l’option inflate: false refuse les corps encodés. Ces mesures ne protègent pas le cas des réponses téléchargées par vos applications (fetch(), curl…). Pour celui-là, il n’y a que le correctif. Les règles WAF restent un pis-aller : Vercel, qui en a déployé dès le 21 octobre, précise lui-même qu’elles « ne remplacent pas le correctif ».
Le reverse proxy reste votre meilleure première ligne, à condition d’être lui-même à jour : voir aussi HTTP/2 Bomb (CVE-2026-49975) et NGINX Rift (CVE-2026-42945).
Détection : mon serveur a-t-il été visé ?
- Indicateurs publiés par ELLIO : IP source
94.154.43.7, User-AgentMozilla/5.0 (compatible; node2shell-check/1.0), corps de requête de 23 069 983 octets (SHA-2567fcbdaae…c93c5c4b) - Crashs répétés d’un worker Node.js ou Python qui accepte du Brotli, ou flux qui restent bloqués : c’est la signature la plus probable d’une tentative
- Gros POST (plusieurs Mo) vers des API qui n’en reçoivent jamais
- Core dumps : un crash peut écrire sur disque des cookies de session, jetons et clés. Limitez qui peut les lire et combien de temps ils sont conservés
sudo zgrep -hE '94\.154\.43\.7|node2shell' /var/log/apache2/*access*.log* /var/log/nginx/access.log* 2>/dev/null
journalctl --since "2026-10-21" | grep -iE 'brotli|SIGSEGV|core dumped' | tail
coredumpctl list --since 2026-10-21 2>/dev/null
Par défaut, ni Apache ni nginx ne journalisent l’en-tête Content-Encoding des requêtes. Pour garder une trace, ajoutez %{Content-Encoding}i (Apache) ou $http_content_encoding (nginx) à votre format de log.
Les scanners automatisés intègrent ce type de faille en quelques jours : pour voir à quoi ressemble ce trafic sur un vrai serveur exposé, lisez notre bestiaire des attaques de bots sur un honeypot SSH.
CVE-2026-111497 en résumé : que faire selon votre situation
| Vous avez… | Action |
|---|---|
| Un serveur Linux à jour | Vérifier le changelog de libbrotli1 et redémarrer les services qui chargent encore l’ancienne version |
| Des conteneurs Docker | Télécharger les nouvelles images, vérifier la version de Brotli dans l’image, recréer les conteneurs |
| Des applications Node.js | 22.23.4 / 24.22.1 / 26.12.1 minimum ; quitter la 20.x ; reconstruire les images |
| Des applications Python | Brotli ≥ 1.2.1 ou brotlicffi ≥ 1.2.1.0 dans chaque environnement |
Une API qui accepte des corps br | Priorité maximale. Bloquer Content-Encoding: br au proxy en attendant le correctif |
| Un simple site WordPress mutualisé | Rien à faire de votre côté : c’est l’hébergeur qui doit mettre à jour le système |
FAQ Node2Shell
Qu’est-ce que la CVE-2026-111497 ?
Une écriture hors limites dans le décodeur de la bibliothèque de compression Google Brotli (versions 1.0.3 à 1.2.0). Un flux compressé piégé peut provoquer un crash, une fuite de mémoire ou une exécution de code. Elle est notée 9.2 en CVSS v4.0 et surnommée Node2Shell ou HTTP2Shell.
Node2Shell ne concerne-t-elle que Node.js ?
Non. Node.js a été le premier à publier un correctif, d’où le nom, mais la faille est dans Brotli. Elle touche aussi Python, .NET, Bun, Envoy, curl et les paquets libbrotli des distributions Linux, donc les conteneurs Docker.
Ma version libbrotli 1.0.9 ou 1.1.0 est-elle vulnérable ?
Pas forcément : Debian et Ubuntu rétroportent le correctif sans changer le numéro de version. Les versions corrigées sont par exemple 1.0.9-2ubuntu0.1 (Ubuntu 22.04) ou 1.1.0-2+deb13u1 (Debian 13). Vérifiez le changelog du paquet.
Comment savoir si mon Node.js est corrigé ?
La version doit être au moins 22.23.4, 24.22.1 ou 26.12.1. La commande node -p "require('zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH" renvoie -17 sur une version corrigée. process.versions.brotli n’est pas fiable.
La faille est-elle exploitée ?
Oui : la CISA l’a ajoutée au catalogue KEV le 27 octobre 2026. Les tentatives observées publiquement restent peu nombreuses et provoquent surtout des crashs, mais une exécution de code a été démontrée sur des builds officiels de Node.js.
Divulgation responsable
Cet article est publié à des fins défensives et pédagogiques. Il s’appuie exclusivement sur des informations rendues publiques par les mainteneurs (Google Brotli, Node.js, Microsoft, Debian, Ubuntu), par des organismes officiels (CISA, CERT-FR, Centre canadien pour la cybersécurité) et par des acteurs reconnus (Imperva, ELLIO, Rescana). Il ne contient volontairement aucun détail d’exploitation et ne renvoie vers aucun code d’exploit. Toute vérification doit se faire uniquement sur des systèmes vous appartenant, en environnement isolé. Attaquer un système tiers sans autorisation écrite est illégal.
À lire aussi
- PHP2Shell (CVE-2026-109618 et CVE-2026-109619) : faille critique dans PHP, corrigée le même jour
- wp2shell : RCE non authentifiée dans le cœur de WordPress
- Comment2Shell : d’un commentaire WordPress à l’exécution de code
- HTTP/2 Bomb (CVE-2026-49975) : un octet pour faire tomber un serveur
- NGINX Rift (CVE-2026-42945) : une faille vieille de 18 ans
Sources
- CVE.org — Enregistrement CVE-2026-111497 (CNA Google)
- NVD — CVE-2026-111497 (CVSS 3.1 : 9.8)
- Google — Brotli v1.2.1
- Node.js — October 2026 Security Releases
- Node.js — Changelog 22.23.4 (cherry-pick 0ed4268a)
- CISA — CISA Adds Two Known Exploited Vulnerabilities to Catalog (27/10/2026)
- CERT-FR — CERTFR-2026-AVI-1367 : Multiples vulnérabilités dans Node
- Centre canadien pour la cybersécurité — AL26-027 : vulnérabilité critique touchant Google Brotli
- Ubuntu — CVE-2026-111497 (USN-8956-1 / -2)
- Debian — Security Tracker CVE-2026-111497 (DSA-6582-1, DLA-4855-1)
- Microsoft — .NET advisory #494
- GitHub Advisory — GHSA-9v8h-qqgm-4m35 (Python Brotli / brotlicffi)
- Imperva — Node2Shell: From Brotli Data to Remote Code Execution
- ELLIO — Node2Shell: RCE on stock Node.js builds (trafic d’exploitation et IOC)
- Rescana — CVE-2026-111497 Node2Shell : chronologie et périmètre
- Help Net Security — Brotli bug reaches far beyond Node.js
- BleepingComputer — CISA warns of hackers now exploiting critical Node2Shell flaw