PHP 22 octobre 2026 7 min de lecture

Faille PHP critique : mettre à jour PHP sur un VPS Ubuntu

Gabriel Janez

Gabriel Janez

Développeur Full-Stack PHP

Une faille critique PHP est annoncée, le réflexe est immédiat : « il faut passer à la dernière version ». Sur mon VPS, php -v affichait 8.4.11 alors que la branche upstream en était à 8.4.27. Seize versions de retard ? Pas tout à fait. Voici ce que j'ai appris en mettant à jour mon propre serveur, et les pièges que j'ai trouvés au passage.

Le numéro de version ne dit pas tout

Les distributions comme Ubuntu et Debian ne suivent pas les versions upstream de PHP. Elles gèlent une version mineure au moment de la release (ici 8.4.11 pour Ubuntu 25.10) puis rétroportent les correctifs de sécurité dedans. Le correctif se lit dans le suffixe du paquet, pas dans php -v :

$ dpkg -l php8.4-cli | tail -1
ii  php8.4-cli  8.4.11-1ubuntu1.1  amd64  command-line interpreter for PHP

$ apt list --upgradable 2>/dev/null | grep php8.4-cli
php8.4-cli/questing-updates 8.4.11-1ubuntu1.2 amd64 [upgradable from: 8.4.11-1ubuntu1.1]

Pour savoir ce que contient réellement ce ubuntu1.2, il suffit de lire le changelog du paquet :

$ apt-get changelog php8.4-cli | head -30
php8.4 (8.4.11-1ubuntu1.2) questing-security; urgency=medium

  * SECURITY UPDATE: out-of-bounds read via NUL byte
    - CVE-2026-6104  [mbstring]
  * SECURITY UPDATE: use-after-free in SOAP extension
    - CVE-2026-6722  [soap]
  * SECURITY UPDATE: XSS via incorrect sanitization
    - CVE-2026-6735  [fpm status]
  * SECURITY UPDATE: DoS via passing signed chars
    - CVE-2026-7258  [Zend]
  ...

À retenir : une 8.4.11 Ubuntu patchée peut être aussi sûre qu'une 8.4.27 upstream face à une CVE donnée. Pour vérifier une faille précise, cherchez son identifiant CVE dans le changelog du paquet ou sur ubuntu.com/security/cves.

Appliquer le correctif sans tout mettre à jour

Sur un serveur de production, on veut patcher PHP rapidement sans embarquer les 200 autres paquets en attente. --only-upgrade limite l'opération aux paquets déjà installés :

sudo apt-get update
PKGS=$(apt list --upgradable 2>/dev/null \
  | grep -E '^(php|libapache2-mod-php)' | cut -d/ -f1)
sudo apt-get install --only-upgrade -o Dpkg::Options::=--force-confold $PKGS

--force-confold conserve vos php.ini et pools FPM modifiés. Pensez ensuite à redémarrer le bon service. Vérifiez d'abord qui sert réellement le site : sur mon VPS, Apache et libapache2-mod-php étaient installés… mais c'est nginx qui écoutait sur le port 443, avec PHP-FPM derrière.

sudo ss -tlnp | grep -E ':(80|443) '   # qui écoute vraiment ?
sudo systemctl restart php8.4-fpm

Le vrai problème : une distribution en fin de vie

En creusant, deux choses m'ont alerté sur mon VPS :

  1. Il tournait sous Ubuntu 25.10, une version intermédiaire supportée seulement 9 mois. Elle est en fin de vie depuis juillet 2026 : plus aucun correctif ne sortira.
  2. Le dépôt -security n'était même pas configuré dans /etc/apt/sources.list.d/ubuntu.sources. Les correctifs n'arrivaient que parce qu'ils sont recopiés dans -updates.
grep -E 'Suites' /etc/apt/sources.list.d/ubuntu.sources
# Attendu : une entrée contenant "questing-security"

Et pour obtenir la vraie 8.4.27, le PPA ondrej/php est la référence, mais il ne publie que pour les versions LTS. Sur une version intermédiaire en fin de vie, on obtient une 404. La seule solution propre est de migrer vers une LTS (26.04), avec cinq ans de correctifs.

Leçon : pour un serveur de production, choisissez toujours une version LTS. Les versions intermédiaires sont faites pour les postes de développement, pas pour un VPS qu'on oublie pendant des mois.

