← Retour à la liste

La faille CVE-2026-42945 de Nginx, restée latente pendant 18 ans : principe, PoC et correctifs décryptés

itadol5j

Nginx CVE-2026-42945

🚨 CVE-2026-42945 : une faille critique de Nginx restée latente pendant 18 ans — principe, PoC et correctifs

Le 13 mai 2026, le cabinet de recherche en sécurité depthfirsta révélé conjointement avec F5 l'une des failles les plus critiques de l'histoire de NGINX — CVE-2026-42945 :

  • Score CVSS v4.0 de 9.2 : une vulnérabilité de gravité critique
  • Dépassement de tampon sur le tas (heap) : peut conduire à une exécution de code à distance (RCE)
  • 18 ans de latence : le code était présent dans la base depuis 2008
  • 9,75 millions de sites touchés dans le monde : plus de 2,54 millions de sites web en Chine concernés
  • PoC public : reproduction confirmée par QiAnXin

Il s'agit d'une faille historique du cœur même de NGINX : l'attaquant peut prendre le contrôle du serveur à distance avec une simple requête HTTP spécialement forgée.

🔍 Aperçu de la vulnérabilité

Informations générales

Propriété Détails
Identifiant de la faille CVE-2026-42945
Score CVSS v4.0: 9.2 | v3.1: 8.1
Type de faille Dépassement de tampon sur le tas (Heap-based Buffer Overflow)
Type de menace Exécution de code à distance (RCE), déni de service (DoS)
Conditions d'exploitation Aucune authentification requise, une simple requête HTTP suffit
Composant concerné ngx_http_rewrite_module (module natif au cœur de NGINX)
Découverte par depthfirst (découverte par un système automatisé en 6 heures)

Portée de l'impact

  • 9,75 millions de sites dans le mondeconcernés
  • 2,54 millions de sites web en Chineconcernés
  • NGINX sert environ 1/3 des sites web mondiaux, d'où une surface d'impact immense
  • Le code est présent depuis 2008, soit une latence de 18 ans

⚠️ Conditions de déclenchement

Trois conditions à réunir simultanément

Le déclenchement de la faille exige une combinaison précise de conditions de configuration :

Condition Description Exemple
1. Capture PCRE anonyme la directive rewrite utilise des groupes de capture anonymes $1, $2, $3…
2. Chaîne de remplacement contenant un point d'interrogation la chaîne de remplacement contient un caractère ? /profile.php?id=$1&tab=$2
3. Suivie d'une directive rewrite/if/set la directive rewrite est immédiatement suivie d'une autre directive rewrite … last; if (…) { … }

Exemple de configuration vulnérable

# 易受攻击配置
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
# 后跟其他指令
if ($arg_debug) {
    set $debug_flag 1;
}

Cette configuration réunit les trois conditions : captures anonymes $1/$2, chaîne de remplacement contenant un ?, suivie d'une directive if.

🔬 Fonctionnement de la faille

Une incohérence d'état entre deux phases de traitement

Le moteur de script de NGINX fonctionne en deux phases :

  • Phase 1 : calcul de la taille de tampon nécessaire
  • Phase 2 : copie des données dans le tampon

Le cœur de la faille tient à une mauvaise gestion de l'indicateur is_args :

Phase État de is_args Logique de traitement Résultat
Phase de calcul de longueur is_args = 0 renvoie la longueur brute des captures taille du tampon sous-estimée
Phase de copie des données is_args = 1 appelle ngx_escape_uri : chaque octet peut s'étendre à 3 octets dépassement de tampon sur le tas

Déroulé détaillé

  1. La directive rewrite contient des captures anonymes $1/$2
  2. La chaîne de remplacement contient un ?, ce qui force is_args = 1
  3. Phase de calcul de longueur : un sous-moteur fraîchement initialisé est utilisé, avec is_args = 0
  4. il renvoie la longueur brute : un tampon de tas trop petit est alloué
  5. Phase de copie des données : le moteur principal prend le relais, avec is_args = 1
  6. il appelle ngx_escape_uri : les octets s'étendent et débordent du tampon
  7. Les données d'URI contrôlées par l'attaquant s'écrivent dans la zone de débordement

Mode d'exploitation

