Nuevos usuariosPlanes gratuitos de DNS y CDN para cada cuenta nueva.Crear una cuenta

PHP2Shell (CVE-2026-109618/109619): cómo lo mitigamos con un parche virtual en el perímetro

Dos avisos críticos de PHP permiten la ejecución remota de código sin autenticación mediante una salida abrupta por falta de memoria y estado global obsoleto. Le explicamos cómo funcionan los fallos, qué bloquea Yeap WAF en el perímetro desde el primer día y qué debe corregir todavía en su origen.

El 21 de octubre de 2026, el proyecto PHP publicó a la vez dos avisos de seguridad de nivel Critical: GHSA-w8hw-w9fx-j79w (CVE-2026-109618) y GHSA-6wmf-4rv5-p3rp (CVE-2026-109619), ambos con una puntuación de 9.2 en CVSS v4. Cada uno permite la ejecución remota de código sin autenticación. El par se conoce ya como PHP2Shell.

Las cuatro ramas con mantenimiento (PHP 8.2, 8.3, 8.4 y 8.5) están afectadas, y el equipo de PHP confirmó que mod_php es explotable con la configuración predeterminada. Para cualquier sitio que ejecute WordPress, Laravel o cualquier otra aplicación PHP, una sola solicitud POST anónima podría bastar para tomar el control del servidor.

El mismo día en que se publicaron los avisos, desplegamos un parche virtual contra la vía de ataque pública en todos los nodos perimetrales de Yeap CDN. En este artículo explicamos cómo funcionan los fallos, qué bloquean nuestras reglas, qué no pueden bloquear y qué debe hacer usted todavía en su servidor de origen.

Cadenas de ataque de PHP2Shell: una salida abrupta por falta de memoria que deja memoria a medio inicializar como si fuera fiable, y estado global obsoleto reutilizado entre solicitudes como un use-after-free
Ambos fallos residen en el ciclo de vida de las solicitudes del motor Zend, no en una extensión concreta.

En qué consisten las vulnerabilidades

CVE-2026-109618: corrupción de memoria por una salida abrupta tras OOM

Cuando PHP se queda sin memoria, llama a longjmp() para abortar la solicitud en curso. En algunos puntos, la memoria de la solicitud ya es accesible antes de estar totalmente inicializada. Si una asignación falla justo en ese momento, la salida anticipada deja memoria no válida, que el cierre de la solicitud lee más tarde y usa para tomar decisiones de ejecución.

Un atacante puede provocar el OOM de forma fiable dentro de los límites normales de PHP mediante una solicitud multipart/form-data malformada: sin una longitud de contenido utilizable, con una parte que contiene un número enorme de cabeceras, con controles de archivo vacíos que eluden max_file_uploads o con nombres de campo profundamente anidados. La corrección oficial elimina por completo longjmp() para los casos de OOM. Ahora PHP termina de forma ordenada en el siguiente punto seguro, y llama a _exit() de inmediato si el uso de memoria supera un umbral más alto.

CVE-2026-109619: estado global obsoleto entre solicitudes

El estado global que pertenece a una solicitud (estado de errores, de sesión, de objetos y de extensiones) puede sobrevivir en el proceso worker después de que se haya liberado la memoria de esa solicitud. Cierto código lee este estado antes de que la siguiente solicitud se inicialice correctamente y, por tanto, sigue un puntero hacia memoria liberada: un use-after-free.

  • Productores (solicitudes que dejan estado obsoleto): errores fatales, tiempos de ejecución agotados, un require fallido, falta de memoria y fatal_error_backtraces en PHP 8.5.
  • Consumidores (solicitudes que lo leen): diagnósticos INI aplicados antes del inicio de la solicitud y el procesamiento de session.upload_progress, que está activado de forma predeterminada.

Cuando un productor y un consumidor caen en el mismo worker, un atacante puede moldear el heap para convertir el use-after-free en ejecución de código. El equipo de PHP validó la vía de upload progress tanto en mod_php como en PHP-FPM.

