Faille PHP2Shell : comment protéger ton serveur dès maintenant

Faille PHP2Shell (CVE-2026-109618 et 109619) : qui est touché, quelles versions installer et comment protéger ton serveur PHP, même sous Docker.

Introduction

Le 20 octobre au soir, l'équipe de PHP a annoncé une mise à jour de sécurité en urgence pour le lendemain. Le 21, la faille PHP2Shell était corrigée, et elle occupait déjà tous les fils d'actualité sécu.

Il y a de quoi : deux CVE notées 9,2 sur 10, de l'exécution de code à distance sans authentification, et un moteur qui fait tourner une énorme partie du web. WordPress, Drupal, Magento, Laravel, mais aussi des classiques du homelab comme Nextcloud, phpMyAdmin ou FreshRSS.

Dans cet article, je fais le point sur ce qu'on sait, je t'aide à savoir si ton serveur est exposé, et je te montre comment corriger : avec apt, avec Docker, ou chez un hébergeur. Et si tu ne peux pas mettre à jour tout de suite, les contournements officiels sont à la fin.

Glossaire

Terme Définition
CVE Identifiant unique attribué à une vulnérabilité publique
CVSS Score de gravité d'une faille, de 0 à 10. Au-dessus de 9, c'est critique
RCE Remote Code Execution : un attaquant fait exécuter son code sur ta machine, à distance
SAPI La façon dont PHP est branché au serveur web (PHP-FPM, mod_php, CGI...)
PHP-FPM Le gestionnaire de processus PHP utilisé avec Nginx, et le plus souvent avec Apache aujourd'hui
mod_php PHP chargé directement dans Apache. Ancienne méthode, encore répandue
Worker Un processus PHP qui traite les requêtes les unes après les autres
Backport Correctif appliqué par une distribution sur une version plus ancienne, sans changer le numéro de version principal
WAF Pare-feu applicatif web, qui filtre les requêtes HTTP malveillantes

Faille PHP2Shell : que s'est-il passé ?

La chronologie est courte, et un peu chaotique (détails chez Sansec) :

  • Août 2026 : les failles sont découvertes puis signalées à l'équipe PHP par les chercheurs de Calif, puis par Wiz Research. Une divulgation coordonnée est prévue pour le jeudi 22 octobre.
  • 20 octobre : des informations fuitent avant la date. watchTowr confirme que les failles sont réelles. L'équipe PHP avance la publication au lendemain (annonce sur oss-security), et le CERT-EU publie une alerte (avis 2026-018).
  • 21 octobre : PHP publie les versions corrigées dans l'après-midi. Le matin même, Cloudflare signalait déjà les premières tentatives d'attaque. Plusieurs preuves de concept circulent publiquement. Aux Pays-Bas, certaines communes ont même mis leurs sites hors ligne par précaution.

Le surnom PHP2Shell résume bien l'enjeu : une requête bien construite, et l'attaquant obtient un shell sur ton serveur.

Détail intéressant : selon Wiz, ces bugs existaient depuis très longtemps, mais leur exploitation demandait une chaîne d'étapes extrêmement complexe. Ce sont des modèles d'IA récents qui ont permis de la mettre au point. Attends-toi à voir ce scénario se répéter.

Les deux CVE en clair

Les deux failles sont distinctes, mais l'équipe PHP recommande de traiter les deux ensemble.

CVE Nom officiel Ce qui se passe
CVE-2026-109618 RCE via corruption mémoire (OOM) Une requête d'upload forgée pousse PHP à dépasser sa limite mémoire au pire moment. Le nettoyage de fin de requête lit ensuite des données à moitié initialisées
CVE-2026-109619 RCE via état global périmé Après une erreur fatale, une partie de l'état interne n'est pas nettoyée. La requête suivante traitée par le même worker réutilise de la mémoire déjà libérée

Deux points importants :

  1. La faille est dans le moteur PHP, pas dans ton code. Une application parfaitement écrite est vulnérable si le PHP en dessous ne l'est pas. Mettre à jour WordPress ou tes plugins ne corrige rien ici.
  2. Une fonctionnalité activée par défaut sert de porte d'entrée. La progression d'upload des sessions (session.upload_progress) fait partie des chemins confirmés, même si ton application n'utilise jamais les sessions.

Pour une analyse plus poussée du code en cause, l'article de JFrog Security Research est une bonne lecture.

Est-ce que ton serveur est concerné ?

D'après l'avis de PHP, toute installation qui sert des requêtes web est à risque : PHP-FPM, Apache avec mod_php, php-cgi, FrankenPHP et LiteSpeed. Le risque est maximal avec mod_php, où l'exploitation a été confirmée avant même que le code de l'application ne s'exécute. Selon le CERT-EU, les versions concernées remontent jusqu'à PHP 5.

Un PHP utilisé uniquement en ligne de commande (scripts cron, outils CLI) n'est pas la cible décrite. Mets-le à jour quand même.

