PHP2Shell son dos vulnerabilidades críticas del propio PHP, CVE-2026-109618 y CVE-2026-109619, que pueden permitir que una petición web sin autenticación ejecute código en cualquier instalación de PHP que atienda peticiones web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP y LiteSpeed. Ambas se están explotando en entornos reales y figuran en el catálogo KEV de CISA. La corrección es PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35; PHP 8.1 y anteriores no reciben versión upstream. Actualice y, después, reconstruya y vuelva a desplegar todas las imágenes de contenedor que lleven PHP, incluidas las etiquetas antiguas que siguen en ejecución y las imágenes que entregó a clientes.
Parchear el servidor que conoce es la parte fácil. La exposición que perdura es el PHP del que se olvidó: un runtime compilado en una imagen base, una etiqueta de imagen del año pasado que sigue en producción, una imagen de CI o un producto entregado a clientes con un PHP al final de su vida útil. Esta página le ayuda primero a aplicar el parche y después le muestra cómo encontrar el resto.
Qué ha pasado
| Fecha (2026) | Evento | Fuente |
|---|---|---|
| 11 y 21 de agosto | Calif comunica los dos fallos al proyecto PHP | Calif |
| 17 de octubre | El primer intento de explotación que Amazon vio en sus honeypots, antes de la divulgación | Amazon Threat Intelligence |
| 20 de octubre | PHP anuncia una versión de seguridad para el 21 de octubre, a las 14:00 UTC, que corrige dos vulnerabilidades puntuadas con 9,2 en CVSS 4.0 | php.net |
| 21 de octubre | PHP publica 8.5.12, 8.4.27, 8.3.36 y 8.2.35 junto con su aviso; los registros CVE se hacen públicos; NCSC-NL abre su repositorio php2shell | Aviso de PHP, NCSC-NL |
| 21 de octubre | Las imágenes oficiales de Docker php se actualizan a las versiones corregidas | docker-library/php |
| 21 de octubre | watchTowr informa de la explotación de ambos CVE en entornos reales; CISA publica una alerta | watchTowr, CISA |
| 22 de octubre | Searchlight Cyber publica php2shell-scanner | GitHub |
| 23 de octubre | PHP aconseja establecer session.upload_progress.enabled=0 frente a un vector de RCE distinto y poco probable, CVE-2026-115560 | php.net |
| 26 de octubre | CISA añade ambos CVE al catálogo KEV, con fecha límite del 29 de octubre para las agencias federales de EE. UU. | CISA KEV |
El nombre PHP2Shell procede del análisis de Calif y se usa en toda la cobertura del sector; los avisos del propio PHP no lo utilizan. Los registros CVE atribuyen el hallazgo a Calif, Wiz y OpenAI.
Quién está afectado
Cualquier PHP que atienda peticiones web. El aviso de PHP menciona PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP y LiteSpeed, y considera que el riesgo es mayor con mod_php, «con un exploit demostrado en el que una petición sin autenticación puede desencadenar el ataque antes de que se ejecute código de la aplicación». Como los fallos están en el propio PHP, las aplicaciones creadas con Laravel, Symfony o WordPress quedan expuestas siempre que lo esté el PHP sobre el que se ejecutan.
| Rama | Afectada | Corregida en | Soporte upstream |
|---|---|---|---|
| 8.5 | anteriores a 8.5.12 | 8.5.12 | Activo |
| 8.4 | anteriores a 8.4.27 | 8.4.27 | Activo |
| 8.3 | anteriores a 8.3.36 | 8.3.36 | Solo correcciones de seguridad, hasta el 31 de diciembre de 2027 |
| 8.2 | anteriores a 8.2.35 | 8.2.35 | Solo correcciones de seguridad, hasta el 31 de diciembre de 2026 |
| 8.1, 8.0, 7.4 | todas las versiones, según Calif y watchTowr | sin versión; backports mínimos del código fuente en php-src | Fin de vida útil |
| 7.3 y anteriores, incluido PHP 5 | todas las versiones, según Calif y watchTowr | sin corrección upstream | Fin de vida útil |
Los avisos de PHP solo enumeran las ramas con soporte. Para las más antiguas, Calif informa de que «la ruta afectada más antigua que encontramos se remonta a PHP 5.4.0», y watchTowr indica que PHP 7 y PHP 5 están afectados y sin corrección. PHP afirma que las ramas 8.1 y anteriores «ya no reciben actualizaciones del proyecto PHP», pero publicó backports mínimos del código fuente para 7.4, 8.0 y 8.1 para quienes compilan desde el código fuente. Algunas distribuciones y proveedores comerciales de soporte a largo plazo ofrecen correcciones adaptadas para ramas al final de su vida útil; consulte al suyo. Si prueba la próxima versión mayor, PHP 8.6.0 RC4, publicada el mismo día, también incluye las correcciones.
Cómo funciona
Ambos CVE son fallos de seguridad de memoria en la forma en que PHP prepara y cierra una petición, por debajo de cualquier código de la aplicación. Los registros CVE clasifican ambos como use after free (CWE-416), junto con gestión incorrecta de condiciones excepcionales, acceso a un puntero no inicializado, asignación de memoria no controlada e inicialización incorrecta (CWE-755, CWE-824, CWE-1325, CWE-1419). En palabras de PHP:
- CVE-2026-109618, RCE mediante corrupción por OOM: «la gestión de la falta de memoria puede interrumpir PHP mientras los datos internos de la petición solo están parcialmente inicializados. La limpieza de la petición puede entonces tratar los datos no válidos como válidos». Un cuerpo de petición diseñado para agotar la memoria mientras PHP lo analiza puede provocar esa salida. Apache con mod_php ejecuta la limpieza incluso cuando ha fallado el inicio de la petición, y por eso el ataque funciona ahí antes de que se ejecute código de la aplicación. Para PHP-FPM, el aviso de PHP indica que el análisis del código fuente respalda que es susceptible, aunque no se ha demostrado ningún exploit completo para FPM.
- CVE-2026-109619, RCE mediante estado global obsoleto: «el estado interno perteneciente a una petición puede sobrevivir después de que se haya liberado la memoria que lo respalda. Una petición posterior atendida por el mismo worker puede usar ese estado obsoleto antes de que la inicialización normal lo restablezca». Hacen falta dos peticiones que lleguen al mismo worker: una que deje atrás el estado, por ejemplo mediante un error fatal, y otra que lo use. El aviso de PHP confirma la vía del progreso de subida de sesión contra mod_php y FPM, y la vía de los backtraces de errores fatales de PHP 8.5 contra mod_php.
Por eso los ajustes provisionales de PHP se centran en los límites de memoria, el tamaño del cuerpo de la petición, el progreso de subida de sesión y los backtraces de errores fatales: cada uno cierra una vía hacia los fallos, no los fallos en sí. PHP, como CNA, puntúa ambos con 9,2 en CVSS 4.0. Las evaluaciones propias de NVD en CVSS 3.1 son 9,8 para CVE-2026-109618 y 8,1 para CVE-2026-109619.
Cómo comprobar si está afectado
Empiece por los hosts que conoce y después busque PHP en todo lo que construye y entrega.
En un host o una VM, compruebe la versión que indica PHP. Compruebe también el SAPI web, ya que php-fpm o el módulo de Apache pueden proceder de un paquete distinto al de la línea de comandos:
php -v
php-fpm -v
Los paquetes de las distribuciones (Debian, Ubuntu, Alpine, RHEL) suelen recibir la corrección como backport sin una nueva versión upstream: Ubuntu 24.04, por ejemplo, incluye la corrección como 8.3.6-0ubuntu0.24.04.13. Aquí comprobar solo la versión induce a error. Liste el paquete instalado y compárelo con la versión corregida del paquete en el tracker de seguridad de su distribución:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
apk info -v | grep '^php' # Alpine
rpm -qa 'php*' # RHEL, Fedora, Rocky, Alma
En imágenes de contenedor. Las imágenes oficiales php: compilan PHP desde el código fuente, así que la versión está en la propia imagen, no en una lista de paquetes de la distribución. Pregunte directamente a la imagen:
docker run --rm --entrypoint php php:8.3-fpm -v
Para comprobar todas las imágenes que realmente ejecuta, enumérelas y pregunte a cada una. En Kubernetes:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
| sort -u \
| while read -r image; do
version=$(docker run --rm --entrypoint php "$image" -r 'echo PHP_VERSION;' 2>/dev/null)
printf '%s\t%s\n' "${version:-no php}" "$image"
done
Las imágenes construidas FROM debian o FROM alpine con PHP instalado mediante el gestor de paquetes necesitan la comprobación de paquetes anterior, ejecutada dentro de la imagen.
En sus repositorios, busque todos los lugares donde se elige PHP:
git grep -nE '^FROM[[:space:]]+(.*/)?php:' -- '*Dockerfile*' '*.dockerfile'
git grep -nE 'php-version|image:.*php' -- .github/workflows '*.yml' '*.yaml'
Las etiquetas fijadas como php:8.3.30-fpm siguen siendo vulnerables hasta que alguien las cambie. Las etiquetas flotantes como php:8.3-fpm se reconstruyeron con las versiones corregidas a partir del 21 de octubre, pero una imagen construida antes conserva el PHP antiguo hasta que la reconstruya. La restricción php de composer.json indica qué versiones acepta su código, no cuál se ejecuta.
En CI. Los jobs de build y de test suelen usar su propio PHP: un contenedor de servicio php:, una acción de configuración con una entrada php-version o una imagen de runner. No atienden tráfico de producción, pero muestran qué imágenes y versiones produce su pipeline.
Hosts expuestos. El php2shell-scanner de Searchlight Cyber sondea una URL con peticiones multipart grandes, de unos 29 MiB por ruta. Ejecútelo solo contra hosts que esté autorizado a probar. Su README advierte de falsos positivos en PHP parcheado con un memory_limit bajo, y cuando PHP no revela su versión, el escáner no puede distinguir un servidor parcheado de uno vulnerable. Trátelo como una pista, no como una prueba. El repositorio de NCSC-NL recopila reglas de detección y una lista de productos que incluyen PHP, con su estado.
Lo que no puede decirle el análisis de hoy. Analizar hoy las imágenes de su registry cubre lo que desplegaría hoy. No cubre una versión anterior que entregó a un cliente, la etiqueta antigua que un cliente sigue ejecutando ni cuáles de sus builds produjeron imágenes con un PHP vulnerable. Para eso necesita un registro de lo que incorporó cada build, por versión. Consulte ¿estamos afectados? cómo evaluar un nuevo CVE en todos sus builds.
Cómo corregirlo y qué hacer si aún no puede aplicar el parche
- Actualice a 8.5.12, 8.4.27, 8.3.36 o 8.2.35, o al paquete corregido de su distribución. Si está en 8.1 o anterior, pase a una rama con soporte; los backports de PHP y los builds de proveedores son soluciones provisionales.
- Reconstruya todas las imágenes a partir de una base corregida (vuelva a descargar la imagen base o construya sin caché) y vuelva a desplegarlas. Las imágenes que ya están en ejecución conservan su PHP antiguo hasta que se sustituyen, así que reinicie también las cargas de trabajo.
- Verifique con la lista de comprobación siguiente, en los contenedores en ejecución, no solo en la imagen nueva.
Si aún no puede actualizar, el aviso de PHP enumera medidas que «reducen la exposición a vías de ataque concretas, pero no hacen segura una instalación». Para CVE-2026-109618:
- «Establezca
memory_limit=-1, preferiblemente de forma que las aplicaciones no puedan sobrescribirlo, por ejemplo conphp_admin_valueen el pool de FPM o en la configuración de Apache, y compruebe que ningún ajuste de pool, directorio o aplicación vuelva a imponer un límite finito». - «En las aplicaciones que no requieren subidas de archivos, establezca
post_max_size = 8M. Si las subidas de archivos son necesarias, establezcapost_max_size = 32M. Mantengaupload_max_filesizepor debajo depost_max_size». - Use un límite de memoria del contenedor o del cgroup como frontera de disponibilidad, y no lo sustituya por
RLIMIT_ASniRLIMIT_DATA, «ya que pueden provocar el fallo de asignación vulnerable».
Para CVE-2026-109619:
- «Establezca
session.upload_progress.enabled=0y reinicie todos los workers. Usephp.ini, un pool de FPM o una configuración del servidor que se aplique antes del análisis de la petición. No confíe enini_set()ni en.user.inide FPM». - «En PHP 8.5, establezca
fatal_error_backtraces=0y reinicie todos los workers».
Compruebe con qué configuración se ejecuta realmente cada worker:
php-fpm -i | grep -E 'memory_limit|post_max_size|session.upload_progress.enabled'
La alerta de CISA va más allá: las organizaciones que no puedan actualizar de inmediato, o que sigan ejecutando PHP 8.1 o anterior, «deberían desconectar los sistemas basados en PHP hasta que puedan parchearse o actualizarse». También aconseja vigilar los procesos worker de PHP que lancen shells o descarguen herramientas.
Verificar la corrección
- Pregunte al PHP en ejecución, no a la imagen que pretendía desplegar. Ejecute
php-fpm -v(ophp -v) dentro de cada contenedor en ejecución y en cada host, y confirme 8.5.12, 8.4.27, 8.3.36, 8.2.35 o posterior. - No se fíe solo de la cadena de versión en los paquetes de las distribuciones. Debian, Ubuntu, RHEL y otras distribuciones aplican la corrección como backport a la versión que ya distribuyen, así que un PHP parcheado puede seguir indicando 8.3.6: la corrección de Ubuntu 24.04 es
8.3.6-0ubuntu0.24.04.13. Compare la versión completa del paquete con el tracker de seguridad de su distribución, o busque el CVE en el changelog del paquete, que normalmente lo menciona. La trampa también funciona al revés: un escáner que solo compara números de versión upstream puede marcar como vulnerable un paquete con backport. - Compruebe que todas las cargas de trabajo ejecutan la imagen reconstruida. Una etiqueta que ahora apunta a una imagen corregida no cambia un pod que descargó la antigua. Compare el digest de imagen que ejecuta cada contenedor con el digest que construyó:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .status.containerStatuses[*]}{.image}{"\t"}{.imageID}{"\n"}{end}{end}'
- Compruebe que todos los workers se han reiniciado. PHP-FPM y Apache mantienen cargado el código antiguo hasta que se reinician; la comprobación de procesos de «Comprobar si ha habido un compromiso» muestra los que aún lo ejecutan.
- Si todavía depende de los ajustes provisionales, compruebe cada pool con el comando
php-fpm -ianterior y manténgalos hasta que la actualización se haya completado en todas partes. - Vuelva a hacer el inventario de la sección de comprobación en su registry, sus imágenes de CI y las versiones que ejecutan sus clientes, no solo en producción.
Comprobar si ha habido un compromiso
PHP2Shell se está explotando en entornos reales, y Amazon vio el primer intento el 17 de octubre de 2026, cuatro días antes de la corrección. Si un PHP expuesto a internet ejecutó una versión afectada sin los ajustes provisionales en cualquier momento desde entonces, compruébelo.
Magnitud de la exposición. Los recuentos de banners de Shodan que Mallory publicó el 20 de octubre, recogidos por CybelAngel, encontraron 2,24 millones de hosts expuestos a internet que anunciaban PHP; de los aproximadamente 1,5 millones que muestran una versión, 883.717 (59 %) ejecutan una rama sin corrección oficial. Son recuentos de hosts, no de sistemas vulnerables confirmados: los paquetes con backport pueden parecer antiguos y estar parcheados, y unos 740.000 hosts ocultan su versión.
Appliances y productos que incluyen PHP. PHP también se ejecuta dentro de appliances, dispositivos de red, interfaces de gestión y productos de proveedores en los que quizá no pueda actualizarlo usted mismo. El inventario de NCSC-NL registraba 968 productos de este tipo el 9 de noviembre de 2026: 205 corregidos, 215 vulnerables, 93 en investigación, 240 dependientes del runtime y 214 no afectados. Compruebe esos productos por separado y aplique las actualizaciones del proveedor en cuanto estén disponibles.
Asegúrese de que la corrección se ejecuta de verdad. En hosts y VM, un proceso de PHP-FPM, php-cgi o Apache que se inició antes de la actualización sigue ejecutando el código antiguo. Su mapa de memoria muestra entonces el binario sustituido o libphp como eliminado. Compare también la hora de inicio de los procesos con la hora de la actualización:
for pid in $(pgrep -f 'php-fpm|php-cgi|apache2|httpd|frankenphp'); do
grep -qE '(php|libphp)[^/]*\(deleted\)' "/proc/$pid/maps" 2>/dev/null \
&& echo "PID $pid still runs a replaced PHP"
done
ps -o pid,lstart,args -p "$(pgrep -d, -f 'php-fpm|php-cgi|apache2|httpd|frankenphp')"
Indicadores de fuentes primarias:
- Peticiones: peticiones POST de subida de formularios que contienen la cadena
PHP_SESSION_UPLOAD_PROGRESS, que Amazon Threat Intelligence vio en intentos de explotación. Amazon también enumera direcciones de origen (103.216.220.92,31.223.184.166,37.19.200.5,134.209.159.64,103.114.163.188,95.217.98.37), pero señala que pertenecen a infraestructura de anonimización compartida: investigue una coincidencia, no la trate como prueba. - Procesos y archivos: procesos worker de PHP que lanzan shells o descargan herramientas (CISA, que añadió una regla de detección Sigma el 23 de octubre), y ejecución de procesos o cambios en archivos inesperados en servidores web (Amazon).
- Logs: en los logs de Apache, PHP-FPM, proxies inversos y servicios, advertencias o errores del núcleo repetidos antes de que se ejecuten los scripts, errores fatales y de análisis, y
Maximum execution time exceeded. El aviso de PHP añade que «la ausencia de un error en los logs no es prueba de seguridad».
Cuándo dar por hecho el compromiso. Si encuentra cualquiera de estos indicadores, o si un servidor expuesto ejecutó un PHP afectado sin mitigaciones y sus logs no permiten descartar la explotación, trátelo como comprometido. PHP describe el impacto como ejecución remota de código con la cuenta del worker web, y esa cuenta normalmente puede leer la configuración y los secretos de la aplicación.
Rote lo que el worker podía leer. Contraseñas de bases de datos, claves de API y tokens en variables de entorno y archivos de configuración, claves que firman sesiones o cookies (y las sesiones firmadas con ellas), y cualquier credencial de la nube disponible en el host. Rótelos después de reconstruir el host, para que los nuevos secretos nunca estén en una máquina comprometida.
Reconstruya en lugar de limpiar. Sustituya un host o contenedor comprometido a partir de una imagen fiable conocida, y no traslade archivos en los que el worker podía escribir, como directorios de subida, cachés o código generado. No reutilice imágenes, cachés de build ni artefactos producidos en un host comprometido.
Qué decir a sus clientes
Si entrega software que se ejecuta con PHP, sus clientes le preguntarán. Responda con versiones y acciones, incluso antes de tener todas las respuestas. Una respuesta que puede adaptar:
PHP2Shell (CVE-2026-109618, CVE-2026-109619) afecta a las versiones de PHP anteriores a 8.5.12, 8.4.27, 8.3.36 y 8.2.35, y a todas las ramas de PHP más antiguas. Las versiones [x a y] de [Producto] incluyen PHP [versión] y están afectadas; la versión [z], publicada el [fecha], incluye PHP [versión corregida]. Actualice a [z]. Si no puede actualizar de inmediato, aplique los ajustes de PHP de nuestro aviso [enlace] y limite el acceso de red a la aplicación. Las versiones [a a b] de [Producto] no están afectadas. Actualizaremos este aviso antes del [fecha].
Si todavía lo está comprobando, dígalo, e indique cuándo responderá. Para una primera declaración y plantillas para cada resultado, consulte cómo responder a los clientes tras un ataque a la cadena de suministro.
Cómo ayuda CRACI
CRACI ejecuta sus jobs de GitHub Actions y registra lo que cada job incorpora durante el build, incluidas imágenes de contenedor, paquetes apt y apk y paquetes de Composer, y conserva todos los builds anteriores con su SBOM. Cuando se publica un CVE, la reevaluación continua señala los builds anteriores que contenían el paquete afectado, de modo que ve qué versiones estuvieron expuestas y durante cuánto tiempo, no solo lo que encuentra el análisis de hoy. Las policy gates pueden bloquear los builds que contengan un CVE concreto.
Un límite en este incidente: el PHP compilado en una imagen oficial php: llega dentro de la imagen, no como descarga de un paquete. CRACI registra la referencia de imagen que descargó cada build, así que busque en sus builds las etiquetas php: además de los paquetes de PHP.
Encuentre todos los builds que entregaron un PHP vulnerable
Más sobre los registros de build: SBOM en tiempo de build, SBOM de imágenes Docker, lo que se le escapa al análisis de contenedores, el catálogo KEV de CISA y tendencias de publicación de CVE. Otros incidentes: todas las vulnerabilidades.
Para la seguridad de PHP más allá de este incidente, consulte nuestra guía de seguridad de PHP.
Fuentes y actualizaciones
Fuentes primarias:
- PHP: aviso de seguridad del 21 de octubre de 2026, aviso informativo del 23 de octubre de 2026, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp, versiones con soporte
- Registros CVE: CVE-2026-109618, CVE-2026-109619
- CISA: alerta del 21 de octubre de 2026, catálogo KEV
- NCSC-NL: repositorio php2shell
- NVD: CVE-2026-109618, CVE-2026-109619
- FIRST: puntuaciones EPSS
Investigación y análisis:
- Calif: PHP2Shell, a tale of two PHP remote vulnerabilities
- Amazon Threat Intelligence
- watchTowr
- Akamai
- CybelAngel
- Searchlight Cyber php2shell-scanner
Actualizaciones:
- 2026-11-11: Se han añadido al recuadro las puntuaciones de NVD, EPSS, las clases CWE, los créditos, las últimas versiones seguras y las fechas de fin de vida útil, además de PHP 8.6.0 RC4 y secciones sobre cómo funcionan los fallos, cómo verificar la corrección y cómo comprobar si ha habido un compromiso.
- 2026-11-11: Primera publicación.