PHP2Shell es un par de vulnerabilidades críticas en el propio motor de PHP, CVE-2026-109618 y CVE-2026-109619, publicadas el 21 de octubre de 2026 con una gravedad CVSS de 9.2. En un entorno de ejecución sin parchear, un atacante sin cuenta puede ejecutar código como el worker de PHP o leer la memoria del proceso, que contiene contraseñas, tokens de sesión, claves de API y certificados. No hace falta que el código de su aplicación tenga ningún fallo: según los investigadores, incluso una página «Hello World» en una versión afectada de PHP puede quedar expuesta. La única solución real es una versión corregida de PHP, seguida del reinicio de cada proceso que ejecute PHP. Esta guía le da los comandos.
Qué versiones están corregidas
| Rama | Vulnerable | Corregido en |
|---|---|---|
| 8.2 | anterior a 8.2.35 | 8.2.35 |
| 8.3 | anterior a 8.3.36 | 8.3.36 |
| 8.4 | anterior a 8.4.27 | 8.4.27 |
| 8.5 | anterior a 8.5.12 | 8.5.12 |
PHP 8.1, 8.0 y 7.x han llegado al final de su vida útil y no recibirán corrección. Si todavía los utiliza, el parche consiste en pasar a una rama con soporte.
Las distribuciones Linux suelen incorporar las correcciones de seguridad a sus propios paquetes (backport) sin cambiar al número de versión upstream. En esos sistemas, la versión por sí sola no basta: busque los dos números CVE en el registro de cambios del paquete (paso 2).
Paso 1: localice cada entorno PHP
Empiece por el inventario, porque el entorno del que nadie se acordaba es el que acaba atacado. En cada servidor:
php -v
systemctl list-units --type=service --all 'php*' 'apache2*' 'httpd*'
ls /usr/sbin/php-fpm* /usr/bin/php[0-9]* 2>/dev/null
La primera línea muestra la versión de la CLI; la segunda, los pools de PHP-FPM y los servidores web en ejecución; y la tercera, todas las versiones de PHP instaladas en paralelo (una fuente habitual de entornos olvidados). Liste también los paquetes instalados:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
rpm -qa 'php*' 'ea-php*' # RHEL, AlmaLinux, Rocky, cPanel
En contenedores, compruebe la versión de PHP dentro de cada imagen en ejecución:
docker ps --format '{{.Names}}' | while read c; do printf '%s: ' "$c"; docker exec "$c" php -r 'echo PHP_VERSION, PHP_EOL;' 2>/dev/null || echo 'no php'; done
No olvide los servidores de preproducción, de cron y de colas, los agentes de compilación ni los planes de alojamiento gestionado. Si tiene un plan de alojamiento, pregunte por escrito al proveedor qué compilación de PHP utiliza y cuándo se parcheó.
Paso 2: instale la versión corregida
Debian y Ubuntu (sustituya 8.3 por su rama):
sudo apt update
sudo apt install --only-upgrade 'php8.3*'
apt changelog php8.3-fpm | grep -E 'CVE-2026-10961[89]'
RHEL, AlmaLinux, Rocky Linux:
sudo dnf upgrade 'php*'
rpm -q --changelog php-fpm | grep -E 'CVE-2026-10961[89]'
Servidores cPanel con paquetes de EasyApache 4:
sudo dnf upgrade 'ea-php*' # older systems: sudo yum update 'ea-php*'
Alpine Linux (los nombres de paquete incluyen la rama, p. ej. php83):
apk update && apk upgrade 'php83*'
Imágenes Docker: fije la etiqueta corregida en el Dockerfile, por ejemplo FROM php:8.3.36-fpm, y después reconstruya sin caché y sustituya los contenedores en ejecución:
docker build --pull --no-cache -t myapp:php2shell .
docker compose up -d --build --force-recreate
Si el grep sobre el changelog no muestra nada, su distribución aún no ha publicado la corrección. Siga comprobando, use la versión oficial de php.net allí donde compile PHP usted mismo y, mientras tanto, aplique las medidas provisionales que se indican más abajo.
Paso 3: reinicie todo lo que cargó el PHP antiguo
Un paquete nuevo no cambia nada en los procesos que ya están en ejecución. Reinícielos:
sudo systemctl restart php8.3-fpm # Debian, Ubuntu (one per installed version)
sudo systemctl restart php-fpm # RHEL family
sudo systemctl restart apache2 # Apache with mod_php (httpd on RHEL)
sudo supervisorctl restart all # long-running workers under Supervisor
php artisan queue:restart # Laravel queue workers
En Debian y Ubuntu, sudo needrestart -r l muestra los servicios que aún usan bibliotecas antiguas.
Paso 4: verifique
Compruebe de nuevo cada entorno, esta vez el que usa el servidor web, no solo la CLI:
php-fpm8.3 -v # or: php-fpm -v
systemctl status php8.3-fpm | grep Active
La versión debe ser igual o superior a la versión corregida (o el changelog del paquete debe incluir ambos CVE), y la hora de «Active: since» debe ser posterior a la actualización. En WordPress también puede consultar la versión en Herramientas, Salud del sitio, Información, Servidor. No publique una página phpinfo() para comprobarlo: revela exactamente lo que buscan los atacantes.
Cuando la actualización tiene que esperar
Estos ajustes propuestos por los investigadores reducen la exposición mientras prepara la actualización. No son una solución:
; php.ini
post_max_size = 8M ; as low as your uploads allow
max_input_nesting_level = 32 ; as low as your forms allow
session.upload_progress.enabled = 0
fatal_error_backtraces = 0 ; where your PHP version supports it
; PHP-FPM pool: recycle workers more often (costs performance)
pm.max_requests = 100
Los valores son ejemplos; pruébelos con su aplicación. Configurar memory_limit = -1 bloquea algunas vías de ataque, pero úselo solo junto con un límite del sistema operativo como memory.max de cgroup v2, y nunca sustituya ese límite por RLIMIT_AS o RLIMIT_DATA. Las reglas WAF y CDN de su proveedor sirven de puente, no de sustituto de la actualización.
Busque indicios de un ataque
No existe una única regla de detección. Estos comandos sacan a la luz las señales que describen los investigadores:
grep -E 'Allowed memory size of [0-9]+ bytes exhausted' /var/log/php*-fpm.log /var/log/apache2/error.log
grep -E 'exited on signal (6|11)' /var/log/php*-fpm.log
awk '$9 == 500' /var/log/nginx/access.log | wc -l
Los errores de límite de memoria tras peticiones multipart inusuales, las ráfagas de respuestas HTTP 500, los workers de PHP que se caen por señales y las cookies PHPSESSID inusualmente grandes en las respuestas merecen un análisis más detenido. Ninguno de ellos demuestra un ataque, y su ausencia no demuestra que no se haya visto afectado. Si los encuentra, conserve los registros, aplique el parche y rote los secretos que estaban en la memoria de PHP: contraseñas de bases de datos, claves de aplicación y tokens de API. Nuestro equipo de respuesta a incidentes puede hacerse cargo de la investigación, y nuestro servicio de seguridad gestionada puede vigilar sus servidores después del parche.
Por dónde empezar
- Ejecute los comandos de inventario en cada servidor y contenedor y anote cada versión de PHP.
- Actualice con su gestor de paquetes o reconstruya sus imágenes sobre una etiqueta corregida.
- Reinicie PHP-FPM, Apache y cada worker de PHP.
- Verifique la versión y la hora del reinicio, y guarde la salida como evidencia.
- Busque con grep en sus registros los indicios descritos arriba y rote los secretos en cualquier sistema que los muestre.
Detalles: sitio del aviso PHP2Shell, anuncio de la PHP Foundation, Wiz Research.

