← Retour aux actualités

PHP2Shell : les failles critiques CVE-2026-109618 et CVE-2026-109619 qui exposent tous vos serveurs PHP

Publié le 22/10/2026

Introduction

Il arrive rarement qu'une vulnérabilité touche non pas une application, mais le moteur d'exécution lui-même. PHP2Shell est de ceux-là. <cite index="3-1">Le 21 octobre 2026, PHP a publié des mises à jour de sécurité pour deux vulnérabilités critiques d'exécution de code à distance (RCE), CVE-2026-109618 et CVE-2026-109619, toutes deux notées 9,2 en CVSS v4.0.</cite> <cite index="4-1">La divulgation coordonnée a été précédée d'une fuite en ligne le 20 octobre, avant même que les correctifs ne soient disponibles</cite>, exposant des millions de serveurs dans un intervalle particulièrement critique.

1. Ce que font ces deux failles

Les deux vulnérabilités partagent une origine commune : la façon dont PHP gère la mémoire en cas d'erreur fatale pendant le traitement d'une requête.

CVE-2026-109618 — Corruption mémoire lors d'un OOM (Out of Memory)

<cite index="4-1">CVE-2026-109618 est une faille d'exécution de code à distance dans la gestion des erreurs de dépassement mémoire de PHP. Si PHP manque de mémoire pendant l'initialisation des données d'une requête, il est interrompu et ces données sont seulement partiellement initialisées.</cite> <cite index="7-1">La routine de nettoyage traite ensuite ces données corrompues comme si elles étaient valides, ce qui ouvre la porte à une exécution de code arbitraire. CVE-2026-109618 peut également provoquer une fuite mémoire similaire à Heartbleed : le gestionnaire de progression de téléchargement de PHP peut retourner de la mémoire libérée du worker au client, dans un cookie de réponse PHPSESSID.</cite>

CVE-2026-109619 — État global obsolète après libération mémoire

<cite index="4-1">CVE-2026-109619 est une faille d'exécution de code à distance causée par le fait que PHP conserve un état interne lié à une requête après que la mémoire qui le supporte a été libérée. Si le même worker traite une requête ultérieure, PHP peut accéder à cet état périmé avant que l'initialisation normale ne le réinitialise.</cite>

En pratique, <cite index="5-1">le vecteur d'attaque confirmé pour CVE-2026-109619 est le gestionnaire session.upload_progress de PHP, qui se déclenche sur n'importe quel endpoint POST avant même que le code de l'application ne s'exécute.</cite>

2. Qui est concerné ?

<cite index="6-1">Toute installation PHP servant des requêtes web est concernée, notamment PHP-FPM, Apache avec mod_php, php-cgi, FrankenPHP et LiteSpeed.</cite>

<cite index="2-1">Toutes les versions de PHP de 5.4 à 8.5.11 sont vulnérables. Les versions corrigées sont PHP 8.5.12, 8.4.27, 8.3.36 et 8.2.35. Le projet PHP ne publie pas de correctifs pour PHP 8.1 et antérieur, déclarés en fin de vie.</cite>

Les applications concernées incluent, sans s'y limiter : <cite index="7-1">Magento 2.4.9, WordPress 7.1.2, Drupal 11.4.3, Joomla 6.1.4, MediaWiki, Roundcube, phpMyAdmin 5.2.3, Nextcloud 35.0.1, Laravel</cite> — et toute application PHP développée en interne utilisant les uploads de fichiers ou les sessions.

<cite index="6-1">Amazon Threat Intelligence a enregistré via son réseau honeypot MadPot une tentative d'exploitation de PHP2Shell dès le 17 octobre 2026, soit quatre jours avant la divulgation publique officielle.</cite>

3. La solution définitive : mettre à jour PHP

<cite index="8-1">La mise à jour est la seule remédiation complète. Le projet PHP le dit explicitement dans les deux avis de sécurité.</cite>

Version PHPVersions affectéesPremière version corrigée
PHP 8.5< 8.5.128.5.12
PHP 8.4< 8.4.278.4.27
PHP 8.3< 8.3.368.3.36
PHP 8.2< 8.2.358.2.35
PHP 8.1 et antérieurToutes versionsAucun patch officiel

4. Tips : correctif temporaire pour ceux qui ne peuvent pas mettre à jour PHP

⚠️ Avertissement important : ces mesures réduisent l'exposition mais ne rendent pas l'installation sécurisée. Elles ne constituent pas une protection complète et ne dispensent pas d'une mise à jour dès que possible. Appliquez-les toutes ensemble, pas séparément.

<cite index="19-1">Appliquez les deux mitigations temporaires ensemble dans la configuration PHP effective : elles couvrent chacune une faille différente, il ne faut pas en appliquer une seule.</cite>

Étape 1 — Désactiver session.upload_progress (couvre CVE-2026-109619)

<cite index="15-1">La mise en œuvre de la progression d'upload de session de PHP constitue le vecteur principal d'exploitation. Désactivez session.upload_progress.enabled dans les directives principales de votre php.ini.</cite>

Localisez votre fichier php.ini principal. Sur Debian/Ubuntu avec PHP 7.3 :

bash
# Vérifier le chemin du php.ini actif selon votre SAPI
php --ini                         # SAPI CLI
php-fpm7.3 -i | grep php.ini     # SAPI PHP-FPM (adapter le nom du binaire)

Ajoutez ou modifiez la ligne suivante dans /etc/php/7.3/fpm/php.ini et /etc/php/7.3/apache2/php.ini selon votre configuration :

ini
; Désactive le gestionnaire de progression d'upload (vecteur CVE-2026-109619)
; Ce mécanisme permet à un attaquant de déclencher un use-after-free via un POST multipart
session.upload_progress.enabled = Off

