Tutoriel

Inventaire des versions PHP du parc clients : méthode d'agence

Sécurité & Monitoring11 min de lecture8 étapes

Quand une faille PHP critique tombe, la question du client est simple : mon site est-il touché ? Pour une agence, y répondre site par site, chez cinq hébergeurs et avec des accès inégaux, prend des jours si rien n'est préparé. Cette méthode tient en une demi-journée pour 20 à 200 sites : une mesure à paliers selon l'accès, un registre qui distingue le présumé du confirmé, des lots de priorité, un message type et une preuve datée de correction. Le même registre se rejoue à chaque CVE et à chaque fin de vie de branche.

Sommaire· Ce qu'un audit de parc doit produire1/14
  1. 01Ce qu'un audit de parc doit produire
  2. 02Contexte daté : PHP2Shell
  3. 03Les quatre paliers de mesure
  4. 04Mesurer palier par palier
  5. 05Pourquoi pas de phpinfo, et surtout pas en public
  6. 06Le registre : une ligne par site
  7. 07Les colonnes du registre
  8. 08Classer en lots, pas en liste de courses
  9. 09Grille de priorité
  10. 10Prévenir les clients sans les affoler
  11. 11Deux messages types
  12. 12Prouver la correction, puis rejouer l'audit
  13. 13La cadence : un audit par trimestre, et à chaque déclencheur
  14. 14La documentation officielle

Ce qu'un audit de parc doit produire

Un audit de parc n'est pas une commande lancée une fois. C'est un registre : une ligne par site, avec la version PHP lue, la manière dont elle a été lue, la date et le degré de certitude. Sans ces trois informations, un chiffre ne vaut rien, parce qu'une version lue le mois dernier ne dit rien de l'état d'aujourd'hui.

L'objection habituelle est légitime : vous n'avez pas la main sur l'hébergeur du client, vous ne pouvez pas lancer de commande SSH partout, et vous ne devez pas déposer de fichier de diagnostic sur un site en production. La réponse tient en une idée : on mesure avec ce que l'on a, et on note honnêtement ce que chaque mesure prouve. Un site lu depuis l'extérieur est présumé ; un site lu depuis le serveur est confirmé. Le registre garde les deux et vous dit où il reste du travail.

Contexte daté : PHP2Shell

Le 21 octobre 2026, le projet PHP a publié les versions 8.5.12, 8.4.27, 8.3.36 et 8.2.35, qui corrigent CVE-2026-109618 et CVE-2026-109619 (exécution de code à distance sans authentification). PHP 8.1 et les branches plus anciennes ne reçoivent plus de mise à jour du projet ; des rétroports minimaux ont été publiés pour les sources de 7.4, 8.0 et 8.1. L'ajout au catalogue CISA des vulnérabilités exploitées date du 26 octobre 2026, avec une échéance fédérale au 29 octobre 2026. La description des failles et la mise à jour d'un serveur sont traitées dans l'article dédié ; ici, on s'occupe du portefeuille.

Les quatre paliers de mesure

Faites défiler le tableau

Palier et accèsCe qu'il prouveCe qu'il ne prouve pas
1. Observation externe, aucun accèsUn en-tête X-Powered-By ou Server, quand il existe, suggère une pile et une versionRien de certain : l'en-tête est souvent masqué, supprimé ou faux. C'est une présomption
2. wp-cli ou SSHLa version du binaire PHP en ligne de commande, lue sur la machineLa version servie par le web : le binaire CLI peut différer de PHP-FPM ou d'Apache
3. Panneau cPanel, WHM ou PleskLa version attribuée à chaque domaine, avec le gestionnaireLe correctif réellement appliqué : un même numéro peut être corrigé ou non selon le paquet
4. DockerLa version dans l'image et dans le conteneur en cours d'exécutionQue l'image déployée soit la bonne : comparer image et conteneur vivant
Lecture du changelog du paquetQue le correctif est présent malgré un numéro inchangé (rétroport)Que le site n'a pas été compromis avant la mise à jour
Aucun palier possibleRien : le site passe en lot 4, à demander au client ou à l'hébergeurNe jamais le classer « corrigé » par défaut

