En resumen: php-cgi es la forma más antigua de ejecutar PHP detrás de un servidor web y sigue funcionando en muchos servidores, a menudo sin que se note. La vulnerabilidad de php-cgi de PHP2Shell afecta expresamente a este modo de funcionamiento. Parchee, finalice todos los procesos php-cgi en ejecución y planifique el paso a PHP-FPM.
Qué es php-cgi y dónde sigue funcionando
PHP existe en varias variantes: como programa de línea de comandos, como módulo de Apache, como PHP-FPM y como php-cgi. php-cgi es un programa que inicia el servidor web y al que pasa las solicitudes mediante CGI o FastCGI. Sin gestión de procesos propia, es más sencillo que PHP-FPM, pero también menos controlable.
Los lugares típicos donde aparece son los paneles de hosting antiguos, Apache con mod_fcgid, scripts envoltorio propios para varias versiones de PHP y PHP en Windows con IIS mediante FastCGI. En agencias y administraciones se encuentran además servidores configurados hace años y que desde entonces solo se han mantenido en funcionamiento.
La vulnerabilidad de php-cgi en PHP2Shell
PHP2Shell comprende las vulnerabilidades CVE-2026-109618 y CVE-2026-109619 en el propio PHP, cada una con un CVSS v4.0 de 9,2. Ambas permiten ejecutar código malicioso sin autenticación. El proyecto PHP cita expresamente php-cgi entre los modos de funcionamiento afectados, junto con PHP-FPM, mod_php, FrankenPHP y LiteSpeed.
Están corregidas PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35. Para PHP 8.1 y anteriores ya no hay actualizaciones oficiales, solo backports mínimos del código fuente para 7.4, 8.0 y 8.1. Precisamente las configuraciones con php-cgi funcionan con una frecuencia superior a la media sobre versiones antiguas. Además, no es la primera vez que php-cgi se ve afectado: ya en 2024, una vulnerabilidad en php-cgi en Windows (CVE-2024-4577) dio mucho que hablar. Las herencias de este tipo merecen por eso una atención especial.
Localizar php-cgi en el servidor
Los comandos siguientes solo leen y ayudan a localizar php-cgi. Las rutas y los nombres de módulos son ejemplos.
# Procesos php-cgi en ejecución con hora de inicio y usuario
ps -eo pid,lstart,user,cmd | grep -E 'php-cgi|php[0-9.]*-cgi' | grep -v grep
# Programas php-cgi instalados
ls /usr/bin/php*-cgi /usr/lib/cgi-bin/php* 2>/dev/null
# Apache: ¿están cargados mod_fcgid o mod_cgi?
apache2ctl -M 2>/dev/null | grep -Ei 'fcgid|cgi'
grep -RniE 'FcgidWrapper|AddHandler.*php|Action.*php' /etc/apache2 /etc/httpd 2>/dev/null
Si encuentra entradas FcgidWrapper o manejadores que apuntan a un programa php-cgi, ese es el modo de funcionamiento. Compruebe la versión de cada programa encontrado con -v. En los paquetes de distribución, el parche lo demuestra el registro de cambios con los números CVE, porque los backports suelen no cambiar el número de versión.
Parchear y finalizar todos los procesos
Instale la actualización con el gestor de paquetes o con la fuente de la que procede php-cgi. Después deben desaparecer todos los procesos php-cgi en ejecución. Con mod_fcgid, Apache mantiene procesos en reserva durante un tiempo; un reinicio completo de Apache los finaliza.
# Reiniciar Apache por completo (Debian/Ubuntu o familia RHEL)
systemctl restart apache2 # o: systemctl restart httpd
# Control: ¿quedan procesos php-cgi más antiguos que la actualización?
ps -eo pid,lstart,cmd | grep -E 'php-cgi' | grep -v grep
Si php-cgi funciona mediante un gestor de procesos propio o un servicio del panel, reinícielo. En Windows con IIS, recicle los grupos de aplicaciones; véase PHP en Windows e IIS.
Si php-cgi funciona con PHP 8.1 o anterior en un servidor accesible públicamente, falta un parche oficial. Aplique de inmediato las medidas provisionales y considere, según la recomendación del BSI, desconectar temporalmente el servidor de la red.
Medidas provisionales con php-cgi
php.net recomienda medidas provisionales que no ofrecen una protección completa. Con php-cgi, los valores van en el php.ini que carga el programa correspondiente o en la configuración del servidor. Según php.net, los archivos .user.ini e ini_set() no bastan para session.upload_progress.enabled.
; php.ini de la instalación de php-cgi
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
Con función de carga de archivos, php.net indica post_max_size = 32M. En PHP 8.5 se añade fatal_error_backtraces=0. Los límites de memoria se fijan mediante cgroups para el servicio del servidor web, y no mediante RLIMIT_AS ni RLIMIT_DATA. Después, reinicie todos los procesos.
El camino hacia PHP-FPM
A la larga, php-cgi no es una buena opción. PHP-FPM ofrece pools por sitio web, usuarios propios, límites por pool, páginas de estado y reinicios controlados. El cambio suele ser bien planificable: instalar PHP-FPM, crear los pools, cambiar el servidor web a FastCGI hacia PHP-FPM y eliminar los scripts envoltorio. Cómo es una configuración limpia se muestra en Proteger Nginx con PHP-FPM. Si además funciona una versión antigua de PHP, combine el cambio con la actualización de versión.
Hasta que se haga el cambio, debería revisar con ojo crítico la configuración existente. El servidor web solo debería pasar a php-cgi archivos con la extensión .php, y no rutas que apunten a archivos inexistentes. En los directorios de cargas no debe ser posible ejecutar PHP. Revise los scripts envoltorio que cargan un php.ini propio para cada sitio web, por si esos archivos anulan de nuevo los valores provisionales. Si un programa php-cgi está directamente en un directorio accesible públicamente como cgi-bin, hay que eliminarlo de allí. Estas herencias suelen proceder de instrucciones de instalación de años pasados y simplemente se olvidan en reformas posteriores. Documente cada hallazgo con su ruta y finalidad, para que la reforma posterior no deje nada sin revisar.
Sigue siendo importante: un parche no elimina el software malicioso introducido antes. Conserve los registros desde el 20/10/2026.
¿Cómo ayuda PHP SOS en concreto?
- Localizamos las instalaciones de php-cgi, los scripts envoltorio y los manejadores y los asignamos a los sitios web.
- Parcheamos, finalizamos todos los procesos antiguos y documentamos el estado.
- Para PHP 8.1 y anteriores planificamos con usted la migración a una versión de PHP compatible.
- Dentro del refuerzo de servidores sustituimos php-cgi por PHP-FPM con pools separados.
Preguntas frecuentes
¿Uso php-cgi sin saberlo?
Es más frecuente de lo que se piensa. Los paneles antiguos, las configuraciones FastCGI con mod_fcgid y PHP en Windows con IIS suelen iniciar PHP como php-cgi. Una lista de procesos o la Server API en phpinfo lo muestran con fiabilidad.
¿Es FastCGI lo mismo que php-cgi?
No exactamente. FastCGI es un protocolo. Tanto PHP-FPM como php-cgi pueden hablar FastCGI, pero php-cgi es el programa más antiguo y sencillo, sin pools ni gestión de procesos. PHP2Shell afecta expresamente a php-cgi.
¿Qué significa CGI clásico en PHP?
En el CGI clásico, el servidor web inicia un proceso PHP nuevo para cada solicitud. Es lento y hoy poco habitual. Es más frecuente php-cgi detrás de mod_fcgid o FastCGI, donde los procesos atienden varias solicitudes.
¿Tengo que reiniciar algo después de la actualización?
Sí. En las configuraciones FastCGI, los procesos php-cgi siguen funcionando un tiempo. Reinicie el servidor web o el gestor de procesos y compruebe que no quede ningún proceso php-cgi más antiguo que la actualización.