Heap Feng Shui à travers plusieurs requêtes :

  • corps de requêtes POST pour asperger la mémoire du tas (car les URI ne peuvent pas contenir d'octets null)
  • Les données du débordement corrompent le pointeur cleanup d'une structure ngx_pool_t adjacente
  • une structure ngx_pool_cleanup_s forgée , pointant vers system()
  • Lors de la destruction du pool, l'appel à system() est déclenché
  • et la RCE est obtenue

Effet de l'ASLR

  • ASLR activé : uniquement un plantage du processus worker (DoS)
  • ASLR désactivé : l'exécution de code à distance (RCE) devient possible

📊 Versions concernées

NGINX Open Source

Plage de versions Version corrigée
0.6.27 – 1.30.0 1.31.0, 1.30.1

NGINX Plus

Plage de versions Version corrigée
R32 – R36 R36 P4, R35 P2, R32 P6

Autres composants concernés

  • NGINX Instance Manager : 2.16.0 – 2.21.1
  • NGINX App Protect WAF : 4.9.0 – 5.8.0
  • NGINX Ingress Controller : 3.5.0 – 5.4.1
  • NGINX Gateway Fabric : 1.3.0 – 2.5.1
  • F5 DoS for NGINX : 4.8.0

🔥 État du PoC

PoC public

  • Dépôt GitHub :https://github.com/DepthFirstDisclosures/Nginx-Rift
  • Reproduction confirmée par QiAnXin : les chercheurs du centre de threat intelligence ont réussi à la reproduire
  • Détails techniques publiés : depthfirst a publié son analyse technique
  • Exploitation en conditions réelles : aucun cas recensé à ce jour

Mode d'emploi du PoC

# 构建容器
./setup.sh

# 启动易受攻击的 NGINX 服务器
docker compose -f env/docker-compose.yml up

# 执行 PoC 获取 Shell
python3 poc.py --shell

✅ Correctifs

Méthode 1 : mettre à jour les versions

# 升级到修复版本
NGINX Open Source >= 1.31.0
NGINX Open Source >= 1.30.1
NGINX Plus >= R32 P6
NGINX Plus >= R36 P4

# 升级后重启 NGINX
nginx -s reload

Méthode 2 : modifier la configuration (mesure d'atténuation)

Remplacer les groupes de capture anonymes par des groupes de capture nommés :

# 易受攻击配置(未命名捕获)
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;

# 修复后配置(命名捕获)
rewrite ^/users/(?[0-9]+)/profile/(?.*)$ /profile.php?id=$user_id&tab=$section last;

Les groupes de capture nommés ne déclenchent pas la faille.

Méthode 3 : vérifier sa configuration

Rechercher les configurations vulnérables :

# 搜索易受攻击的 rewrite 指令
grep -E "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/nginx.conf
grep -rE "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/conf.d/

🔍 Processus de découverte

Découverte par un système automatisé

depthfirst : son système d'analyse de sécurité a,

  • en 6 heures, trouvé 5 problèmes
  • dont 4 confirmés par NGINX
  • CVE-2026-42945est la plus grave des failles
  • Elle remonte à 2008 et est présente dans presque toutes les builds standards

Autres failles associées

  • CVE-2026-42946 : corruption mémoire
  • CVE-2026-40701 : corruption mémoire
  • CVE-2026-42934 : corruption mémoire

📝 En résumé

CVE-2026-42945est l'une des failles les plus critiques de l'histoire de NGINX :

  • 18 ans de latence : le code est présent dans la base depuis 2008
  • CVSS 9.2 : dépassement de tampon sur le tas, pouvant mener à une RCE
  • Conditions de déclenchement : directive rewrite avec captures anonymes + chaîne de remplacement contenant un ? + suivie d'une autre directive
  • Portée : 9,75 millions de sites dans le monde, dont 2,54 millions de sites web en Chine
  • PoC public : dépôt GitHub + reproduction confirmée par QiAnXin
  • Correctifs : mise à jour des versions ou adoption de groupes de capture nommés

Une faille restée 18 ans dans l'ombre vient d'éclater : il est vivement conseillé de mettre à jour ou d'ajuster sa configuration sans tarder.

Annonce officielle :https://my.f5.com/manage/s/article/K000161019

Dépôt du PoC :https://github.com/DepthFirstDisclosures/Nginx-Rift

Analyse technique :https://depthfirst.com/research/nginx-rift