En bref : CGI (Common Gateway Interface) est une ancienne interface dans laquelle le serveur web lance un nouveau programme pour chaque requête, pour PHP le programme php-cgi. FastCGI en est l'évolution : les processus PHP tournent en permanence et reçoivent de nombreuses requêtes via un socket. PHP-FPM est la principale mise en œuvre de FastCGI pour PHP. Du point de vue de la sécurité, ce sont surtout les réglages cgi.* et la règle selon laquelle un accès FastCGI ne doit jamais être joignable publiquement qui comptent.
Qu'est-ce que CGI ?
CGI est l'une des plus anciennes méthodes par lesquelles les serveurs web produisent des contenus dynamiques. À propos du réglage cgi.rfc2616_headers, le manuel PHP renvoie à la RFC 3875, la spécification du Common Gateway Interface. Les débuts de PHP étaient eux aussi des programmes CGI : Rasmus Lerdorf a écrit en 1994 les premiers « Personal Home Page Tools » sous forme de binaires CGI en C.
Le principe : pour chaque requête, le serveur web lance un nouveau processus, lui transmet les données de la requête par des variables d'environnement et l'entrée standard, et lit la réponse sur la sortie standard. Le processus se termine ensuite. Selon le manuel PHP, avec CGI et CLI, PHP relit son php.ini à chaque appel, avec les modules serveur seulement au démarrage.
Cela rend CGI robuste, car chaque requête démarre avec un processus neuf. Mais cela le rend aussi lent : le démarrage du processus, le chargement de la configuration et l'initialisation des extensions coûtent du temps à chaque requête.
Qu'est-ce que FastCGI ?
FastCGI résout le problème de performance en maintenant les processus en vie. Le serveur web se connecte à un processus en cours d'exécution par un socket Unix ou un port TCP et lui envoie la requête dans le protocole FastCGI. Le processus la traite et attend la suivante.
| Caractéristique | CGI | FastCGI avec php-cgi | FastCGI avec PHP-FPM |
|---|---|---|---|
| Processus par requête | oui | non | non |
| Nom de la SAPI | cgi-fcgi |
cgi-fcgi |
fpm-fcgi |
| Pools avec utilisateur propre | non | non | oui |
| Pilotage des processus | serveur web | module du serveur web, p. ex. mod_fcgid | processus maître propre |
.user.ini est lu |
oui | oui | oui |
Selon le manuel, PHP-FPM est l'implémentation FastCGI principale de PHP. Il complète le protocole avec la gestion des processus, des pools, des pages d'état et un slowlog. Les détails figurent sous PHP-FPM expliqué.
Les réglages cgi dans le php.ini
Pour l'exploitation en CGI, PHP connaît ses propres réglages. Les valeurs et descriptions suivantes proviennent du manuel PHP :
cgi.force_redirect(par défaut 1,INI_SYSTEM) : selon le manuel, nécessaire pour exploiter PHP en CGI de façon sûre avec la plupart des serveurs web. Ne le désactiver qu'« à vos propres risques » ; sous IIS, il doit être désactivé.cgi.fix_pathinfo(par défaut 1,INI_SYSTEM) : assure des valeurs correctes pourPATH_INFOetPATH_TRANSLATED. Les scripts doivent utiliserSCRIPT_FILENAMEplutôt quePATH_TRANSLATED.cgi.discard_path(par défaut 0,INI_SYSTEM) : permet de placer le binaire CGI en toute sécurité en dehors du répertoire web, sans que la protection par.htaccesspuisse être contournée.fastcgi.impersonate(par défaut 0,INI_SYSTEM) : pertinent uniquement pour IIS sous Windows.user_ini.filenameetuser_ini.cache_ttl(par défaut.user.iniet 300 secondes) : déterminent si et à quelle fréquence PHP lit les fichiers.user.ini.
Avec Nginx, il faut en outre une transmission correcte du chemin du script. Un modèle de base lisible, sans garantie pour chaque environnement :
location ~ \.php$ {
try_files $uri =404; # ne transmettre à PHP que les fichiers existants
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
La ligne try_files $uri =404; empêche que des requêtes vers des chemins .php inexistants soient transmises à PHP.
Pourquoi un accès FastCGI ouvert est dangereux
Le manuel PHP avertit expressément : qui peut ouvrir une connexion FastCGI vers PHP contrôle la configuration de la requête, par exemple auto_prepend_file, et peut ainsi exécuter du code arbitraire. La raison est que les serveurs web peuvent transmettre des réglages PHP via des paramètres FastCGI comme PHP_VALUE et PHP_ADMIN_VALUE.
Des règles claires en découlent :
- Ne raccorder PHP-FPM ou php-cgi en mode FastCGI que par un socket Unix lorsque le serveur web tourne sur le même hôte.
- Avec TCP, définir
listen.allowed_clientset bloquer le port dans le pare-feu ; des indications figurent dans l'article Pare-feu pour serveurs web. - Restreindre strictement les droits du socket avec
listen.owner,listen.groupetlisten.mode.
Vérifiez avec ss -lntp | grep -i php si un processus PHP écoute sur une adresse TCP. Une liaison à 0.0.0.0 ou à une adresse publique appelle une action urgente.
CGI, FastCGI et PHP2Shell
PHP2Shell concerne aussi bien php-cgi que PHP-FPM. Pour les deux, il faut : mise à jour vers 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, ou un rétroportage confirmé, puis arrêt et redémarrage de tous les processus PHP en cours. Dans les configurations FastCGI avec php-cgi, les processus continuent souvent de tourner sans qu'on le remarque, car aucun service dédié ne les gère. La manière de trouver et de remplacer cet héritage figure sous php-cgi : un héritage à risque. Dans Plesk, les variantes portent d'autres noms ; l'article Plesk : comprendre les gestionnaires PHP aide à s'y retrouver.
Comment PHP SOS aide-t-il concrètement ?
- Recenser les gestionnaires : nous déterminons si vos sites web fonctionnent via CGI, FastCGI avec php-cgi ou PHP-FPM.
- Fermer les accès : nous vérifions les sockets, ports et règles de pare-feu pour qu'aucun accès FastCGI ne soit joignable de l'extérieur.
- Corriger et nettoyer : nous mettons PHP à jour et arrêtons tous les anciens processus, y compris les instances php-cgi orphelines.
- Remplacer : dans le cadre du durcissement de serveur, nous remplaçons les héritages CGI par PHP-FPM avec des pools distincts.
Questions fréquentes
FastCGI est-il la même chose que PHP-FPM ?
Non. FastCGI est un protocole par lequel un serveur web dialogue avec un processus d'application. PHP-FPM est un programme qui met en œuvre ce protocole pour PHP et gère les processus. php-cgi peut aussi parler FastCGI, mais n'offre pas de pools.
Pourquoi le CGI pur est-il considéré comme obsolète ?
Avec CGI, le serveur web lance un nouveau processus pour chaque requête, et PHP relit chaque fois sa configuration. Cela coûte du temps et des ressources. FastCGI et PHP-FPM gardent des processus prêts en permanence et sont donc nettement plus efficaces.
Qu'est-ce qu'un .user.ini ?
Un .user.ini est un petit fichier de configuration placé dans un répertoire web. Selon le manuel PHP, il n'est lu que par les SAPI CGI et FastCGI, donc aussi par PHP-FPM. Il ne peut contenir que des réglages des modes INI_PERDIR, INI_USER ou INI_ALL.
Comment savoir si php-cgi tourne sur mon serveur ?
Avec des commandes en lecture seule comme ps ou pgrep, cherchez des processus nommés php-cgi, et examinez dans la configuration du serveur web des entrées comme mod_fcgid, Action ou ScriptAlias avec php-cgi. Dans les panneaux d'hébergement, ce mode d'exécution s'appelle souvent CGI ou application FastCGI.