Pour faire l'inventaire sur une machine Debian ou Ubuntu :

# Version de PHP par défaut
php -v

# Toutes les versions installées
ls /etc/php/

# Apache utilise-t-il mod_php ?
apache2ctl -M 2>/dev/null | grep -E 'mpm_|php'

Si la dernière commande affiche mpm_prefork_module et php_module (ou php8.x_module), tu es en mod_php : c'est ta priorité numéro un.

Côté Docker, ne te fie pas qu'aux noms d'images. nextcloud, wordpress ou phpmyadmin embarquent PHP sans le dire. Vérifie directement dans chaque conteneur :

docker exec -it NOM_DU_CONTENEUR php -v

Si tu gères un parc plus large, le NCSC néerlandais tient à jour une liste de logiciels qui dépendent de PHP potentiellement concernés.

Comment corriger la faille PHP2Shell ?

Les versions à installer

Branche Version corrigée Statut
8.5 8.5.12 Supportée
8.4 8.4.27 Supportée
8.3 8.3.36 Correctifs de sécurité uniquement
8.2 8.2.35 Correctifs de sécurité uniquement, fin de vie le 31 décembre 2026
8.1 et avant Aucune version officielle Fin de vie

Les sources sont sur la page de téléchargement de PHP, et le calendrier de support de chaque branche sur la page Supported Versions.

Pour les versions en fin de vie, l'équipe PHP a exceptionnellement publié des backports minimaux en code source pour 7.4, 8.0 et 8.1, destinés à ceux qui compilent eux-mêmes (Help Net Security). Sinon, regarde du côté de ta distribution ou d'un fournisseur de support étendu. La vraie solution reste de migrer vers une branche supportée.

Sur Debian ou Ubuntu

sudo apt update && sudo apt upgrade

Puis redémarre PHP. Sans redémarrage, les workers continuent de tourner avec l'ancien code :

sudo systemctl restart php8.3-fpm   # adapte à ta version
sudo systemctl restart apache2      # si tu utilises mod_php

Attention au piège de la vérification : les distributions backportent souvent le correctif sans changer le numéro de version. php -v peut donc afficher une version inférieure à celles du tableau alors que tu es protégé. Pour en avoir le cœur net, cherche les CVE dans le journal des modifications du paquet :

zgrep -E 'CVE-2026-10961[89]' /usr/share/doc/php8.3-common/changelog.Debian.gz

Tu es protégé si la version est au moins celle du tableau, ou si cette commande trouve les deux CVE. Tu peux aussi consulter le suivi de ta distribution : Debian Security Tracker ou Ubuntu CVE. Sinon, le correctif n'est pas encore arrivé dans ton dépôt : applique les contournements de la section suivante en attendant.

Si tu utilises le dépôt d'Ondřej Surý (ppa:ondrej/php ou packages.sury.org), il publie habituellement les correctifs très vite. Sur Red Hat et dérivés, le dépôt communautaire de Remi n'avait pas de mise à jour le jour même : passe par les paquets de ta distribution. AlmaLinux détaille par exemple ses backports flux par flux.

Sous Docker

Avec l'image officielle php utilisée directement :

docker compose pull
docker compose up -d
docker compose exec app php -v

Si ton image est construite à partir d'un Dockerfile qui commence par FROM php:..., il faut reconstruire en forçant la récupération de l'image de base :

docker compose build --pull
docker compose up -d

Pour les images tierces (Nextcloud, WordPress, LinuxServer.io...), tout dépend du rythme de leur mainteneur. Vérifie la version dans le conteneur après chaque pull. Si elle n'est pas encore corrigée, monte les contournements par volume (voir plus bas). C'est le même principe de mise à jour que dans mon tuto sur la seedbox avec Docker.

Sur un hébergement mutualisé

Tu n'as pas la main sur le PHP du serveur. Vérifie la version dans ton panneau d'administration et, si besoin, ouvre un ticket chez ton hébergeur. Si ton site passe par Cloudflare, des règles WAF contre les vecteurs connus ont été déployées pour tous les clients, y compris en offre gratuite. C'est une rustine bienvenue, pas un correctif.

Que faire si tu ne peux pas mettre à jour tout de suite ?

L'avis de PHP liste des réglages qui ferment certains chemins d'attaque. Ils réduisent l'exposition, ils ne rendent pas ton installation sûre.

Contre CVE-2026-109619 :

  • Désactive session.upload_progress.enabled. Peu d'applications s'en servent, et PHP conseille de le laisser désactivé même après la mise à jour si tu n'en as pas besoin. Ce réglage doit être posé dans php.ini, un fichier de conf.d ou le pool FPM : ni ini_set() ni .user.ini, qui s'appliquent trop tard.
  • Supprime les réglages PHP invalides ou obsolètes définis par répertoire (.htaccess, PHP_VALUE transmis par Nginx ou Apache) qui génèrent des avertissements. Masquer ces avertissements avec display_errors ou @ ne protège pas.