Pour PHP-FPM : vérifiez également que les pools ne remettent pas cette valeur à On. Dans chaque fichier de pool (/etc/php/7.3/fpm/pool.d/www.conf par exemple) :

ini
; Force la désactivation même si une application tente de la réactiver via .user.ini
php_admin_flag[session.upload_progress.enabled] = off

Pour Apache avec mod_php : ajoutez également dans /etc/apache2/conf-available/php7.3.conf ou dans un fichier de configuration dédié :

apache
# Désactive session.upload_progress au niveau du serveur web
# php_admin_* empêche les applications de le réactiver via .user.ini ou ini_set()
php_admin_flag session.upload_progress.enabled Off

Étape 2 — Désactiver la limite mémoire (couvre CVE-2026-109618)

<cite index="3-1">Pour CVE-2026-109618 : imposer memory_limit = -1 au niveau administrateur, et le coupler avec des limites de requêtes au niveau du frontal et des limites mémoire sur le conteneur.</cite>

⚠️ Attention : memory_limit = -1 supprime toute limite de mémoire par requête. Un seul worker peut alors consommer toute la RAM disponible. Surveillez la mémoire du serveur après application et remettez une valeur réelle dès que le patch est appliqué.

Dans /etc/php/7.3/fpm/php.ini :

ini
; Supprime la limite mémoire pour empêcher l'attaque OOM qui déclenche CVE-2026-109618
; ATTENTION : sans limite, une requête peut consommer toute la RAM disponible
; À coupler OBLIGATOIREMENT avec des limites au niveau du reverse proxy ou WAF
memory_limit = -1

Dans le pool PHP-FPM (www.conf) :

ini
; Force la valeur même si une application essaie de la modifier via ini_set()
php_admin_value[memory_limit] = -1

Compensez cette absence de limite au niveau de votre reverse proxy ou serveur web, par exemple sous Apache :

apache
# Limite la taille des requêtes POST pour réduire le risque d'épuisement mémoire
# en l'absence de memory_limit PHP (mitigation partielle CVE-2026-109618)
LimitRequestBody 8388608

Étape 3 — Redémarrer les services PHP

bash
# Redémarrer PHP-FPM
systemctl restart php7.3-fpm

# Redémarrer Apache si mod_php est utilisé
systemctl restart apache2

# Vérifier que la configuration est bien prise en compte
php7.3 -i | grep session.upload_progress.enabled   # doit afficher "Off"
php7.3 -i | grep memory_limit                      # doit afficher "-1"

Étape 4 — Vérifier qu'aucun fichier .user.ini ne réactive la fonctionnalité

<cite index="11-1">Sans verrouillage explicite via php_admin_*, un fichier .user.ini présent dans le répertoire d'une application peut réactiver session.upload_progress.enabled = On et annuler la mitigation.</cite>

bash
# Rechercher tous les fichiers .user.ini qui réactiveraient la fonctionnalité
# Adapter le chemin /var/www selon votre arborescence web
grep -r "session.upload_progress.enabled" /var/www/ --include="*.ini" --include=".user.ini"

Pour les environnements Docker / conteneurs

Ajoutez dans votre Dockerfile (ajuster le chemin selon l'image de base) :

dockerfile
# Mitigation temporaire PHP2Shell (CVE-2026-109618 / CVE-2026-109619)
# À retirer une fois l'image PHP mise à jour vers une version corrigée
RUN echo 'session.upload_progress.enabled=Off' > /usr/local/etc/php/conf.d/zz-php2shell.ini && \
    echo 'memory_limit=-1' >> /usr/local/etc/php/conf.d/zz-php2shell.ini

Pour les backports communautaires sur PHP 7.x et 8.0/8.1

<cite index="16-1">Des patchs communautaires de backport sont disponibles pour PHP 5.6, 7.x, 8.0 et 8.1 sur le dépôt GitHub Anton-Barinov/php2shell-patches, compilés et testés par la communauté. Ces patchs incluent des corrections minimales officielles ainsi qu'une variante améliorée qui permet de conserver la fonctionnalité session.upload_progress fonctionnelle après correction.</cite> Ces patchs nécessitent une recompilation de PHP depuis les sources — à réserver aux équipes disposant de l'expertise nécessaire et d'un environnement de test.

Les points de vigilance

<cite index="6-1">Le NCSC britannique (National Cyber Security Centre) invite les organisations à envisager de mettre hors ligne tout système qui ne peut pas être corrigé immédiatement.</cite> Si vous gérez des environnements PHP 7.3 ou PHP 7.4 sur des infrastructures de production inaccessibles à une mise à jour rapide, c'est le moment d'escalader la priorité de cette montée de version auprès de votre direction ou de vos clients. La présence d'un reverse proxy ou d'un WAF devant vos serveurs PHP ne constitue pas non plus une protection suffisante par lui-même : l'exploitation peut passer par des requêtes POST légitimes en apparence.

Conclusion

PHP2Shell est l'une des failles PHP les plus critiques depuis des années : elle touche le moteur d'exécution lui-même, pas une application en particulier, et elle est exploitable sans authentification sur des configurations par défaut depuis PHP 5.4. La mise à jour vers PHP 8.2.35, 8.3.36, 8.4.27 ou 8.5.12 reste la seule solution définitive. Pour les environnements qui ne peuvent pas être mis à jour immédiatement — et en particulier pour ceux encore sur PHP 7.3 ou 7.4 — la combinaison session.upload_progress.enabled = Off et memory_limit = -1, correctement verrouillée au niveau du pool PHP-FPM et du serveur web, constitue la meilleure parade temporaire disponible aujourd'hui. À appliquer sans délai.