Mesurer palier par palier

  1. Palier 1 : lire les en-têtes sans accès

    Préparez sites.txt, une URL par ligne, puis lancez while read -r u; do printf '%s,%s\n' "$u" "$(curl -sI --max-time 10 "$u" | tr -d '\r' | grep -iE '^(server|x-powered-by):' | tr '\n' ' ')"; done < sites.txt > externe.csv. Chaque ligne donne l'URL et les deux en-têtes trouvés. Une ligne vide est une information : l'en-tête est masqué. Classez ces sites « présumé » et passez au palier suivant dès que possible.

  2. Palier 2 : interroger WordPress avec wp-cli

    Sur un site WordPress où wp-cli est installé, wp cli info affiche notamment la ligne PHP binary et la ligne PHP version. Pour extraire la seconde : wp cli info | grep 'PHP version'. Notez que cette valeur décrit le binaire utilisé en ligne de commande. Le serveur web peut tourner sous une autre version, notamment quand l'hébergeur propose plusieurs versions par domaine. Pour un contrôle fiable, comparez avec le palier 3.

  3. Palier 2 bis : un script SSH en lot

    Avec hotes.txt (un alias SSH par ligne) : while read -r h; do printf '%s,%s\n' "$h" "$(timeout 20 ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$h" "php -r 'echo PHP_VERSION;'" 2>/dev/null || echo inconnue)"; done < hotes.txt > ssh.csv. Le -n empêche ssh d'avaler la liste, BatchMode évite qu'un hôte demande un mot de passe et bloque la boucle, timeout borne chaque tentative. Les hôtes qui échouent ressortent en « inconnue » au lieu de disparaître : testé avec un hôte en échec et un hôte qui ne répond pas, les deux apparaissent bien dans le CSV.

  4. Palier 3 : lire les panneaux

    Dans cPanel, MultiPHP Manager liste chaque domaine avec sa version PHP, ou la mention Inherited quand il suit la valeur système. Dans WHM, le même outil donne la vue par compte. Dans Plesk, la version et le gestionnaire se règlent par domaine dans Sites web et domaines, rubrique Paramètres PHP, selon la version de Plesk. Relevez la version affichée, puis passez à l'étape suivante pour savoir si le correctif est présent.

  5. Rétroports : lire le changelog, pas seulement le numéro

    Les distributions et les hébergeurs sous CloudLinux corrigent souvent sans changer le numéro amont. AlmaLinux le dit expressément dans son avis : ne vous fiez pas à php -v, comparez le paquet installé avec la version corrigée publiée, par exemple avec rpm -q php-common. Pour chercher la mention d'une CVE dans l'historique du paquet : rpm -q --changelog php-common | grep CVE-2026-109618 sur la famille RHEL, et apt changelog suivi du nom du paquet sur Debian et Ubuntu. Absente de l'historique, la CVE n'est pas corrigée dans ce paquet.

  6. Palier 4 : conteneurs

    Une image récente ne prouve pas que le conteneur qui tourne l'est aussi. Comparez la version dans l'image et celle du conteneur en cours d'exécution, puis reconstruisez si besoin. La procédure complète est dans l'article sur la reconstruction des images PHP, auquel nous renvoyons pour ne pas la recopier.

Pourquoi pas de phpinfo, et surtout pas en public

Le réflexe est de déposer un fichier phpinfo() sur le site. Il donne tout, mais il expose aussi les chemins, les modules et la configuration du serveur à quiconque connaît l'adresse, et un fichier oublié devient un point d'entrée pour la reconnaissance. Sur le site d'un client, il y a un second problème : modifier ce site sans mandat écrit est une faute, même pour lire une version.

Par défaut, écartez-le. Si une situation l'impose, un fichier temporaire doit répondre à quatre conditions : l'accord écrit du client, un nom imprévisible, une suppression immédiate après lecture, et une trace de l'opération dans le registre. Dans presque tous les cas, un palier 2 ou 3 rend ce fichier inutile.

Le registre : une ligne par site

Un tableur partagé suffit, à condition de tenir les mêmes colonnes pour tout le monde. Le but est qu'un collègue puisse reprendre l'audit sans vous poser de question, et que le client puisse recevoir sa ligne telle quelle.

Les colonnes du registre

  • Site, client, hébergeur — l'identité de la ligne, avec l'URL canonique et le contact technique.
  • Type d'accès — aucun, wp-cli, SSH, panneau ou Docker : ce qui détermine le palier atteignable.
  • Méthode de mesure — la commande ou l'écran utilisé, pour que la mesure soit rejouable à l'identique.
  • Version lue et SAPI — le numéro et le mode d'exécution (FPM, module Apache, CLI), car le risque diffère selon le mode.
  • Date de mesure — une version sans date est une opinion.
  • Niveau de confiance — présumé (palier 1) ou confirmé (paliers 2 à 4), plus la mention rétroporté si le changelog le confirme.
  • Lot de priorité et statut — de 1 à 4, puis à faire, prévenu, en cours, corrigé, ou refusé par le client.
  • Date et preuve de correction — la capture, la sortie de commande et le nom de l'opérateur.

Classer en lots, pas en liste de courses

Quand le registre est rempli, la question n'est plus « tout est-il à jour ? » mais « par quoi commencer ? ». Quatre lots répondent. Le lot 1 regroupe les sites exposés sur une branche qui ne reçoit plus de correctif du projet PHP (8.1 et antérieures), sauf correctif d'un fournisseur confirmé par le changelog. Le lot 2 : branche encore supportée mais version antérieure au correctif. Le lot 3 : branche corrigée, à confirmer par une mesure de palier 2 ou 3. Le lot 4 : site non joignable ou version inconnue.