Versiones afectadas

RamaAfectadasCorregido en
PHP 8.5< 8.5.128.5.12
PHP 8.4< 8.4.278.4.27
PHP 8.3< 8.3.368.3.36
PHP 8.2< 8.2.358.2.35

Está confirmado que mod_php es explotable. Según el análisis del código fuente, FPM, FrankenPHP y LSAPI también son vulnerables. Las versiones sin soporte no recibirán un parche oficial, lo que hace que la protección delante de ellas sea aún más importante.

Qué puede bloquear un WAF

El exploit conocido públicamente es, en esencia, una única solicitud POST multipart sin autenticar. Incluye un campo PHP_SESSION_UPLOAD_PROGRESS y una subida de archivo para llegar al manejador de upload progress, además de un gran número de campos de formulario que rocían el heap y recuperan la memoria liberada. Esa forma es visible en la capa HTTP, por lo que se puede detener antes de que la solicitud llegue a PHP.

Hemos añadido al motor OWASP CRS de Yeap WAF un conjunto de reglas autónomas de parche virtual. Reconocen la combinación del disparador de upload progress y el patrón de rociado del heap del que depende el exploit, y devuelven 403 antes de que PHP llegue a procesar la solicitud.

  • Bloquean por sí solas. No dependen de la puntuación de anomalías, así que el nivel de paranoia o el umbral de puntuación del sitio no las debilitan.
  • Analizan el comportamiento, no una firma fija. Renombrar campos o cambiar la forma de la carga no permite evadirlas.
  • No afectan a las subidas reales. Los formularios de subida legítimos, incluidos los que tienen barra de progreso, siguen funcionando.
  • Se ejecutan en el perímetro. No hay que instalar nada en su origen ni cambiar una sola línea de configuración.
Capas de protección perimetral de Yeap CDN: terminación TLS y origen oculto, parche virtual de PHP2Shell, reglas gestionadas de OWASP CRS, limitación de tasa y listas de bloqueo
Los intentos de explotación se detienen en el perímetro. El tráfico normal continúa hasta su origen.

Del aviso a la protección en cada nodo

Cronología: avisos publicados el 21 de octubre, reglas validadas y activas en todos los nodos perimetrales a las 23:34 del mismo día, incluidas en el paquete OWASP CRS v4.30.0 el 22 de octubre

Antes de publicarlas, validamos las reglas frente a las formas del tráfico de ataque y frente a varios tipos de subidas legítimas: todas las formas de ataque se bloquearon y todas las subidas legítimas pasaron. Después, las reglas se compilaron en nuestro paquete CRS como un plugin y se activaron en todos los nodos perimetrales a las 23:34 (UTC+8) del 21 de octubre. En la madrugada del 22 de octubre actualizamos todo el paquete a OWASP CRS v4.30.0, y el parche virtual se distribuyó con él.

Esa rapidez se debe al proceso de actualización de Yeap WAF. Cada nuevo paquete se compila y se comprueba en segundo plano y, a continuación, pasa a nodos canario, donde vigilamos el estado de carga y la tasa de bloqueo. Solo un paquete en buen estado se despliega en todas partes. Los nodos perimetrales cambian las reglas de forma atómica: las reglas antiguas siguen funcionando hasta que las nuevas están listas, de modo que nunca hay un hueco en la protección, y podemos volver a la última versión correcta con un solo clic.

Un WAF no es un parche: lo que usted aún debe hacer

Para que quede claro, un WAF solo puede detener la parte del ataque que viaja en el cuerpo de la solicitud HTTP. CVE-2026-109619 también tiene productores y consumidores que nunca pasan por multipart, como fatal_error_backtraces en PHP 8.5 o las advertencias INI durante el arranque, y la liberación y el uso pueden repartirse entre dos solicitudes que, por separado, parecen perfectamente normales. Eso solo puede corregirse dentro del motor de PHP. Además, las variantes basadas en tiempos, como los POST lentos, no son algo que un WAF de contenido pueda ver.