Avant de migrer : vérifiez vos sauvegardes

Une montée de version d'OS n'est jamais sans risque. Avant de lancer do-release-upgrade, j'ai voulu m'appuyer sur ma sauvegarde nocturne de la base MySQL… et j'ai découvert qu'elle ne tournait plus depuis neuf mois. En cause, cette ligne :

# /etc/cron.d/gabi77-backup : NE FONCTIONNE PAS
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Correct : les fichiers de /etc/cron.d exigent un champ utilisateur
0 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Contrairement à crontab -e, les fichiers de /etc/cron.d/ ont un sixième champ : l'utilisateur. Sans lui, cron interprète le chemin du script comme un nom d'utilisateur et abandonne en silence. Le fichier de log n'existait même pas, ce qui aurait dû m'alerter plus tôt.

Ma checklist avant toute migration :

  • Snapshot du VPS chez l'hébergeur : c'est le seul vrai retour arrière
  • Dump MySQL frais, vérifié (zcat dump.sql.gz | grep -c "CREATE TABLE")
  • Archive du code (/var/www) et des configurations (/etc/apache2, /etc/php, /etc/letsencrypt, /etc/cron.d)
  • Liste des paquets installés : dpkg --get-selections > packages.txt
  • Tout rapatrier hors du serveur (rsync vers une autre machine)
  • Tester le code sous la future version de PHP, sans toucher au serveur : docker run --rm -v "$PWD":/app -w /app php:8.5-cli php -l fichier.php

La migration vers Ubuntu 26.04 LTS

La migration elle-même tient en trois étapes : mettre à jour complètement la version actuelle, redémarrer, puis lancer l'outil de migration. Je la lance dans tmux pour qu'une coupure SSH ne l'interrompe pas en plein milieu :

sudo apt update && sudo apt full-upgrade && sudo reboot
# puis, après reconnexion :
tmux new -s upgrade
sudo do-release-upgrade

Une trentaine de minutes plus tard : Ubuntu 26.04.1 LTS, PHP 8.5.4… et un site en erreur 502. Deux causes :

  1. La migration avait supprimé php8.4-fpm sans installer php8.5-fpm : les extensions avaient été migrées vers la 8.5, mais pas FPM. Vérifiez avec dpkg -l | grep php8.5 juste après la migration.
  2. La configuration nginx pointait en dur sur l'ancien socket : fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
sudo apt install php8.5-fpm
sudo sed -i 's#php8.4-fpm.sock#php8.5-fpm.sock#' /etc/nginx/sites-available/monsite.conf
sudo nginx -t && sudo systemctl reload nginx

Astuce : comparez l'ancien et le nouveau pool FPM avant de supprimer définitivement les fichiers de la 8.4, pour ne perdre aucun réglage personnalisé : diff <(grep -vE '^\s*(;|$)' /etc/php/8.4/fpm/pool.d/www.conf) <(grep -vE '^\s*(;|$)' /etc/php/8.5/fpm/pool.d/www.conf)

Dernier point : la migration n'ajoute pas le dépôt de sécurité s'il était absent avant. Je l'ai ajouté à la main dans /etc/apt/sources.list.d/ubuntu.sources :

Types: deb
URIs: http://security.ubuntu.com/ubuntu
Suites: resolute-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

Pour finir, vérifiez tout ce qui s'exécute en dehors du navigateur : les crons (générateur de sitemap, sauvegardes) tournent désormais avec le nouveau binaire PHP.

Conclusion

Face à une faille PHP critique, la bonne question n'est pas « quelle version afficher ? » mais « le correctif est-il appliqué ? ». Sur Ubuntu, la réponse est dans le changelog du paquet. Mettre à jour PHP a surtout été l'occasion de vérifier le reste : distribution en fin de vie, dépôt de sécurité absent, sauvegardes cassées sans que personne s'en aperçoive. Résultat : un serveur en 26.04 LTS, supporté jusqu'en 2031, et PHP 8.5. Un audit de dix minutes qui vaut la peine d'être refait régulièrement.

Sources :

Tags

CVE DevOps PHP Sécurité Ubuntu VPS

Partager

Articles similaires

Besoin d'aide sur votre projet ?

Discutons de vos besoins et trouvons ensemble la meilleure solution technique.

Me contacter