En bref : dans Kubernetes, PHP se trouve dans l'image de conteneur, pas dans le cluster. Après PHP2Shell, vous devez reconstruire chaque image PHP Kubernetes avec une version de PHP corrigée, redéployer tous les workloads concernés, puis vérifier l'état dans chaque pod en service. Une image de base mise à jour dans le registre ne change rien, à elle seule, aux pods en service.
Pourquoi le cluster ne se corrige pas lui-même
Kubernetes gère des conteneurs, mais ne s'occupe pas des logiciels qu'ils contiennent. Chaque pod tourne avec l'image dont il est issu, jusqu'à ce qu'il soit remplacé. Qui exploite des applications PHP dans le cluster porte donc la responsabilité des images, même si le cluster tourne comme service géré chez un fournisseur cloud. Le fournisseur entretient typiquement le plan de contrôle et les nœuds, pas les images des clients.
PHP2Shell regroupe CVE-2026-109618 et CVE-2026-109619, chacune CVSS v4.0 9.2. Sont notamment concernés PHP-FPM, Apache avec mod_php et FrankenPHP, c'est-à-dire les modes d'exécution habituels dans les images PHP. Les versions corrigées sont PHP 8.5.12, 8.4.27, 8.3.36 et 8.2.35.
Inventaire : quelle image PHP Kubernetes tourne où ?
Commencez par une liste de toutes les images du cluster. Les commandes suivantes se contentent de lire. Les noms de namespaces, de deployments et de conteneurs sont des exemples.
# Toutes les images de tous les pods, regroupées
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'
# Digest d'image réellement en service par conteneur
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .status.containerStatuses[*]}{.imageID}{" "}{end}{"\n"}{end}'
# Version de PHP dans un pod en service
kubectl exec -n shop deploy/web -c php -- php -v
Pensez, outre les deployments, aux StatefulSets, DaemonSets, CronJobs et conteneurs d'initialisation. Dans les grands clusters, des scanners d'images, qui analysent les images à la recherche de CVE connues, sont utiles. Pour les paquets de distribution à l'intérieur de l'image, la règle est la même qu'ailleurs : un backport peut laisser le numéro de version inchangé, c'est alors le journal des modifications du paquet qui compte.
Reconstruire les images
Mettez d'abord à jour l'image de base. Si vous utilisez les images PHP officielles, choisissez une variante avec une version de PHP corrigée. Reconstruisez ensuite votre propre image, sans reprendre l'ancienne couche de base depuis le cache.
# Exemple : reconstruire l'image, récupérer activement à nouveau l'image de base
docker build --pull --no-cache -t registry.example.com/shop/web:2026-10-25 .
# Vérifier la version de PHP dans la nouvelle image avant le rollout
docker run --rm registry.example.com/shop/web:2026-10-25 php -v
Ne vous fiez pas à des balises comme latest ou à une simple version majeure. Référencez si possible dans le manifeste le digest de la nouvelle image, afin qu'il soit clair quel état est déployé. Si le déploiement passe par GitOps ou Helm, modifiez l'image à cet endroit, pour que l'état ne soit pas réinitialisé lors de la prochaine synchronisation.
Rollout et contrôle
Un nouveau rollout remplace progressivement tous les pods d'un workload. Vous vérifiez ensuite l'état dans les pods en service. Ce n'est qu'alors que le correctif est effectif, car de nouveaux fichiers n'aident que si d'anciens processus PHP ne tournent plus.
# Rollout avec la nouvelle image (noms à titre d'exemple)
kubectl -n shop set image deploy/web php=registry.example.com/shop/web@sha256:<digest>
kubectl -n shop rollout status deploy/web
# Contrôle : tous les pods redémarrés, nouveau digest actif ?
kubectl -n shop get pods -o wide
kubectl -n shop exec deploy/web -c php -- php -v
Si l'image a été poussée à nouveau sous la même balise, kubectl rollout restart déclenche un redémarrage ; les pods ne récupèrent toutefois l'image à nouveau que si l'imagePullPolicy le prévoit. Il est plus sûr de passer à un nouveau digest.
Sauvegardez les journaux avant de remplacer des pods. Avec l'ancien pod disparaissent aussi ses journaux locaux. Conservez les journaux du serveur web et de l'application à partir du 20 octobre 2026, idéalement dans une plateforme de journalisation centrale.
Mesures transitoires dans le cluster
Si aucune image corrigée n'est encore disponible pour votre version de PHP, php.net recommande des mesures transitoires sans protection complète. Dans le cluster, vous définissez les limites de mémoire via les limites de ressources des conteneurs, qui reposent sur les cgroups. Cela correspond à la recommandation de limiter la mémoire via le conteneur ou les cgroups et non via RLIMIT_AS ou RLIMIT_DATA.
; php.ini ou pool FPM dans l'image, p. ex. intégré via une ConfigMap
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
Avec une fonction d'envoi de fichiers, php.net indique post_max_size = 32M. Sur PHP 8.5, fatal_error_backtraces=0 s'y ajoute. Après modification de la configuration, un nouveau rollout est nécessaire. En complément, des NetworkPolicies limitent les connexions sortantes des pods PHP, et un Ingress avec des règles de protection peut compliquer les tentatives d'attaque. Selon Cloudflare, des règles fondées sur les seules données de la requête ne suffisent toutefois pas.
Mieux se positionner durablement
Planifiez des rebuilds automatiques réguliers de toutes les images PHP, un contrôle d'images dans la chaîne de build et des politiques n'autorisant que des images signées ou vérifiées. Si les conteneurs PHP tournent avec un utilisateur sans droits root et un système de fichiers en lecture seule, les dégâts d'une attaque réussie diminuent. Des indications pour des conteneurs individuels figurent sous Corriger PHP dans des conteneurs Docker, pour FrankenPHP sous Sécuriser FrankenPHP.
Dans de nombreux clusters, les applications PHP ne tournent pas seules. Il y a souvent des conteneurs sidecar pour la journalisation ou les métriques, des images auxiliaires pour les migrations de bases de données et des jobs qui ne démarrent que la nuit. Des images de tiers, par exemple pour un wiki, une interface de supervision ou un système de tickets, peuvent aussi contenir PHP sans que cela soit reconnaissable dans le nom. Vérifiez donc non seulement vos propres applications, mais chaque image du cluster. Pour les images tierces : attendez une version mise à jour de l'éditeur, vérifiez ses indications sur la version de PHP contenue et limitez l'accessibilité jusqu'à ce qu'elle soit disponible. Si un tel système ne tourne qu'en interne, cela réduit le risque, mais ne remplace pas la mise à jour.
Comment PHP SOS aide-t-il concrètement ?
- Nous recensons tous les workloads avec PHP, leurs images et digests et vérifions la version de PHP dans les pods en service.
- Via le service de correctifs PHP, nous reconstruisons les images, les déployons et documentons l'état par workload.
- Nous sauvegardons les journaux avant le remplacement et recherchons des traces d'une attaque.
- Avec la supervision de sécurité et des rebuilds automatisés, nous veillons à ce que le prochain correctif arrive plus vite dans le cluster.
Questions fréquentes
Suffit-il de mettre à jour l'image de base dans le registre ?
Non. Les pods en service continuent d'utiliser l'image avec laquelle ils ont démarré. Seul un nouveau rollout avec l'image reconstruite remplace les pods. Vérifiez ensuite la version de PHP dans chaque pod en service.
Pourquoi référencer les images par digest ?
Une balise peut pointer vers différents états d'image selon le moment où elle a été récupérée. Un digest désigne exactement un état. Vous savez ainsi avec certitude quel code tourne dans quel pod, et les rollouts deviennent traçables.
Qu'en est-il des CronJobs et des conteneurs d'initialisation ?
Eux aussi peuvent contenir PHP et font partie de l'inventaire. Les CronJobs démarrent à chaque exécution de nouveaux pods à partir de leur modèle ; mettez donc à jour l'image dans le modèle. Les conteneurs d'initialisation s'exécutent au démarrage de chaque pod.
Une NetworkPolicy protège-t-elle contre PHP2Shell ?
Elle ne comble pas la faille, mais peut limiter les dégâts. Qui restreint les connexions sortantes des pods PHP complique le téléchargement de code malveillant et les déplacements latéraux dans le cluster.