Una filtración adelantó la publicación del parche 24 horas y, aun así, los exploits llegaron antes que muchas actualizaciones. CVE-2026-109618 y CVE-2026-109619, bautizadas como php2shell, son dos fallos de gestión de memoria en el propio runtime de PHP, con un CVSS de 9.2, que afectan a todas las versiones desde la 5.4 hasta la 8.5.11 y permiten ejecutar código en el servidor sin autenticación. Wiz Research lo confirmó contra instalaciones de Drupal y de WordPress.
Qué está roto y por qué no basta con actualizar el CMS
Los dos fallos aparecen cuando PHP aborta una petición a medias y después limpia mal lo que dejó:
| CVE | Qué falla |
|---|---|
| CVE-2026-109618 | Un error de falta de memoria interrumpe la petición cuando parte de los datos internos aún no está inicializada; la limpieza los trata como válidos. |
| CVE-2026-109619 | Tras un error fatal, PHP conserva referencias a memoria que ya se ha liberado; la siguiente petición que atiende el mismo worker puede usarlas y exponer datos de otra petición. |
Un atacante solo necesita enviar peticiones HTTP preparadas, y las peticiones grandes son una forma de forzar la presión de memoria. A partir de ahí puede tumbar el proceso, leer memoria ajena o ejecutar su propio código. El detalle importante para operar es que el fallo está en el intérprete: actualizar WordPress, Magento o un plugin no arregla nada. Hay que cambiar el binario de PHP, y si lo gestiona tu proveedor de hosting, pedirle que lo haga.
Qué versiones arreglan php2shell
| Rama | Versión con el parche |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
| 8.1 y anteriores | Sin parche (fin de vida): hay que subir a 8.2 o superior |
La última fila es la que va a doler. Quien siga en PHP 7.4 u 8.1 no tiene un parche que aplicar, sino una migración de rama con un exploit público en circulación.
Un embargo de dos meses que se rompió en un día
La cronología explica la prisa. Wiz Research encontró el primer fallo el 19 de agosto de 2026 con su herramienta Wiz Atlas y los modelos Gemini 4 Argon y GPT-5.6 Sol, confirmó la ejecución remota contra Drupal y WordPress en los dos días siguientes y lo comunicó al equipo de seguridad de PHP el 24 de agosto. El parche estaba previsto para el 22 de octubre a las 14:00 UTC.
El 20 de octubre, hacia las 15:00 UTC, los identificadores de los CVE empezaron a circular en foros y redes, con una hora de publicación equivocada y un CVSS de 10.0 que no era el real. PHP adelantó el preaviso a las 19:30 UTC y el lanzamiento al 21 de octubre a las 14:00 UTC. Hacia las 20:00 UTC, Calif, una de las firmas que habían reportado los fallos, publicó por error un vídeo con su prueba de concepto funcionando contra varios objetivos. Lo borraron, pero las copias aceleraron el desarrollo de exploits públicos.
Me quedo con dos ideas. La primera: los modelos ya no solo ayudan a escribir el parche, también encuentran el fallo y desarrollan el exploit, así que el número de vulnerabilidades serias por año va a subir. La segunda: con tantas partes en el embargo (Calif, Wiz, OpenAI, Quarkslab, proveedores de WAF y nubes), el margen real entre el aviso y el ataque se mide en horas.
Cómo comprobar qué versión estás ejecutando
Comprueba la versión dentro de lo que corre en producción, no en el Dockerfile. Este comando falla (código de salida distinto de cero) si la versión no está parcheada, así que sirve también como paso de CI:
php -r '
$fixed = ["8.5" => "8.5.12", "8.4" => "8.4.27",
"8.3" => "8.3.36", "8.2" => "8.2.35"];
$branch = PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;
if (!isset($fixed[$branch])) {
echo PHP_VERSION, ": rama sin parche, sube a 8.2+\n"; exit(2);
}
$ok = version_compare(PHP_VERSION, $fixed[$branch], ">=");
echo PHP_VERSION, $ok ? ": parcheada\n" : ": VULNERABLE\n";
exit($ok ? 0 : 1);'En contenedores, reconstruye forzando la descarga de la imagen base y comprueba el resultado antes de desplegar:
docker build --pull --no-cache -t mi-app:php-parcheado .
docker run --rm --entrypoint php mi-app:php-parcheado -vY para saber qué pods de Kubernetes usan imágenes de PHP reconocibles por el nombre:
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}' | grep -i phpUna imagen llamada api con PHP dentro no saldrá en ese listado; para eso están los escáneres de imágenes. En Google Cloud, Artifact Analysis ya avisa de estos CVE en artefactos nuevos y existentes.
Qué hace cada plataforma por ti
En Google Cloud, App Engine standard con PHP 8.2 o superior se actualiza solo. Cloud Run y Cloud Run functions también, pero únicamente si tienen activadas las actualizaciones automáticas de la imagen base; si no, o si despliegas tu propia imagen, hay que reconstruir y volver a desplegar. App Engine flexible, GKE y las soluciones de Marketplace con PHP, como un LAMP o un CMS, requieren redesplegar tú.
El WAF compra tiempo, no arregla nada
Cloudflare activó reglas contra php2shell el 21 de octubre a las 03:02 UTC, unas nueve horas antes de la divulgación, y vienen activas por defecto en todos los planes con WAF, incluido el gratuito. Ya ha visto tráfico de ataque y payloads mutados para saltarse las reglas. Para estas detecciones estrenó la "detección de transacción completa", que mira la petición y la respuesta del origen juntas y puede bloquear la respuesta si delata un exploit que ha funcionado.
Cloud Armor, en cambio, solo protege de forma automática a quien ya tenga activas las reglas gestionadas. Si no es tu caso, Google pide como mínimo las categorías File Upload y RFI, probarlas antes en modo preview y añadir una regla que rechace los cuerpos de petición que superen el límite de inspección, porque el ataque puede usar payloads grandes precisamente para forzar la falta de memoria.
Los dos proveedores dicen lo mismo: el WAF es una capa más mientras actualizas, no la solución.
Checklist para cerrar el incidente
- Inventario completo: servidores, imágenes base de CI, contenedores, funciones y cualquier LAMP o CMS de Marketplace.
- Versión comprobada en ejecución con el comando de arriba, también en preproducción.
- Workers de PHP-FPM y servidores web reiniciados tras actualizar el paquete: el binario viejo sigue en memoria hasta entonces.
- Plan con fecha para todo lo que esté en 8.1 o anterior.
- Revisión de los eventos del WAF desde el 20 de octubre. En Cloudflare, en Security > Security Analytics > Events, filtrando por los IDs de regla que publica el aviso.
- Si un servidor expuesto siguió sin parchear y hay coincidencias en esos registros, trátalo como comprometido: rota sus secretos y reconstruye la máquina en lugar de limpiarla.