Trois critères font monter un site d'un lot : un formulaire public, une boutique, la présence de données personnelles, ou un plugin qui accepte des fichiers envoyés. Un site vitrine statique en lot 2 passe après une boutique en lot 3.

Grille de priorité

Faites défiler le tableau

LotCritèreAction
Lot 1Exposé, branche sans correctif du projet (8.1 et antérieures)Migrer ou exiger un paquet corrigé par le fournisseur, prévenir le client le jour même
Lot 2Branche supportée, version antérieure au correctifMettre à jour vers la version corrigée de la branche, dans la semaine
Lot 3Branche corrigée, mesure à confirmerMesure de palier 2 ou 3, puis passer le niveau de confiance à confirmé
Lot 4Injoignable, accès refusé ou version inconnueDemander l'accès ou la version au client, relancer et dater chaque demande
AggravantFormulaire, boutique, données personnelles, uploadMonte le site d'un lot dans l'ordre de traitement

Prévenir les clients sans les affoler

Un client n'a pas besoin du détail des deux CVE. Il a besoin de savoir si son site est concerné, ce que vous faites et ce que cela change pour lui. Deux messages courts suffisent, à adapter. Gardez le même ton factuel : la version lue, la date, la suite. N'écrivez pas que le site est protégé ou sécurisé : une version lue n'est pas une preuve d'absence de compromission.

Deux messages types

  1. Client informé de l'état de son site

    « Bonjour, nous avons relevé la version PHP de votre site le [date]. Elle était [version], antérieure au correctif publié par le projet PHP pour deux failles critiques. Nous la mettons à jour le [date], sans interruption prévue. Nous vous envoyons ensuite la preuve datée de la version en service. Aucune action n'est nécessaire de votre côté. Si vous avez des questions, répondez à ce message. »

  2. Client dont le site ne peut pas être migré tout de suite

    « Bonjour, votre site tourne sur une version de PHP qui ne reçoit plus de correctifs du projet. La migration demande [travaux], que nous vous proposons pour le [date]. En attendant, nous [mesure : paquet corrigé par l'hébergeur, retrait du formulaire d'envoi de fichiers, filtrage]. Ces mesures limitent le risque sans le supprimer. Merci de nous confirmer la date retenue avant le [date]. »

Prouver la correction, puis rejouer l'audit

La preuve d'une correction est un enregistrement par site : la mesure avant, l'intervention, la même mesure après, la capture ou la sortie de commande, le numéro de version, la date et le nom de l'opérateur. Rejouer la même mesure, avec la même méthode, est ce qui rend la preuve comparable. Conservez le journal avec le registre.

Gardez en tête la limite : une version lue prouve la version servie à l'instant de la mesure, pas l'absence d'intrusion avant la mise à jour. Si un site est resté exposé après le 21 octobre 2026, la recherche de traces d'exploitation est un second chantier, décrit dans l'article PHP2Shell.

La cadence : un audit par trimestre, et à chaque déclencheur

Rejouez l'audit chaque trimestre, plus à chaque nouvelle CVE critique et à chaque fin de vie de branche. Comparez les deux mesures : une dérive, c'est un site dont la version a baissé ou dont le niveau de confiance est redevenu présumé. Reportez dans le registre les dates de fin de vie qui comptent. Pour PHP 8.2, le projet indique le 31 décembre 2026 ; la checklist de migration vers 8.3 ou 8.4 est dans l'article dédié. Le premier lot de l'audit suivant est déjà connu : tout ce qui tourne encore sur 8.2 le 1er janvier.

La documentation officielle

  • Avis PHP du 21 octobre 2026 — https://www.php.net/archive/2026.php#2026-10-21-5
  • Versions supportées de PHP — https://www.php.net/supported-versions.php
  • Alerte CISA du 26 octobre 2026 — https://www.cisa.gov/news-events/alerts/2026/10/26/cisa-adds-two-known-exploited-vulnerabilities-catalog
  • Dépôt NCSC-NL php2shell — https://github.com/NCSC-NL/php2shell
  • Avis AlmaLinux sur les paquets corrigés — https://almalinux.org/blog/2026-10-21-php2shell-cve-2026-109618-cve-2026-109619/
  • MultiPHP Manager (cPanel) — https://docs.cpanel.net/cpanel/software/multiphp-manager-for-cpanel/
  • wp cli info — https://developer.wordpress.org/cli/commands/cli/info/

Un seul endroit pour lire et imposer la version PHP de chaque compte

Quand les sites clients sont répartis chez plusieurs hébergeurs, chaque audit repart de zéro : accès à récolter, versions hétérogènes, renouvellements dispersés. Un hébergement revendeur Agency S (WHM, marque blanche) ou une flotte de VPS regroupe les comptes au même endroit : une interface pour lire la version PHP de chaque compte, l'imposer et en garder la preuve. Les offres Agency incluent des sauvegardes quotidiennes.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet