PHP2Shell est le nom donné à deux failles critiques d’exécution de code à distance sans authentification dans PHP : CVE-2026-109618 et CVE-2026-109619, notées 9.2 sur 10. Le correctif est sorti le 21 octobre 2026 : PHP 8.5.12, 8.4.27, 8.3.36 et 8.2.35. Voici ce que dit l’avis officiel de cette faille PHP, les risques pour vos sites, les contournements si vous ne pouvez pas mettre à jour tout de suite, et la procédure de mise à jour.
Mis à jour le 21 octobre 2026 après la publication de l’avis de sécurité officiel de PHP et des advisories GitHub GHSA-w8hw-w9fx-j79w et GHSA-6wmf-4rv5-p3rp.
PHP2Shell : deux RCE dans PHP lui-même, corrigées dans l’urgence
Il ne s’agit pas d’une faille dans un CMS ou une extension, mais dans l’interpréteur PHP : WordPress, Nextcloud, Magento, Drupal, Laravel, vos outils internes… tout ce qui sert des requêtes web en PHP est concerné. La divulgation devait se faire sous embargo le jeudi 22 octobre ; les identifiants CVE et une capture d’un outil d’exploitation ont fuité la veille, ce qui a poussé l’équipe PHP à publier le 21 octobre, et même un peu en avance sur l’horaire annoncé (14h00 UTC).
- Type : exécution de code à distance (RCE) non authentifiée, avec les droits du worker web
- Sévérité : CVSS v4.0 = 9.2 (critique) pour les deux CVE, vecteur
AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H - Versions vulnérables : toutes les versions antérieures à 8.2.35, 8.3.36, 8.4.27 et 8.5.12, ainsi que les branches en fin de vie (8.1 et antérieures)
- Versions corrigées : PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35
- PHP 7.4, 8.0 et 8.1 : pas de release officielle, mais des backports minimaux du correctif publiés sous forme de branches sources par l’équipe PHP
- Découverte : lcfr-hax, sagitzadik-wiz (Wiz), tomash-areion, amyb-oai ; correctifs par arnaud-lb, iluuu1994, bukka et ndossche
Chronologie de la fuite PHP2Shell
| Date (UTC) | Événement |
|---|---|
| 20/10, 15h20 | Un post sur Hacker News annonce deux divulgations RCE imminentes dans PHP |
| 20/10 | PHP publie un avis anticipé de release de sécurité critique pour le 21/10 à 14h00 UTC. watchTowr confirme que les failles sont réelles. CERT-EU publie un avis |
| 21/10, 02h13 | Un développeur du cœur PHP déclare que la seule mitigation est la mise à jour |
| 21/10, 07h43 | Cloudflare signale les premières attaques contre des sites PHP et déploie des règles WAF |
| 21/10, 08h48 | La PHP Foundation prévient que le dépôt de Remi (RHEL/Fedora) ne sera pas mis à jour le jour même |
| 21/10, 10h35 | Selon Sansec, plusieurs sites néerlandais (Tweakers, Tweede Kamer, NCSC, Security.NL) passent hors ligne |
| 21/10, ~13h30 | Publication de PHP 8.5.12, 8.4.27, 8.3.36 et 8.2.35, de l’avis de sécurité et des deux advisories GitHub |
CVE-2026-109618 et CVE-2026-109619 : ce que dit l’avis officiel
CVE-2026-109618 — RCE via corruption en cas de manque mémoire (OOM)
Pour interrompre une requête qui dépasse sa mémoire, PHP utilisait un saut brutal (longjmp()). Dans certains contextes, ce saut survient alors que des données internes de la requête ne sont que partiellement initialisées ; la phase de nettoyage de fin de requête les traite ensuite comme valides. Un attaquant capable de provoquer ce manque de mémoire au bon moment peut transformer cet état incohérent en exécution de code.
Le point d’entrée cité par l’avis est le parsing des requêtes multipart, que PHP effectue avant toute ligne de code applicatif. Le correctif supprime purement et simplement le longjmp() en cas d’OOM.
CVE-2026-109619 — RCE via état global périmé (use-after-free)
Un worker PHP persistant (qui traite plusieurs requêtes à la suite) peut conserver un état global — erreurs, session, objets, extensions — pointant vers de la mémoire appartenant à une requête précédente, déjà libérée. Certaines opérations exécutées avant l’initialisation normale de la requête suivante lisent cet état : c’est un use-after-free classique (CWE-416). Il faut qu’une première requête laisse cet état derrière elle (erreur fatale, OOM, timeout…) et qu’une seconde tombe sur le même worker ; plusieurs workers et leur recyclage réduisent les chances de succès sans supprimer le risque.
Quels modes d’exécution de PHP sont touchés ?
| SAPI | CVE-2026-109618 (OOM) | CVE-2026-109619 (état périmé) |
|---|---|---|
| Apache + mod_php | RCE complète démontrée en HTTP, avec les limites par défaut | RCE confirmée (chemin fatal backtrace, PHP 8.5) |
| PHP-FPM | Vulnérable selon l’analyse du code, pas d’exploit complet démontré | Chemin session.upload_progress validé |
| FrankenPHP | Probablement vulnérable (analogue à mod_php) | Pas de chemin établi en config par défaut, sans être immunisé |
| LiteSpeed (LSAPI) | Probablement vulnérable | Selon configuration |
L’équipe PHP considère le risque le plus élevé pour Apache avec mod_php, où une requête non authentifiée déclenche l’attaque avant tout code applicatif. Le score « AC:H / AT:P » (complexité élevée, prérequis) reflète le fait que la fiabilité dépend du build, des extensions et de la disposition mémoire : cela ne rend pas la faille théorique, des exploits fonctionnels existent.
Attention aux faux PoC. Comme à chaque fuite très médiatisée, des dépôts « exploit PHP2Shell » non vérifiés circulent. Tenable rappelle que ce genre de code est régulièrement piégé (malware ciblant… ceux qui le lancent). Ne testez rien qui ne vienne pas d’une source identifiée, et jamais hors d’un labo isolé.
Faille PHP2Shell : quels risques pour vos sites ?
- Surface gigantesque : Silas Cutler estime à plus de 1,3 million le nombre d’hôtes exposés potentiellement vulnérables ; une recherche Shodan (Henk Poley) compte plus de 1,9 million d’hôtes PHP exposés.
- Indépendant de l’application : l’attaque frappe pendant le traitement de la requête, avant votre code. Un WordPress parfaitement à jour, un pare-feu applicatif en PHP (Wordfence, etc.) ou un plugin de sécurité ne servent à rien. Les modes maintenance de WordPress et Magento ne protègent pas non plus, puisque PHP est toujours appelé.
- Exploitation rapide : Cloudflare a observé des attaques dès le matin du 21 octobre, et les correctifs publiés permettent désormais à n’importe qui de comprendre les bugs. Sansec anticipait des attaques massives dans les minutes suivant la release.
- Parc legacy : PHP 7.4 à 8.1 n’ont pas de release officielle. Sans backport de votre distribution ou recompilation, ces serveurs restent vulnérables.
- Impact classique d’une RCE web : webshell, vol de la base de données et des identifiants (
wp-config.php,.env), injection de skimmers sur les sites e-commerce, rebond vers le reste de l’infrastructure.
Étape 1 : inventorier vos versions de PHP
Première étape, savoir où tourne PHP. On oublie souvent une deuxième version installée en parallèle ou un vieux conteneur :
# Paquets PHP installés (Debian/Ubuntu)
dpkg -l 'php*' | grep ^ii
# Versions réellement en service
php -v
ps -eo pid,lstart,cmd | grep -E '[p]hp-fpm: master|[a]pache2'
# Conteneurs Docker : image utilisée et version de PHP
docker ps --format '{{.Names}}\t{{.Image}}'
for c in $(docker ps -q); do
echo "$(docker inspect -f '{{.Name}}' $c): $(docker exec $c php -r 'echo PHP_VERSION;' 2>/dev/null)"
done
Avant de mettre à jour, prévoyez un retour arrière : sauvegarde des fichiers et dumps SQL, tag des images Docker actuelles (docker tag wordpress:php8.3-apache wordpress:php8.3-apache-rollback).
Étape 2 : mettre à jour PHP et appliquer le correctif PHP2Shell
Liens officiels des correctifs (publiés le 21 octobre 2026) :
- Téléchargement des sources (et binaires Windows) : php.net/downloads
- ChangeLog des versions corrigées : 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35
- Advisories et patchs sources : CVE-2026-109618 · CVE-2026-109619
- Backports sources pour branches EOL (à compiler soi-même) : PHP 7.4 · PHP 8.0 · PHP 8.1
Paquets système (Debian / Ubuntu)
Les distributions ont reçu les correctifs en avance. Elles rétroportent souvent sans changer le numéro de version upstream : un php8.3 d’Ubuntu 24.04 peut être corrigé tout en affichant 8.3.6. Vérifiez donc le changelog plutôt que la version. Le dépôt d’Ondřej Surý suit, lui, les versions upstream (8.3.36, etc.) : vérifiez qu’elles sont bien disponibles avant de considérer le serveur corrigé.
apt update && apt list --upgradable 2>/dev/null | grep php
apt install --only-upgrade 'php8.3*' # adapter à votre branche
# Le correctif est-il bien dans le paquet ?
apt changelog php8.3-fpm 2>/dev/null | grep -E 'CVE-2026-10961(8|9)'
# INDISPENSABLE : redémarrer ce qui charge PHP
systemctl restart php8.3-fpm # et/ou
systemctl restart apache2 # si mod_php
Un paquet corrigé sur le disque ne protège de rien tant que les anciens workers tournent. Comparez l’heure de démarrage des processus avec l’heure d’installation du paquet (ps -eo pid,lstart,cmd | grep '[p]hp-fpm: master').
RHEL / Rocky / Alma et dépôt Remi
Surveillez les RHSA et errata correspondants (dnf module list --enabled php pour savoir quel flux vous utilisez). Le dépôt rpms.remirepo.net, maintenu bénévolement, n’a pas de mise à jour le 21 octobre : l’équipe PHP recommande d’utiliser les paquets de la distribution ou de compiler depuis les sources, et d’appliquer les contournements ci-dessous en attendant.
Conteneurs Docker
Les images officielles (php, wordpress, nextcloud…) doivent être reconstruites sur les nouvelles versions ; un conteneur en cours d’exécution ne récupère jamais seul la nouvelle image. Il faut tirer l’image, reconstruire vos images dérivées, puis recréer le conteneur (un simple docker restart ne suffit pas) :
docker pull wordpress:php8.3-apache
docker compose up -d --force-recreate monsite
docker exec monsite php -r 'echo PHP_VERSION, PHP_EOL;' # doit afficher 8.3.36
Si PHP_VERSION affiche encore l’ancienne version, l’image corrigée n’est pas encore publiée sur Docker Hub : appliquez les contournements en attendant. Les images wordpress:*-apache utilisent mod_php, la configuration la plus exposée. Après chaque mise à jour, contrôlez que vos sites répondent (code 200) et que les conteneurs sont sains.
PHP 7.4, 8.0 et 8.1
Le projet PHP ne publie plus de versions pour ces branches. Vu la gravité, l’équipe sécurité a toutefois mis à disposition des backports minimaux du correctif sous forme de branches du dépôt php-src (PHP-7.4-CVE-2026-109618-109619, PHP-8.0-…, PHP-8.1-…), utiles si vous compilez PHP vous-même. Sinon : vérifiez si votre distribution ou un fournisseur LTS propose un backport, ou migrez vers une branche supportée. À défaut, CERT-EU recommande de retirer l’application d’Internet (VPN, liste blanche d’IP, arrêt).
PHP2Shell : les contournements si vous ne pouvez pas patcher tout de suite
L’avis officiel est sans ambiguïté : seule la mise à jour est une solution complète. Les mesures ci-dessous réduisent l’exposition à certains chemins d’attaque connus, elles ne rendent pas une installation sûre.
Contournements officiels pour CVE-2026-109618 (OOM)
memory_limit=-1, imposé de façon non modifiable par l’application (php_admin_valuedans le pool FPM ou la conf Apache), en vérifiant qu’aucun pool, répertoire ou réglage applicatif ne remet une limite finie. Cela supprime l’échec contrôlable de la limite mémoire PHP, pas un échec d’allocation sous-jacent.post_max_sizebas : 8M sans besoin d’upload, 32M sinon, avecupload_max_filesizeinférieur.- Limites côté serveur web ou proxy sur la taille des requêtes, le nombre de champs, de parties multipart, d’en-têtes et la profondeur d’imbrication — y compris pour les requêtes sans
Content-Lengthexploitable. - Limite mémoire par conteneur ou cgroup comme garde-fou de disponibilité. À ne pas remplacer par
RLIMIT_AS/RLIMIT_DATA, qui peuvent justement provoquer l’échec d’allocation vulnérable.
Contournements officiels pour CVE-2026-109619 (état périmé)
session.upload_progress.enabled=0(activé par défaut !) dansphp.ini, le pool FPM ou la conf serveur — pas viaini_set()ni.user.ini— puis redémarrage de tous les workers.- Sur PHP 8.5 :
fatal_error_backtraces=0, puis redémarrage des workers. - Supprimer les réglages invalides ou dépréciés appliqués par requête qui émettent des diagnostics avant l’initialisation. Masquer les erreurs (
error_reporting,display_errors,@) n’aide pas. - Corriger les erreurs fatales et timeouts déclenchables par un attaquant (callbacks, traitement d’uploads ou d’imports…).
Exemple de fichier de durcissement, à adapter (et à placer dans le répertoire conf.d du SAPI utilisé) :
; /etc/php/8.x/{fpm,apache2}/conf.d/99-php2shell.ini
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
; PHP 8.5 uniquement :
; fatal_error_backtraces = 0
Bloquer les requêtes multipart/form-data au niveau du serveur web
Le parsing multipart étant un point d’entrée cité par l’avis, le rejeter avant PHP (mesure recommandée par Sansec) coupe ce chemin. Contrepartie : plus d’upload de fichiers (médiathèque WordPress, formulaires avec pièce jointe, certains tunnels de commande).
# Apache (VirtualHost, mod_rewrite requis)
RewriteEngine On
RewriteCond %{HTTP:Content-Type} multipart/form-data [NC]
RewriteRule ^ - [F]
# Nginx (bloc server)
if ($http_content_type ~* "multipart/form-data") {
return 403;
}
Pour garder les uploads côté administration, ajoutez une exception par IP (RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$). Testez avec curl -F 'a=b' https://votre-site/ : la réponse doit être un 403. Pour les sites critiques, on peut aller plus loin en n’autorisant que GET et HEAD, ou en servant une page de maintenance statique sans PHP.
WAF en frontal (Cloudflare & co)
Cloudflare a déployé des règles WAF managées ciblant les vecteurs connus, y compris pour les comptes gratuits — son CTO les qualifie lui-même de « STOPGAP only ». Elles ne servent que si le domaine est proxifié et que le serveur d’origine n’accepte que les plages IP de Cloudflare ; sinon un attaquant qui connaît l’IP de l’origine contourne simplement le WAF.
Détection : mon serveur PHP a-t-il été compromis ?
Pas d’IOC officiels à ce stade. Les signaux génériques d’une RCE web restent valables :
# Processus enfants des workers PHP-FPM (normalement : rien)
for p in $(pgrep -f '^php-fpm: pool'); do
ps --no-headers -o pid,user,lstart,cmd --ppid "$p"
done
# Shells / outils lancés par l'utilisateur du serveur web
ps -u www-data -o pid,lstart,cmd | grep -E 'sh|bash|curl|wget|nc|python|perl'
# Fichiers PHP créés ou modifiés depuis le 20 octobre
find /var/www -name '*.php' -newermt '2026-10-20' -ls
# Workers qui crashent ou dépassent leur mémoire (indice de tentatives)
grep -iE 'Allowed memory size|segfault|exited on signal' /var/log/apache2/error*.log /var/log/php*-fpm.log 2>/dev/null | tail -50
# POST inhabituels
grep '"POST ' /var/log/apache2/*access*.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -30
Si vous trouvez un webshell ou un processus suspect : isolez la machine, conservez les logs, puis changez tous les secrets accessibles par PHP (mots de passe de base, clés d’API, sels WordPress, Application Passwords) après avoir restauré une version saine.
PHP2Shell en résumé : que faire selon votre situation
| Situation | Action |
|---|---|
| PHP 8.2 à 8.5, paquets distrib ou Sury | Passer en 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 (ou backport distrib), redémarrer FPM/Apache, vérifier le changelog |
| Apache + mod_php | Priorité absolue : configuration la plus exposée |
| Conteneurs Docker | Pull de l’image rebuildée + recréation du conteneur, vérifier PHP_VERSION |
| Dépôt Remi | Paquets distrib ou compilation, contournements en attendant |
| PHP 7.4 à 8.1 | Backport distrib/LTS, branches source de l’équipe PHP, ou isoler d’Internet et migrer |
| Impossible de patcher maintenant | session.upload_progress.enabled=0, memory_limit=-1, post_max_size bas, blocage multipart, WAF avec origine filtrée |
| Après le patch | Chercher webshells, processus enfants suspects et crashes de workers |
FAQ PHP2Shell
Qu’est-ce que PHP2Shell ?
PHP2Shell désigne deux vulnérabilités critiques d’exécution de code à distance sans authentification dans l’interpréteur PHP : CVE-2026-109618 (corruption lors d’un manque de mémoire) et CVE-2026-109619 (use-after-free sur un état global périmé), notées 9.2 en CVSS v4.0 et corrigées le 21 octobre 2026.
Quelles versions de PHP sont vulnérables à PHP2Shell ?
Toutes les versions antérieures à PHP 8.2.35, 8.3.36, 8.4.27 et 8.5.12, ainsi que les branches en fin de vie (8.1 et antérieures). Apache avec mod_php est la configuration la plus exposée, mais PHP-FPM, FrankenPHP et LiteSpeed sont aussi concernés.
Quelles sont les versions de PHP corrigées ?
PHP 8.5.12, 8.4.27, 8.3.36 et 8.2.35. Les distributions Linux rétroportent souvent le correctif sans changer le numéro de version : vérifiez le changelog du paquet. Pour PHP 7.4, 8.0 et 8.1, l’équipe PHP a publié des backports sources minimaux.
WordPress est-il concerné par PHP2Shell ?
Oui : la faille se situe dans PHP et non dans WordPress. Un WordPress à jour, Wordfence ou le mode maintenance ne protègent pas. Il faut mettre à jour PHP (ou l’image Docker) puis redémarrer PHP-FPM ou Apache.
Comment se protéger de PHP2Shell sans mettre à jour ?
Aucune mesure n’est complète. L’avis officiel recommande de désactiver session.upload_progress.enabled, de fixer memory_limit à -1 de façon non modifiable, de baisser post_max_size, de limiter la taille et la structure des requêtes au niveau du serveur web et, sur PHP 8.5, de désactiver fatal_error_backtraces, puis de redémarrer tous les workers.
Divulgation responsable
Cet article est publié à des fins défensives et pédagogiques. Il s’appuie exclusivement sur des informations rendues publiques par l’équipe sécurité de PHP (avis officiel et advisories GitHub) et par des acteurs reconnus (Sansec, Tenable, watchTowr, CERT-EU, Cloudflare). 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
Autres failles critiques récentes de l’écosystème PHP : wp2shell (CVE-2026-63030 & CVE-2026-60137) et Comment2Shell (CVE-2026-93485).
Sources
- PHP — Critical remote code execution vulnerabilities, update now (avis du 21 octobre 2026)
- GitHub php-src — GHSA-w8hw-w9fx-j79w : RCE via OOM corruption (CVE-2026-109618)
- GitHub php-src — GHSA-6wmf-4rv5-p3rp : RCE via stale global state (CVE-2026-109619)
- Sansec — Critical PHP RCE: CVE-2026-109618 and CVE-2026-109619
- Tenable — php2shell : FAQ
- watchTowr — PHP Remote Code Execution FAQ
- PatchMon — Patching the Critical PHP RCE Across Your Fleet