Blog / Sécurité

Faille critique PHP du 21 octobre : se préparer avant 16 h

PHP publie ce 21 octobre à 16 h deux correctifs critiques. Le vrai délai est dans vos paquets, vos images et vos workers : voici comment le réduire ce matin.

Par Romain Barberi Mis à jour le 26 octobre 2026 9 min de lecture 9 sources

Le 20 octobre, l’équipe de sécurité de PHP a fait une chose qu’elle fait rarement : prévenir. Une version de sécurité sort ce mercredi 21 octobre à 14:00 UTC, soit 16 h à Paris, et elle corrige deux vulnérabilités notées 9,2 sur l’échelle CVSS v4.0. L’annonce ne dit rien d’autre : ni les extensions touchées, ni les versions concernées, ni la nature des failles. Je pense que c’est précisément ce qui rend la journée utile. On ne peut pas encore savoir si l’on est exposé, mais on peut savoir dès ce matin combien de temps il faudra pour être corrigé, et sur un parc qui a quelques années, ce temps se compte rarement en heures.

Ce que l’annonce dit, et ce qu’elle tait

Le texte publié sur php.net tient en quelques lignes. La sortie est programmée pour le 21 octobre à 14:00 UTC. Elle corrige deux failles critiques, toutes deux à 9,2. Tous les utilisateurs sont invités à se préparer pour mettre à jour dès la disponibilité. L’équipe se réserve le droit de publier plus tôt si le détail d’une des failles devient public ou si une exploitation est observée. Les détails, les versions affectées et les versions corrigées seront publiés avec la sortie.

Deux conséquences pratiques. D’abord, rien ne sert de chercher le détail des failles aujourd’hui : il n’est pas public, et ce qui circulera avant 16 h relèvera de la spéculation. Ensuite, l’heure peut avancer. Une équipe qui attend 16 h pour commencer à réfléchir a déjà perdu sa marge.

Le calendrier des branches donne en revanche une information solide. Selon la page des versions supportées de php.net, quatre branches reçoivent encore des correctifs de sécurité : 8.2 (jusqu’au 31 décembre 2026), 8.3 (jusqu’au 31 décembre 2027), 8.4 et 8.5. La 8.1 est en fin de vie depuis le 31 décembre 2025, sa dernière version est la 8.1.34 ; la 8.0 s’est arrêtée à la 8.0.30 et la 7.4 à la 7.4.33. Pour ces branches, php.net ne publiera rien ce soir, quelle que soit la gravité.

Le délai qui compte n’est pas celui de php.net

Pour la plupart des équipes, « PHP sort une version à 16 h » ne veut pas dire « nous pouvons mettre à jour à 16 h ». Entre les deux, il y a la personne qui reconstruit le binaire que vous exécutez réellement : votre distribution, l’image Docker de base, ou vous.

J’ai regardé ce que cela donne sur une machine Ubuntu 24.04, ce matin :

$ php -v | head -1
PHP 8.3.6 (cli) (built: Oct  7 2026 18:06:38) (NTS)
$ dpkg -l 'php8.3-cli' | awk '/^ii/ {print $2, $3}'
php8.3-cli 8.3.6-0ubuntu0.24.04.12
$ zcat /usr/share/doc/php8.3-cli/changelog.Debian.gz | sed -n '1,/^ -- /p' \
    | grep -oE 'CVE-[0-9]+-[0-9]+' | sort -u | wc -l
10

Ces commandes ont été exécutées dans un conteneur Ubuntu 24.04 ce 21 octobre. Elles disent deux choses. La première : php -v affiche 8.3.6, une version de 2024, alors que le binaire embarque les correctifs publiés en amont le 24 septembre dans la 8.3.35 (le journal du paquet cite notamment les CVE du SOAP, du wrapper HTTP et d’OpenSSL de cette livraison). La distribution rétroporte les correctifs sans changer le numéro. Un scanner qui compare PHP_VERSION à la dernière version publiée signalera donc cette machine comme vulnérable à tort, et un humain qui lit php -v ne saura pas si elle est corrigée. Seul le paquet dit la vérité.

La seconde : l’entrée du journal est datée du 7 octobre 2026. Les correctifs publiés par php.net le 24 septembre sont arrivés dans noble-security treize jours plus tard. Ce n’est pas un reproche : rétroporter sur une base de deux ans demande du travail, et l’urgence de septembre était moindre. Mais c’est l’ordre de grandeur à avoir en tête. Si votre production tourne sur les paquets de la distribution, votre correctif de ce soir dépend de son calendrier, pas de celui de php.net. Sur les migrations que j’ai menées, cette dépendance était presque toujours implicite : personne ne l’avait choisie, elle venait de l’image de base.

