On pense être tranquille avec des mises à jour régulières, et puis paf, une nouvelle vulnérabilité comme PHP2Shell arrive et nous rappelle que la vigilance est de mise. Récemment, les alertes concernant des vulnérabilités d'exécution de code à distance (RCE) en PHP (notamment les CVE-2026-109618, CVE-2026-109619 et CVE-2026-115560) m'ont fait transpirer à grosses gouttes. Bien sûr, la première chose à faire est de patcher son PHP. Mais est-ce vraiment suffisant ?
Comme tout bon homelabber/développeur qui se respecte, je suis un adepte de la défense en profondeur. Un peu parano ? Peut-être, mais mes serveurs me remercient. C'est dans cette optique que je me suis penché sur le toolkit syhunt/php2shell-protection. Ce n'est pas une baguette magique qui corrige tout, loin de là, mais c'est une sacrée couche de protection supplémentaire pour durcir son environnement PHP.
PHP2Shell et les RCE : comprendre le risque
Avant de plonger dans le vif du sujet, un petit rappel sur les RCE en PHP. En gros, une RCE permet à un attaquant d'exécuter du code arbitraire sur votre serveur. Ça peut aller du simple affichage d'informations sensibles à la prise de contrôle totale de votre machine. Les vulnérabilités comme PHP2Shell exploitent souvent des failles dans la gestion des requêtes HTTP, notamment les requêtes multipart/form-data, ou des problèmes de corruption de mémoire. Le problème, c'est que même avec des versions PHP patchées, il peut y avoir des scénarios où une mauvaise configuration ou un oubli laisse une porte ouverte. D'où l'intérêt de ne pas mettre tous ses œufs dans le même panier et d'ajouter des barrières.
syhunt/php2shell-protection : le bouclier temporaire
Le projet syhunt/php2shell-protection est un kit d'outils développé par Syhunt. Il a été conçu spécifiquement pour aider à mitiger les risques liés aux vulnérabilités PHP2Shell, mais il va au-delà en proposant des mesures de durcissement générales pour les environnements PHP. Attention, et c'est important de le répéter : ce n'est PAS un substitut aux versions PHP patchées. C'est une mesure de défense en profondeur, une rustine robuste en attendant mieux, ou une couche supplémentaire une fois que tout est à jour. Pensez-y comme à un gilet pare-balles : ça aide, mais ça ne rend pas invincible.
Mise en œuvre : installer et configurer les protections
L'installation est simple, car il ne s'agit pas d'un paquet à installer via Composer ou autre. C'est un dépôt GitHub avec des fichiers de configuration à appliquer manuellement. La première étape est donc de le récupérer :
git clone https://github.com/syhunt/php2shell-protection.git cd php2shell-protection
Durcissement Apache via .htaccess
Le toolkit propose des exemples de configuration Apache, notamment via un fichier .htaccess. L'idée principale est de bloquer ou de limiter certaines requêtes suspectes. Si votre application n'a pas besoin de requêtes POST avec un Content-Type multipart/form-data (par exemple, si vous ne gérez pas d'uploads de fichiers), vous pouvez les bloquer purement et simplement. C'est une mitigation partielle pour certaines RCE.
Voici un extrait de ce que vous pourriez ajouter à votre .htaccess (ou directement dans la configuration de votre hôte virtuel Apache), inspiré de httpd/.htaccess.example :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{HTTP:Content-Type} ^multipart/form-data [NC]
RewriteRule .* - [F,L]
</IfModule>
Cette règle bloque toute requête POST de type multipart/form-data. Testez bien sûr si votre application en a besoin !
Une autre bonne pratique est de limiter la taille du corps des requêtes. Cela peut aider à prévenir les attaques par déni de service ou les tentatives d'exploitation de vulnérabilités par corruption de mémoire qui nécessitent de grandes quantités de données. Dans votre configuration Apache (pas dans .htaccess pour LimitRequestBody), vous pouvez ajouter :
LimitRequestBody 10485760
Ici, j'ai mis 10 Mo (10485760 octets). Adaptez cette valeur à vos besoins réels.
Durcissement PHP via php.ini
Le toolkit fournit également un exemple de fichier php-session-hardening.ini.example, mais les points les plus cruciaux pour les mitigations des RCE sont les suivants, à configurer directement dans votre php.ini ou via la configuration de votre serveur (PHP-FPM par exemple), et non via ini_set() qui serait trop tardif :
- Désactiver la progression des téléchargements de session : C'est une source potentielle de vulnérabilité.
session.upload_progress.enabled = Off
- Limiter la taille des requêtes POST et des fichiers téléchargés : Des valeurs trop généreuses peuvent être exploitées.
post_max_size = 32M upload_max_filesize = 30M
Assurez-vous toujours que upload_max_filesize est inférieur à post_max_size.
- Gérer la limite de mémoire pour CVE-2026-109618 : Pour la vulnérabilité de corruption OOM (Out Of Memory), une astuce est de définir
memory_limit=-1viaphp_admin_value(pour que l'application ne puisse pas le modifier) et de s'appuyer sur les limites de mémoire de cgroup/conteneur.
php_admin_value memory_limit -1
- Mitigation pour PHP 8.5+ (CVE-2026-109619) :
fatal_error_backtraces=0
Après chaque modification de php.ini ou de la configuration Apache, n'oubliez pas de redémarrer vos services PHP (PHP-FPM, Apache, etc.). C'est un piège classique : les processus en cours d'exécution conservent l'ancienne configuration. Si vous utilisez Docker, cela signifie reconstruire vos images et relancer vos conteneurs.
Audit de sécurité : vérifier ses protections
Le toolkit contient des scripts de test, mais pour une vérification rapide de ces protections, l'approche est plutôt de tenter de les contourner et de surveiller. Par exemple :
- Tentez d'envoyer une requête
POSTavecmultipart/form-datasi vous l'avez bloquée. Vous devriez obtenir une erreur 403 Forbidden. - Envoyez une requête
POSTavec un corps de requête plus grand que votreLimitRequestBodyconfiguré. Le serveur devrait la rejeter. - Surveillez vos logs Apache et PHP-FPM. Recherchez des messages d'erreur liés aux requêtes
POST, des épuisements de mémoire inattendus, ou des erreurs fatales précoces. Une surveillance active est votre meilleure ligne de défense pour détecter des tentatives d'exploitation.
Bonnes pratiques complémentaires : ne pas relâcher la garde
Même avec syhunt/php2shell-protection, il est vital de ne pas se reposer sur ses lauriers. Voici les mesures complémentaires absolument essentielles :
- Mettre à jour PHP IMMÉDIATEMENT : C'est la solution la plus complète. Les versions patchées sont PHP 8.2.35, 8.3.36, 8.4.27, et 8.5.12. Si vous êtes sur une version PHP en fin de vie (8.1 ou antérieure), vous êtes en danger et devez migrer ou chercher des backports auprès de votre distribution.
- Reconstruire et redémarrer : Après toute mise à jour ou modification de configuration, assurez-vous que tous vos workers PHP (PHP-FPM, modules Apache) sont bien redémarrés et que vos images Docker sont reconstruites.
- Utiliser un WAF : Un Web Application Firewall (comme Cloudflare) peut intercepter et bloquer des requêtes malveillantes avant qu'elles n'atteignent votre serveur. De nombreux WAF ont déployé des protections spécifiques contre PHP2Shell.
- Limiter les requêtes au niveau du proxy/serveur web : Au-delà de
LimitRequestBody, vous pouvez configurer votre proxy inverse (Nginx, Traefik) pour limiter la taille des requêtes, le nombre de champs, ou la profondeur d'imbrication des données. - Faire l'inventaire : Connaissez toutes vos installations PHP ! Des vieux CMS oubliés aux conteneurs non mis à jour, chaque instance est une porte d'entrée potentielle.
Conclusion : vers une approche proactive
Les vulnérabilités RCE en PHP, comme PHP2Shell, sont un rappel brutal que la sécurité est un processus continu. Le toolkit syhunt/php2shell-protection est un excellent ajout à votre arsenal de défense en profondeur. Il ne remplace pas une mise à jour rapide et rigoureuse de PHP, mais il offre une couche de résilience supplémentaire, particulièrement utile si vous avez des contraintes de déploiement ou des environnements plus anciens à protéger. Adopter ces mesures, c'est passer d'une posture réactive à une approche proactive, et ça, ça n'a pas de prix pour la tranquillité d'esprit (enfin, presque).