Apache HTTP Server HTTP/2 RCE, corrigé en 2.4.71 (CVE-2026-119618)
Faille de concurrence dans mod_http2 d'Apache HTTP Server : un client HTTP/2 non authentifié peut corrompre la mémoire ; corrigée en 2.4.71.
En bref
- Le module mod_http2 d'Apache HTTP Server écrit un en-tête
Content-Lengthsynthétique dans une table partagée avec le thread de connexion. Apache qualifie la faille de critique. Red Hat lui attribue un score CVSS v3.1 de 9,8. - Les versions 2.4.55 à 2.4.70 sont concernées lorsque HTTP/2 est activé avec h2 ou h2c. Les serveurs qui ne parlent qu'HTTP/1.1 ne sont pas concernés.
- Red Hat indique que des recherches publiques ont démontré un exploit fiable contre un serveur configuré par défaut. Aucun code d'exploit public n'est lié, et aucune exploitation réelle n'est connue ; le CVE n'est pas dans le catalogue KEV de la CISA au 2026-11-12.
- Mettez à niveau vers 2.4.71 ou vers le paquet corrigé de votre distribution. Si vous ne pouvez pas, désactivez HTTP/2 ; voir « Comment corriger ? ».
Suis-je concerné ?
Vous êtes exposé si toutes ces conditions sont réunies :
- Vous exécutez Apache HTTP Server 2.4.55 à 2.4.70.
mod_http2est chargé et HTTP/2 est activé, viaProtocols h2 http/1.1pour TLS ouh2cpour le trafic en clair.- Des clients non fiables peuvent atteindre ce listener HTTP/2, directement ou via un proxy qui transmet HTTP/2 à Apache.
Les serveurs configurés uniquement pour HTTP/1.1 ne sont pas concernés. Red Hat indique que RHEL 8 et les versions antérieures ne sont pas concernées, car leur mod_http2 est antérieur à la version 2.0.8.
RHEL 9 et RHEL 10 sont concernés, mais classés Important. Red Hat explique que chaque flux HTTP/2 est alloué à partir d'un allocateur distinct, ce qui augmente sensiblement la complexité de l'exploitation. L'avis Apache liste mod_h2 2.0.8 à 2.0.42 comme concerné ; la version 2.4.71 embarque le module corrigé.
| Branche | Versions concernées | Version corrigée |
|---|---|---|
| Apache HTTP Server 2.4.x | 2.4.55 à 2.4.70 | 2.4.71 |
Apache est utilisé par 20,9 % des sites web dont le serveur web est connu, selon W3Techs. La plage concernée ne représente qu'une partie de ces déploiements, car HTTP/2 doit être activé.
Vérifiez la version installée et l'activation de HTTP/2 :
# Debian and Ubuntu
apache2 -v
apache2ctl -M | grep http2
# RHEL, Fedora and other RPM distributions
httpd -v
httpd -M | grep http2
# The Protocols directive shows whether h2 or h2c is enabled
grep -R "Protocols" /etc/apache2 /etc/httpd 2>/dev/null
Pour un conteneur, vérifiez le processus en cours plutôt qu'une image fraîchement téléchargée :
docker exec <container> apache2 -v
docker exec <container> apache2ctl -M | grep http2
Sur RHEL, httpd -v affiche toujours la version de base 2.4 après le correctif. La mise à jour de sécurité modifie le paquet mod_http2, il faut donc comparer ce paquet avec l'avis :
rpm -q mod_http2
RHEL 9.9 embarque mod_http2-2.0.26-7.el9_9.1, selon la page CVE de Red Hat. RHEL 10.3 embarque mod_http2-2.0.29-5.el10_3.1. Les versions antérieures de mod_http2 sur ces branches sont concernées.
Comment corriger ?
Mettez à niveau vers Apache HTTP Server 2.4.71, ou installez le paquet mod_http2 corrigé publié par votre distribution. Red Hat a publié les rétroportages le 2026-11-11. Le DSA-6620-1 de Debian liste apache2 2.4.71 pour Debian 13.
- Mettez à jour le paquet : ```bash # Debian and Ubuntu sudo apt update sudo apt install --only-upgrade apache2
# RHEL and Fedora
sudo dnf update httpd mod_http2
2. Confirmez la version corrigée. Sur Debian 13, `apache2 -v` affiche 2.4.71. Les versions plus anciennes de Debian et d'Ubuntu reçoivent le correctif rétroporté dans leur série existante : comparez la version affichée par `dpkg -s apache2` avec celle du DSA ou de l'USN de votre version. Sur RHEL, comparez `rpm -q mod_http2` avec la version du paquet indiquée dans l'avis.
3. Redémarrez Apache pour charger le nouveau module :bash
sudo systemctl restart apache2 # Debian et Ubuntu
sudo systemctl restart httpd # RHEL et Fedora
```
4. Reconstruisez et recréez chaque image de conteneur qui embarque Apache. Télécharger une nouvelle image ne suffit pas si le conteneur en cours utilise encore l'ancienne couche.
Si vous compilez depuis les sources, utilisez l'archive de la version 2.4.71 du projet Apache HTTP Server.
Si vous ne pouvez pas mettre à niveau immédiatement, désactivez HTTP/2. La faille se trouve dans le chemin de requête HTTP/2, donc supprimer ce chemin la ferme. Le coût est la perte du bénéfice de performance du multiplexage.
- Sur Debian et Ubuntu, désactivez le module et redémarrez :
bash sudo a2dismod http2 sudo systemctl restart apache2 - Sur RHEL et Fedora, commentez la ligne
LoadModule http2_moduleet vérifiez queProtocolsne liste nih2nih2c, puis redémarrez :bash sudo systemctl restart httpd - Sur toute distribution, confirmez la disparition du module avec
apache2ctl -M | grep http2ouhttpd -M | grep http2. Aucune sortie signifie que HTTP/2 est désactivé.
Un proxy inverse qui termine HTTP/2 et transmet HTTP/1.1 à Apache supprime ce chemin côté backend. Le proxy lui-même peut rester concerné s'il exécute une version d'Apache vulnérable. Désactiver HTTP/2 est une solution de contournement, pas un correctif ; le module corrigé est la réponse durable.
Quelle est la cause racine ?
mod_http2 traduit les trames HTTP/2 en une structure request_rec interne, et assign_headers() copie les en-têtes de requête analysés dans la table d'en-têtes de la requête. Le bug vient d'une branche qui écrit un en-tête Content-Length synthétique dans la table source partagée au lieu de la copie propre à la requête.
La fonction se trouve dans modules/http2/h2_request.c. Voici le code à l'étiquette 2.4.70 :
static void assign_headers(request_rec *r, const h2_request *req,
int no_body, int is_connect)
{
const char *cl;
r->headers_in = apr_table_clone(r->pool, req->headers);
if (req->authority && !is_connect) {
...
apr_table_setn(r->headers_in, "Host", req->authority);
}
/* Unless we open a byte stream via CONNECT, apply content-length guards. */
if (!is_connect) {
cl = apr_table_get(req->headers, "Content-Length");
if (no_body) {
if (!cl && apr_table_get(req->headers, "Content-Type")) {
/* If we have a content-type, but already seen eos, no more
* data will come. Signal a zero content length explicitly.
*/
apr_table_setn(req->headers, "Content-Length", "0");
}
}
req->headers est la table d'en-têtes analysée pour le flux sur la connexion. r->headers_in est un clone alloué dans le pool de la requête, et c'est la table que lisent les modules Apache. La fonction reçoit req comme const h2_request *, elle n'est donc pas censée le modifier. La branche Host de ce snippet écrit dans r->headers_in, ce qui montre la cible prévue. La branche Content-Length est l'exception.
Le déclencheur est étroit et ne nécessite pas de corps. no_body est vrai lorsque le client place END_STREAM sur la trame HEADERS, donc aucun corps de requête ne suit. Si cette requête possède un Content-Type et aucun Content-Length, la branche s'exécute.
apr_table_setn() ajoute une nouvelle clé, ce qui agrandit la table et alloue de la mémoire dans le pool de la table. Ce pool appartient à la connexion et au flux, alors que l'écriture s'exécute sur le thread de travail du flux. Red Hat décrit le résultat comme un thread de travail qui écrit dans la mémoire du thread de connexion via un allocateur partagé et sans verrou.
Les tables et les pools APR ne sont pas thread-safe. Une allocation ou un parcours concurrent de la même table peut donc corrompre le tas. L'avis classe la faille comme un problème d'exécution concurrente avec une synchronisation incorrecte (CWE-362), et la description d'Apache nomme directement assign_headers().
Comment la faille est-elle exploitée ?
- L'attaquant ouvre une connexion HTTP/2 vers le serveur, via TLS avec h2 ou en clair avec h2c.
- L'attaquant envoie de nombreuses requêtes HEADERS concurrentes sur cette connexion. Chaque requête porte
:method,:path,:authorityet unContent-Type, et place END_STREAM sansContent-Length. - Chaque requête atteint
assign_headers()sur un thread de travail avecno_bodyactivé. Le thread ajouteContent-Length: 0à la tablereq->headerspartagée. - Pendant que le thread alloue dans cette table, le thread de connexion et les autres threads peuvent lire ou allouer dans la même table et le même pool. La course corrompt le tas.
- Apache indique que la corruption peut mener à l'exécution de code à distance. Un plantage du thread ou du processus serveur est l'issue la plus simple.
L'avis ne publie pas de code d'exploit. Red Hat indique que des recherches publiques ont démontré un exploit fiable contre un serveur configuré par défaut avec mod_http2 activé, et classe la faille critique pour cette raison. Aucune exploitation réelle n'est connue au 2026-11-12.
Comment se déroule l'attaque ?
Un client HTTP/2 non authentifié envoie une requête sans corps qui porte un Content-Type mais aucun Content-Length, et l'écriture synthétique du thread de travail entre en course avec l'allocateur du thread de connexion jusqu'à corrompre le tas.
flowchart LR
A["Client HTTP/2<br/>HEADERS + END_STREAM"] --> B["mod_http2 active<br/>no_body"]
B --> C["assign_headers()<br/>Content-Type, pas de Content-Length"]
C --> D["apr_table_setn(req->headers)<br/>table partagée, thread de travail"]
D --> E["allocateur partagé<br/>du thread de connexion"]
E --> F["corruption du tas"]
F --> G["plantage ou exécution<br/>de code à distance"]
Que peut faire un attaquant ?
Un attaquant non authentifié qui peut atteindre un listener HTTP/2 peut faire planter le serveur. Si la corruption du tas est façonnée en primitive utile, il peut exécuter du code avec l'utilisateur qui lance Apache. L'avis d'Apache indique que la faille peut mener à l'exécution de code à distance. Red Hat va plus loin et affirme qu'une exploitation réussie permet des commandes arbitraires, le contrôle total du processus serveur et l'accès à des données sensibles.
Red Hat note la faille CVSS v3.1 9,8, CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.
Les conditions sont celles de « Suis-je concerné ? » : une version 2.4 concernée, mod_http2 chargé, HTTP/2 activé et une accessibilité réseau. L'attaquant n'a besoin d'aucun compte et d'aucune interaction utilisateur.
L'exploitation dépend d'une course, donc sa fiabilité varie avec la charge, la disposition de l'allocateur et le nombre de flux concurrents. Red Hat classe RHEL 9 et RHEL 10 Important plutôt que Critique pour cette raison, tout en les listant comme concernés.
Un plantage est un déni de service, pas une exécution de code. Les sources décrivent l'exécution de code comme possible et, selon Red Hat, démontrée en recherche. Aucune source ne publie d'exploit fonctionnel ni de rapport de victime.
Pourquoi le correctif fonctionne-t-il ?
Le correctif modifie une ligne dans assign_headers() pour que l'en-tête synthétique aille dans le clone propre à la requête :
@@ -350,7 +350,7 @@ static void assign_headers(request_rec *r, const h2_request *req,
/* If we have a content-type, but already seen eos, no more
* data will come. Signal a zero content length explicitly.
*/
- apr_table_setn(req->headers, "Content-Length", "0");
+ apr_table_setn(r->headers_in, "Content-Length", "0");
}
}
r->headers_in est alloué dans le pool de la requête et n'est utilisé que par le thread qui traite ce flux. La table req->headers partagée n'est plus modifiée après la création du clone, donc le thread de travail cesse d'écrire dans la mémoire du thread de connexion. L'en-tête synthétique atteint toujours les modules en aval, car ils lisent r->headers_in.
Le changement couvre la seule écriture dans req->headers de assign_headers(). L'autre écriture d'en-tête de la même fonction, pour Host, utilisait déjà r->headers_in. Le correctif ne modifie ni le framing HTTP/2 ni la gestion du corps de requête.
Comment vérifier si j'ai été compromis ?
Aucun indicateur de compromission n'est publié pour cette faille. Une exploitation réussie peut ne laisser aucune trace au-delà de la mémoire corrompue, et une tentative ratée peut seulement faire planter un thread.
Cherchez les plantages et les sorties inattendues de processus enfants dans le journal d'erreurs d'Apache, surtout sur les serveurs qui exposaient HTTP/2 avant le correctif :
grep -Ei "segfault|signal 11|child pid .* exit|AH00051" /var/log/apache2/error.log
grep -Ei "segfault|signal 11|child pid .* exit|AH00051" /var/log/httpd/error_log
Sur un hôte systemd, listez les core dumps du binaire Apache :
coredumpctl list apache2
coredumpctl list httpd
Un plantage est une piste, pas une preuve d'exploitation, car d'autres bugs et limites de ressources peuvent aussi tuer un thread. Si vous trouvez des plantages répétés sur un serveur HTTP/2 qui exécutait une version concernée, conservez les journaux et les core dumps avant de redémarrer. Traitez l'hôte comme potentiellement compromis jusqu'à la fin de votre examen.
Chronologie
- 2026-10-26 : l'OSS Scanner d'Anthropic signale la faille à l'équipe de sécurité d'Apache sous la référence ANT-2026-MAPKT6MZ.
- 2026-11-03 : Anthony Weems et Simon Scannell, de Google Cloud Vulnerability Research, signalent la faille indépendamment.
- 2026-11-09 : le correctif arrive sur la branche 2.4.x avec le commit
824beab, un cherry-pick du commit5ed3928de master. - 2026-11-11 : Apache publie 2.4.71 et l'avis CVE-2026-119618. Red Hat publie le même jour ses paquets
mod_http2corrigés et ses avis.
FAQ
Cette faille concerne-t-elle les serveurs uniquement HTTP/1.1 ?
Non. La faille se trouve dans le chemin de requête HTTP/2. Un serveur qui charge mod_http2 mais ne négocie qu'HTTP/1.1 n'atteint pas assign_headers().
Mon proxy inverse termine TLS. Mon backend Apache est-il exposé ?
Cela dépend du protocole entre le proxy et Apache. Si le proxy transmet HTTP/2, le backend est exposé. S'il transmet HTTP/1.1, ce chemin est fermé côté backend, mais le proxy lui-même peut exécuter une version d'Apache concernée.
Existe-t-il un exploit public ?
Aucun code d'exploit public n'est lié depuis l'avis Apache ni depuis l'enregistrement CVE. Red Hat indique que des recherches publiques ont démontré un exploit fiable contre un serveur configuré par défaut avec mod_http2 activé.
CVE-2026-119618 est-il dans le catalogue KEV de la CISA ?
Non. Le CVE n'était pas dans le catalogue Known Exploited Vulnerabilities de la CISA au 2026-11-12, et aucune exploitation réelle n'est connue.
Quelles versions de RHEL sont concernées ?
RHEL 9 et RHEL 10 sont concernés et classés Important. RHEL 8 et les versions antérieures ne sont pas concernés, car leur mod_http2 est antérieur à 2.0.8. Installez la version du paquet mod_http2 indiquée dans l'avis Red Hat pour votre branche.
Pourquoi httpd -v affiche-t-il encore 2.4.57 après la mise à jour RHEL ?
Red Hat a rétroporté le correctif dans le paquet mod_http2 au lieu de changer la version d'httpd. Comparez rpm -q mod_http2 avec la version corrigée du paquet, pas avec la chaîne de version d'httpd.
Références
- Page de sécurité d'Apache HTTP Server, avis CVE-2026-119618, publié le 2026-11-11 : https://httpd.apache.org/security/vulnerabilities_24.html (consulté le 12 novembre 2026)
- Enregistrement CVE-2026-119618, CNA Apache Software Foundation, publié le 2026-11-11 : https://www.cve.org/CVERecord?id=CVE-2026-119618 (consulté le 12 novembre 2026)
- Commit du correctif sur la branche 2.4.x, 824beab, 2026-11-09 : https://github.com/apache/httpd/commit/824beab9b9424d6cfb29595248fdbf6c3dddeab1 (consulté le 12 novembre 2026)
- Commit du correctif upstream sur master, 5ed3928, 2026-11-09 : https://github.com/apache/httpd/commit/5ed39287660daacd1233cb9bbc984b25fa9a4fe3 (consulté le 12 novembre 2026)
- Page CVE-2026-119618 de Red Hat, CVSS v3.1 9.8 et paquets mod_http2 corrigés, publiée le 2026-11-11 : https://access.redhat.com/security/cve/CVE-2026-119618 (consulté le 12 novembre 2026)
- Suivi de sécurité Debian pour CVE-2026-119618, DSA-6620-1 et apache2 2.4.71 corrigé : https://security-tracker.debian.org/tracker/CVE-2026-119618 (consulté le 12 novembre 2026)
- W3Techs, part d'utilisation d'Apache, 20,9 % des sites dont le serveur web est connu : https://w3techs.com/technologies/details/ws-apache (consulté le 12 novembre 2026)