Les images officielles php du Docker Hub suivent une autre logique : elles compilent PHP depuis les sources, donc elles affichent le numéro amont et sont reconstruites quand une version sort. Encore faut-il que votre Dockerfile en profite.

Inventorier les binaires, pas les applications

L’erreur classique consiste à faire l’inventaire par application : « le site tourne en 8.3, c’est bon ». Or une même application exécute souvent plusieurs PHP différents : le FPM du serveur web, le CLI des tâches cron, les workers Messenger sous supervisord, l’image de la CI, parfois un vieux conteneur de génération de PDF que personne n’a reconstruit depuis deux ans. Chacun a sa propre provenance et son propre délai.

Voici l’inventaire que je lance avant ce type de sortie. Il tient sur un écran et ne modifie rien :

# 1. Sur chaque hôte : le paquet installé, CLI et FPM séparément
dpkg -l 'php*-cli' 'php*-fpm' 2>/dev/null | awk '/^ii/ {print $2, $3}'
rpm -qa 'php*' 2>/dev/null | sort

# 2. Depuis quand tourne le master FPM (un paquet à jour ne sert à rien
#    tant que le processus en mémoire date d'avant)
ps -o lstart=,cmd= -p "$(pgrep -o php-fpm)"

# 3. Chaque image en service et la version qu'elle embarque
for img in $(docker ps --format '{{.Image}}' | sort -u); do
  printf '%s : ' "$img"
  docker run --rm --entrypoint php "$img" -r 'echo PHP_VERSION, PHP_EOL;' 2>/dev/null \
    || echo "pas de php ou entrypoint différent"
done

# 4. Les images référencées dans le code, CI comprise
grep -rnE '^FROM .*php|image: .*php' --include=Dockerfile* --include=*.yml --include=*.yaml .

Le point 2 est celui qu’on oublie. Les processus longs gardent l’ancien binaire en mémoire jusqu’à leur redémarrage : le master FPM, mais aussi les consumers Messenger, les workers de queue, les serveurs applicatifs persistants. Mettre à jour le paquet sans redémarrer ces processus laisse la faille ouverte, avec un inventaire qui dit le contraire.

Le résultat attendu tient dans un petit tableau, à remplir avant 16 h. Voici sa forme, avec des lignes types :

BinaireProvenanceQui publie le correctifDélai attenduRedémarrage nécessaire
FPM productionpaquet de la distributionla distributionjoursmaster FPM
Workersmême image que le FPMidemidemsupervisord
CIphp:8.4-cli (Docker Hub)images officiellesheuresaucun
Ancien conteneur PDFphp:7.4-apachepersonnejamaisà isoler

La dernière ligne est la plus importante du tableau, et une ligne de ce genre existe dans la plupart des parcs qui ont quelques années.

Préparer le chemin de déploiement pendant qu’il est calme

Une version corrective (8.3.x vers 8.3.y) ne change ni la syntaxe ni les fonctions disponibles : le risque n’est pas la compatibilité du code, c’est le déploiement lui-même. Tout ce qui peut être fait avant la sortie doit l’être ce matin.

Si vos images partent de php:8.x-fpm avec un tag flottant, vérifiez que la CI reconstruit avec docker build --pull, sinon le cache local resservira l’ancienne couche de base. Si vous épinglez un digest (php:8.3-fpm@sha256:…), ce qui est une bonne pratique, préparez la branche qui le changera et sachez qui peut la merger ce soir. Si vous dépendez de paquets de distribution, vérifiez que les dépôts de sécurité sont bien actifs sur chaque hôte, et non un miroir figé.

Faites aussi une photo de l’existant pour pouvoir comparer après coup. Reconstruire une image tire parfois une autre version d’une extension PECL, et c’est là que les surprises arrivent :

php -m | sort > modules-avant.txt
php -i | grep -E '^(opcache\.|memory_limit|date\.timezone)' > ini-avant.txt

Après la mise à jour, deux diff suffisent pour vérifier que rien d’autre n’a bougé. Ajoutez un test de fumée qui passe par les chemins vraiment utilisés en production, pas seulement la page d’accueil : une connexion, un appel sortant en HTTPS, un message traité par un worker.

Les branches que personne ne corrigera ce soir

Si l’inventaire révèle du PHP 8.1 ou plus ancien, la sortie de ce soir ne vous concerne pas au sens où il n’y aura rien à installer. Les distributions qui livrent encore ces branches dans une version supportée peuvent rétroporter des correctifs, à leur rythme. Une image php:7.4 du Docker Hub, elle, ne recevra rien.