Contre CVE-2026-109618 :

  • Baisse post_max_size : 8M si tes applications n'acceptent pas d'upload, 32M sinon, avec upload_max_filesize en dessous.
  • L'avis propose aussi memory_limit = -1, imposé de façon non modifiable par l'application (php_admin_value dans la configuration du pool FPM), avec une limite mémoire au niveau du conteneur ou du cgroup en garde-fou. C'est un réglage à manier avec prudence : tu retires la limite mémoire par requête.

Sur Debian/Ubuntu avec PHP-FPM :

echo 'session.upload_progress.enabled = 0' | sudo tee /etc/php/8.3/fpm/conf.d/99-php2shell.ini
sudo systemctl restart php8.3-fpm

Sous Docker, avec une image basée sur l'image officielle php, crée un fichier php2shell.ini à côté de ton docker-compose.yml :

session.upload_progress.enabled = 0
post_max_size = 32M
upload_max_filesize = 16M

Puis monte-le dans le dossier de configuration de PHP :

services:
  app:
    image: php:8.4-fpm
    volumes:
      - ./php2shell.ini:/usr/local/etc/php/conf.d/99-php2shell.ini:ro

Pour une image tierce, le dossier conf.d peut être ailleurs : vérifie-le avec php --ini dans le conteneur.

Enfin, si tu es en mod_php, passer à PHP-FPM supprime les chemins d'attaque confirmés qui ne dépendent pas de l'application. Et si un service exposé ne peut être ni corrigé ni durci, le CERT-EU et le NCSC britannique recommandent la même chose : le couper d'internet le temps de régler le problème.

Après le correctif : vérifie que tu n'as pas été visité

Mettre à jour ferme la porte, mais ne chasse pas quelqu'un qui serait déjà entré. Quelques vérifications rapides, inspirées des recommandations de SOCRadar :

  • Les processus : un worker PHP qui lance un sh, un bash, un curl ou un wget n'a rien de normal. Regarde l'arborescence avec ps -ef --forest.
  • Les fichiers PHP récents dans ta racine web :
sudo find /var/www -name '*.php' -newermt '2026-10-20' -ls
  • Les tâches planifiées de l'utilisateur web :
sudo crontab -l -u www-data
  • Les logs : des rafales de requêtes POST en multipart/form-data vers des URL inhabituelles méritent un coup d'œil.

Une fois les services redémarrés, vérifie qu'ils répondent tous : c'est exactement le rôle d'un outil comme Uptime Kuma. Il te dira si c'est en ligne, pas si c'est compromis.

En cas de doute sérieux : isole la machine, conserve les logs, et réinstalle plutôt que de nettoyer. Et si le serveur héberge des données personnelles, une compromission est une violation de données au sens du RGPD, avec notification à la CNIL sous 72 heures.

FAQ

Mon site WordPress est-il concerné par PHP2Shell ?

Oui, si le PHP de ton serveur n'est pas à jour. La faille est dans le moteur, pas dans WordPress : mettre à jour le CMS ou les plugins ne suffit pas. Sansec a d'ailleurs confirmé l'exploitation sur plusieurs applications PHP courantes.

Je suis en PHP 7.4 ou 8.1, je fais quoi ?

Il n'y a pas de version officielle corrigée pour ces branches. Vérifie si ta distribution propose un backport, applique les contournements, et planifie la migration vers une branche supportée.

Cloudflare me protège-t-il complètement ?

Non. Les règles WAF bloquent les vecteurs connus aujourd'hui. Une variante qu'elles ne reconnaissent pas passera. Seule la mise à jour corrige la faille.

Faut-il redémarrer après la mise à jour ?

Oui. PHP-FPM et Apache gardent l'ancien code en mémoire tant qu'ils ne sont pas redémarrés.

Conclusion

PHP2Shell rappelle une règle simple : tu ne peux pas corriger ce que tu ne sais pas que tu possèdes. Le plus long, aujourd'hui, n'est pas de taper apt upgrade, c'est de retrouver tous les endroits où PHP tourne : le VPS oublié, le conteneur Nextcloud, le phpMyAdmin de test.

Fais cet inventaire maintenant, garde-le à jour, et la prochaine faille de ce calibre te prendra dix minutes au lieu d'une soirée. Vu la vitesse à laquelle les exploits arrivent désormais, il y en aura une prochaine.

Et toi, combien d'instances PHP as-tu découvertes en faisant le tour de ton infra ?

Sources

Cet article vous a plu ?

Avec un compte gratuit, vous aimez, vous commentez et vous recevez des suggestions « Pour vous ». Connexion en un clic avec Google ou GitHub, sans mot de passe.

Commentaires

Connectez-vous en un clic pour rejoindre la discussion.

Chargement des commentaires…

Masquer ce commentaire ?

Il ne sera plus visible du public. Son texte est conservé et vous pourrez le rétablir. Ses réponses restent visibles.

Signaler ce commentaire

Pourquoi ?