Considere las reglas perimetrales como una primera línea de defensa que le da tiempo, y complete esta lista lo antes posible:

  1. Actualice PHP a 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 o posterior. Según los avisos, esta es la única corrección completa.
  2. Refuerce php.ini antes de actualizar y, después, reinicie todos los workers de PHP:
    ; Desactívelo si no usa barras de progreso de subida
    ; (el aviso recomienda mantenerlo desactivado incluso después de aplicar el parche)
    session.upload_progress.enabled = 0
    
    ; PHP 8.5: elimina el productor de RCE confirmado
    fatal_error_backtraces = 0
    
    ; Límites conservadores de cuerpo y de entrada
    post_max_size = 8M
    max_input_vars = 1000
    max_input_nesting_level = 16
    
  3. En PHP-FPM, considere pm.max_requests = 1. Cada worker se recicla tras una solicitud, lo que rompe la reutilización entre solicitudes. Tiene un coste de rendimiento, así que úselo como medida de emergencia a corto plazo.
  4. Rechace multipart donde no necesite subidas. En la consola de Yeap CDN, vaya a Firewall → Reglas personalizadas y cree una regla de bloqueo con «el método es POST», «la cabecera de solicitud Content-Type contiene multipart/form-data» y sus rutas, permitiendo solo los endpoints que realmente aceptan subidas.
  5. Limite la tasa de solicitudes POST para frenar los escaneos y los sondeos repetidos.

Para comprobar su entorno:

php -v
php -i | grep -E "session.upload_progress.enabled|fatal_error_backtraces"

La CLI y el servidor web pueden cargar archivos php.ini distintos. La comprobación más fiable es una página temporal con phpinfo() en el propio sitio. Elimínela en cuanto la haya consultado.

Proteja sus sitios PHP con Yeap CDN y WAF

PHP2Shell no será el último fallo crítico de PHP. Siempre hay una ventana entre la publicación de un aviso y la aplicación del parche en todos los servidores, y los atacantes suelen empezar a escanear en cuestión de horas. Ponga su sitio detrás de Yeap CDN y nosotros cubriremos esa ventana por usted en el perímetro:

  • Reglas gestionadas siempre al día: el conjunto completo de reglas OWASP CRS v4 en 14 categorías, incluidas inyección SQL, XSS, ejecución remota de comandos, inyección PHP y webshells. Usted activa y desactiva categorías en lugar de ajustar reglas individuales, y las nuevas versiones publicadas por el proyecto se compilan, se prueban en nodos canario y se despliegan automáticamente.
  • Parches virtuales para fallos críticos: como en esta ocasión, se activan reglas específicas en el perímetro el mismo día del aviso, sin ningún cambio en su origen.
  • Un origen oculto: los atacantes solo llegan al perímetro. Permita en su origen únicamente el tráfico de la CDN y la superficie de ataque directo se reduce prácticamente a nada.
  • Reglas personalizadas y limitación de tasa: combine IP, país, ruta, cabecera y método para bloquear, desafiar o limitar el tráfico.
  • HTTPS gratuito y aceleración global: los certificados se emiten y renuevan automáticamente, y nodos perimetrales en varias regiones responden cerca de sus visitantes.

La incorporación lleva unos minutos: añada su dominio, apunte su registro DNS al CNAME que le proporciona Yeap CDN y active la protección en la configuración de WAF del dominio. Consulte Configure Yeap CDN y HTTPS gratuito para su sitio web en 10 minutos para ver una guía paso a paso, y Yeap CDN y Seguridad para conocer los detalles del producto.

Estamos habilitando el motor de reglas gestionadas de OWASP CRS dominio por dominio. Si desea este parche virtual de PHP2Shell en su sitio de inmediato, abra un ticket de soporte en la consola y lo activaremos para su dominio.

Referencias

Cree en Yeap Cloud

Planes gratuitos de DNS y CDN para cada cuenta nueva.

Registrarse gratis