Il reste trois options, à choisir en connaissant les détails des failles : monter de version (rarement possible en une soirée), réduire l’exposition (sortir le service d’Internet, le placer derrière une authentification, appliquer les mesures provisoires de l’avis), ou accepter le risque par écrit. La pire option est la quatrième, celle qu’on prend par défaut : ne rien décider. C’est aussi le bon moment pour noter que la 8.2 sort du support de sécurité le 31 décembre 2026. Une application en 8.2 sera corrigée ce soir, mais c’est l’une des dernières fois.

Les limites

Cet article s’appuie uniquement sur l’annonce de php.net et sur le calendrier des branches : à l’heure où il a été écrit, le détail des failles n’était pas public. L’avis publié depuis montre que toutes les SAPI web sont touchées : la préparation décrite ici reste une mesure de délai, et ce délai concerne tout le monde. Elle a aussi un coût : sur un petit parc d’une seule application, l’inventaire est fait en dix minutes et le tableau est superflu. Enfin, le délai de treize jours observé sur Ubuntu en septembre concerne une livraison notée « élevée » au plus ; pour ces deux failles critiques, Ubuntu a publié son paquet le jour même (voir la mise à jour ci-dessous), ce qui ne vaut pas garantie pour la prochaine fois.

Concrètement, par où commencer

Avant 16 h :

  • Lancez l’inventaire ci-dessus sur chaque hôte et chaque image, CI comprise, et remplissez le tableau de provenance.
  • Repérez les processus longs (FPM, workers, serveurs persistants) et la commande qui les redémarre.
  • Vérifiez que la CI reconstruit avec --pull, ou préparez la branche qui change le digest.
  • Prenez la photo des modules et des réglages pour le diff d’après.

À 16 h, lisez l’avis : versions corrigées, extensions concernées, conditions d’exploitation. Croisez-le avec votre tableau, ligne par ligne, et traitez d’abord ce qui est exposé à Internet. Pour les lignes « personne », décidez explicitement.

Ce que la journée apprend dépasse cette sortie : le jour où une faille critique sortira sans préavis, ce tableau de provenance sera la seule chose qui sépare une heure de travail d’une semaine d’incertitude.

Mise à jour du 26 octobre 2026

Le 23 octobre, php.net a publié un avis informatif : une exécution de code à distance, jugée peu probable et suivie sous CVE-2026-115560, reste possible après la mise à jour du 21 octobre, et son correctif attendra la prochaine version de maintenance. Elle suppose une combinaison précise : session.serialize_handler réglé sur php_binary ou php_serialize dans la configuration, repassé à php par ini_set() avant session_start(), avec session.upload_progress.enabled toujours actif. L’équipe conseille donc de mettre session.upload_progress.enabled=0 jusqu’à cette version, y compris sur les branches corrigées ; si vous l’aviez appliqué comme mesure provisoire, gardez-le. Pour savoir si une application est dans le cas, un grep -rn "serialize_handler" --include='*.php' . suffit, et php -i | grep upload_progress.enabled donne la valeur active en CLI, à confirmer dans le pool FPM.

Mise à jour du 22 octobre 2026

La version est sortie le 21 octobre comme annoncé : PHP 8.5.12, 8.4.27, 8.3.36 et 8.2.35 corrigent CVE-2026-109618 (état d’une requête corrompu quand la mémoire vient à manquer) et CVE-2026-109619 (état global d’une requête précédente réutilisé par le même worker), deux exécutions de code à distance sans authentification. Selon php.net, elles touchent toutes les installations qui servent des requêtes web, FPM, mod_php (le cas jugé le plus exposé), php-cgi, FrankenPHP et LiteSpeed compris : aucune configuration n’y échappe, et le paragraphe des limites a été corrigé en ce sens. Pour les branches 7.4, 8.0 et 8.1, l’équipe a publié des rétroportages minimaux sous forme de sources, sans nouvelle version ; ses mesures provisoires (memory_limit=-1, post_max_size réduit, session.upload_progress.enabled=0 puis redémarrage de chaque worker) ne remplacent pas la mise à jour. Côté distribution, Ubuntu 24.04 a publié le jour même le paquet php8.3 en 8.3.6-0ubuntu0.24.04.13, dont le journal, lu dans un conteneur ce matin, cite les deux CVE : treize jours d’attente en septembre, aucun cette fois, mais php -v affiche toujours 8.3.6. Vérifiez donc le paquet, puis l’heure de démarrage du master FPM et des workers : c’est le point 2 de l’inventaire qui dit aujourd’hui si la faille est fermée.

Sources

Sur ce sujet, l’offre de l’atelier : Audit gratuit

À lire aussi

Un socle à migrer, une architecture à fiabiliser ?

Renfort senior en régie, ou forfait à périmètre et prix fixés : l’atelier intervient à distance sur PHP, Symfony, les systèmes distribués et l’adoption des agents de code, avec des tests de caractérisation avant chaque migration.