Seguridad

PHP2Shell: los dos fallos de PHP que hay que parchear hoy

PHP ha publicado hoy 8.5.12, 8.4.27, 8.3.36 y 8.2.35 para cerrar dos fallos críticos que permiten ejecutar código en el servidor sin autenticación. Qué son, qué había de cierto en los avisos que corrieron por las redes, qué comprobar y a quién le toca actualizar.

Esta mañana circulaba por las redes un mensaje con todos los ingredientes del pánico: «¡Vulnerabilidad crítica histórica de PHP!», parche urgente a las 16:00, ejecución de código remoto «en cualquier servidor», afecta «de PHP 5 hasta la 8» y ya hay un exploit dando vueltas. Debajo, la captura del aviso que la PHP Foundation había publicado ayer, mucho más sobrio: versión de seguridad el miércoles 21 de octubre a las 14:00 UTC, dos vulnerabilidades críticas, las dos con un 9,2 en CVSS v4.

Las 14:00 UTC son las 16:00 en la España peninsular, así que la hora estaba bien. Y esta tarde ha salido lo prometido: PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35. El aviso oficial de php.net no se anda con rodeos: corrigen «dos vulnerabilidades críticas que pueden permitir la ejecución remota de código sin autenticación», y «todos los usuarios de PHP» deben actualizar «inmediatamente».

Ilustración de un módulo metálico con el logotipo de PHP, agrietado por una fisura incandescente y con una señal de peligro amarilla, montado sobre una placa en una sala de servidores en penumbra con luces moradas y ámbar. A la izquierda, el texto «PHP2Shell» y, debajo, «Actualiza PHP»

Ilustración generada con IA para este artículo; no representa ningún servidor ni sistema real.

Esto sí es de los que hay que atender hoy. Pero el mensaje que ha corrido por las redes mezcla cosas ciertas con cosas exageradas, y para decidir qué hacer conviene separarlas.

Qué ha pasado, en orden

Cuándo Qué
Agosto de 2026 Dos equipos, por separado, encuentran fallos de la misma familia y se los reportan al equipo de seguridad de PHP: Calif el 11 de agosto, con una prueba de concepto que PHP confirma el 15, y Wiz Research el 24.
20 de octubre Se filtra. Un mensaje en Hacker News, borrado después, adelanta que hay dos fallos «CVSS 10» con publicación prevista para el jueves 22. La firma watchTowr confirma a la prensa que son reales. Esa misma tarde, PHP publica el aviso con fecha y hora.
21 de octubre, por la mañana El CTO de Cloudflare dice en X que están viendo «los primeros ataques», según recoge BleepingComputer.
21 de octubre, por la tarde Salen las versiones corregidas, anunciadas para las 14:00 UTC, y los investigadores publican sus análisis. Calif publica además una herramienta de explotación.

El embargo existía para que el parche y la explicación salieran a la vez, y que quien administra un servidor tuviera la solución en la mano el mismo minuto en que los atacantes tenían el mapa. La filtración se lo saltó, y por eso PHP ya había avisado de que adelantaría la publicación «si los detalles se hacen públicos o hay indicios de explotación activa».

Qué es, sin jerga

Los dos fallos tienen nombre oficial, CVE-2026-109618 y CVE-2026-109619, y los dos tienen que ver con lo que hace PHP cuando una petición se interrumpe a medias.

El ejemplo más claro es la memoria. Cada script de PHP tiene un tope, el famoso memory_limit, y cuando una petición lo supera PHP no termina con orden: aborta de golpe lo que estaba haciendo y salta al final. Si ese salto le pilla preparando la petición, hay estructuras internas que se quedan a medio construir. Ese es el primer fallo.

El segundo va un paso más allá. PHP guarda cierto estado interno que debería vivir lo que dura una petición, y que en algunos casos sobrevive a ella y sigue apuntando a memoria que ya se ha liberado. No hace falta quedarse sin memoria para llegar ahí: el aviso habla también de otros errores fatales, de tiempos agotados e incluso de avisos de diagnóstico que no detienen nada. Y como el mismo proceso de PHP atiende después otras peticiones, esa basura puede acabar usándose como si fuera buena.

En resumen: PHP gestiona mal su memoria y su estado interno cuando una petición se corta a medias, y con la petición adecuada un atacante puede aprovechar ese desorden para ejecutar sus propias órdenes en el servidor.

Lo que lo hace grave es que no depende de tu código. El fallo está en el motor, no en lo que corre encima, y no hace falta usuario ni contraseña. En el caso más claro, el que está demostrado con Apache y mod_php, basta un formulario con archivos adjuntos de los de toda la vida (multipart/form-data) preparado para agotar la memoria, y el ataque se produce antes de que la aplicación ejecute una sola línea: no hace falta un plugin vulnerable ni que tu web tenga un formulario de subida. En otras configuraciones el camino es distinto y puede depender de lo que haga la aplicación, pero el aviso no deja fuera ninguna: incluye PHP-FPM, mod_php, php-cgi, FrankenPHP y LiteSpeed.

Hay un detalle histórico que tiene su gracia. Calif empieza su cronología en 2004, con un fallo muy parecido —ejecución remota a partir del límite de memoria— que encontró entonces Stefan Esser. Veintidós años después, la misma esquina del motor. Y esta vez quien la ha vuelto a mirar no ha ido solo: tanto Calif como Wiz cuentan que buena parte del trabajo de búsqueda y de construcción del exploit lo hicieron con modelos de IA. Los créditos del aviso de PHP incluyen además a investigadores de OpenAI.

Lo que decía el mensaje y lo que hay

El mensaje decía Lo que consta
«Vulnerabilidad crítica histórica» Crítica, sí: 9,2 sobre 10 en CVSS v4. El «10» que circulaba ayer venía de la filtración; la puntuación oficial es 9,2. Lo de «histórica» es una valoración, pero tiene base: según Wiz, todas las versiones de PHP de la última década tienen al menos uno de los dos fallos.
«Afecta a versiones de PHP 5 hasta la 8» Los investigadores sitúan el camino vulnerable más antiguo en PHP 5.4.0, de 2012. El aviso oficial solo enumera las ramas que el proyecto mantiene (todo lo anterior a 8.2.35, 8.3.36, 8.4.27 y 8.5.12). Que una versión antigua no salga en esa lista no significa que esté a salvo: significa que el proyecto PHP no le saca versión nueva.
«Se podría ejecutar código remoto en cualquier servidor» Con matices. La ejecución remota completa está demostrada contra Apache con mod_php y configuración por defecto. En PHP-FPM —lo habitual con nginx y en la mayoría de paneles de hosting— uno de los dos fallos está validado y el otro el propio aviso lo da por explotable aunque no haya demostración completa. Para decidir si actualizas hoy, la diferencia no importa: actualiza.
«Ya está circulando un posible exploit» Ayer era un rumor sin verificar. Hoy, tras la publicación, la herramienta de Calif es pública y Cloudflare dice estar viendo ataques. Toca asumir que se va a explotar en masa.
«Si tienes WordPress o similares, actualiza» Correcto, con una aclaración importante: actualizar WordPress no corrige estas vulnerabilidades. El fallo no está en WordPress, ni en el tema, ni en los plugins, sino en el PHP que los ejecuta. Calif y Wiz confirman explotación sin autenticación contra WordPress y Drupal.

Así que el mensaje exageraba en la forma y acertaba en lo que importa: hay que actualizar, y hoy.

Qué tienes que comprobar

Primero, qué PHP sirve tu web. En WordPress está en Herramientas → Salud del sitio → Información → Servidor. En un panel tipo Plesk o cPanel, en la configuración de PHP de cada dominio. En un servidor propio, php -v en la consola. Ojo: el PHP de la consola y el que sirve la web pueden no ser el mismo, sobre todo en servidores con varias versiones instaladas; si dudas, mira el de la web con un phpinfo() temporal, y bórralo después.

Segundo, a quién le toca actualizarlo. Esta es la pregunta que más webs deja sin parchear, porque cada uno cree que es cosa del otro:

Si tu web está en… Quién actualiza y qué hacer
Un hosting compartido o gestionado Tu proveedor. Pregúntale hoy cuándo va a aplicar el parche, y si la respuesta es vaga, insiste.
Un servidor con Plesk o cPanel Quien administre el servidor. El panel trae sus propios paquetes de PHP: hay que buscar la actualización desde el panel y comprobar después la versión que muestra cada dominio.
Un servidor Linux con los paquetes de la distribución Quien administre el servidor, con el gestor de paquetes. El número que verás no es el de php.net: las distribuciones corrigen su propia versión en lugar de saltar a la nueva. En Ubuntu 24.04, por ejemplo, el arreglo va en el paquete 8.3.6-0ubuntu0.24.04.13. Mira el aviso de seguridad de tu distribución, no el número.
El repositorio de Remi (habitual en RHEL, Rocky o Alma) Quien administre el servidor. El aviso de PHP advierte de que hoy ese repositorio no tendría todavía las actualizaciones: comprueba si ya han llegado y, mientras no lo hagan, aplica la contención de más abajo.
Docker Quien mantenga la imagen. Hay que reconstruirla bajando la base de nuevo (docker build --pull) y comprobar que dentro del contenedor ya sale la versión corregida antes de desplegarla. Una imagen construida la semana pasada lleva el PHP de la semana pasada.

Y reiniciar PHP. Instalar el paquete no cambia nada mientras sigan vivos los procesos antiguos: hay que reiniciar PHP-FPM o Apache.

Si hoy no puedes actualizar

Hay medidas de contención, pero el aviso de PHP es tajante: «No hay mitigaciones completas; actualizar es la única opción segura». Lo que sigue es para ganar unas horas, no para quedarse así, y son cambios de configuración del servidor: si no administras tú el servidor, no son para ti, y lo que toca es la pregunta al proveedor de la tabla anterior.

  • session.upload_progress.enabled = 0, puesto en php.ini, en el pool de FPM o en la configuración del servidor, porque tiene que aplicarse antes de que PHP lea la petición. No vale hacerlo con ini_set() desde la aplicación, ni en un .user.ini.
  • memory_limit = -1, solo si controlas los límites que hay por fuera. Quitar el tope de PHP significa que una petición puede comerse toda la memoria, así que el aviso lo acompaña de un post_max_size bajo —8M si no subes archivos, 32M si sí—, de un límite de memoria en el contenedor o mediante cgroups —no con RLIMIT_AS ni RLIMIT_DATA, que según el aviso pueden provocar justo el fallo de asignación vulnerable—, y de fijarlo de forma que la aplicación no pueda cambiarlo (php_admin_value). Sin eso, cambias un problema por otro.
  • En PHP 8.5, además, fatal_error_backtraces = 0.
  • Si la web está detrás de Cloudflare, ya ha desplegado reglas en su cortafuegos, también en el plan gratuito. Eso reduce la exposición, y solo si el servidor no acepta tráfico que no venga de Cloudflare, pero no sustituye al parche.

Después de cambiar la configuración, otra vez: reiniciar PHP, y comprobar con phpinfo() que los valores nuevos son los que se están aplicando.

Si tu PHP es 8.1 o anterior

Aquí está la parte incómoda. PHP 8.1 y anteriores no reciben versiones nuevas del proyecto PHP. El proyecto ha publicado los arreglos adaptados a las ramas 7.4, 8.0 y 8.1 como código fuente, pero eso no es una actualización que se instale con un clic: es material para quien compila su propio PHP y para los proveedores que siguen manteniendo esas ramas. Algunos ya lo han aplicado; Ubuntu 22.04, por ejemplo, tiene corregido su PHP 8.1 en el paquete 8.1.2-1ubuntu2.28.

Así que la pregunta, si estás ahí, es si tu proveedor o tu distribución sigue manteniendo esa rama. Si la respuesta es sí, actualiza su paquete y listo por hoy. Si no lo sabes, confírmalo con tu proveedor. Y si nadie mantiene esa rama, tu web lleva tiempo sin parches de seguridad y hoy simplemente se ha notado: necesitas planificar la actualización. Subir de versión a veces arrastra cambios en la aplicación, en los plugins o en el tema. Mientras tanto, la contención de arriba y, si la web no puede esperar, sacarla de internet.

Ojo también a PHP 8.2: hoy ha recibido el parche, pero el proyecto deja de darle soporte el 31 de diciembre de 2026. Dentro de diez semanas estará en la misma situación que la 8.1.

Esto es justo de lo que hablaba en «No necesito mantenimiento web»: una web no se estropea un día concreto, se va quedando atrás, y un día como hoy esa deuda se cobra entera.

En casa

Lo primero que he hecho al leer el aviso ha sido mirar lo mío. Esta web está escrita en PHP, y el contenedor en el que la desarrollo llevaba PHP 8.3.35, construido el 25 de septiembre, con session.upload_progress.enabled activado, que es el valor por defecto. Vulnerable, por tanto, aunque ese contenedor no esté expuesto a internet.

Si necesitas una mano

Si al leer esto no tienes claro qué versión de PHP sirve tu web, a quién le toca actualizarla o si la actualización va a romper algo, puedo ayudarte. Llevo más de veinte años desarrollando y manteniendo webs en PHP, WordPress incluido, y un día como hoy suele haber dos trabajos distintos:

  • El del servidor. Comprobar qué versión sirve de verdad cada web, actualizar PHP —en el panel, en los paquetes de la distribución o en la imagen de Docker—, aplicar la contención si la actualización tiene que esperar y verificar después que todo sigue funcionando.
  • El del código. Cuando la web está en PHP 7 o en un 8.0 o 8.1 sin mantenimiento, actualizar el servidor no basta: la aplicación tiene que funcionar en una versión actual. Revisar si aparecen incompatibilidades al subir, adaptar el desarrollo propio, los plugins o el tema, y dejarlo funcionando en una versión de PHP con soporte y parches de seguridad.

Puedes necesitar uno, el otro o los dos. Escríbeme contándome dónde está alojada tu web y qué versión de PHP crees que tiene (si no lo sabes, también vale) y te digo qué hay que hacer, lo hagas tú, tu proveedor o yo.

Preguntas frecuentes

¿Qué versiones de PHP corrigen PHP2Shell?

PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, publicadas el 21 de octubre de 2026. Cualquier versión anterior de esas ramas es vulnerable. Si usas los paquetes de tu distribución Linux, el número será otro, porque las distribuciones aplican el arreglo sobre su propia versión: en Ubuntu 24.04, por ejemplo, va en el paquete 8.3.6-0ubuntu0.24.04.13.

¿Afecta a PHP 7 o a PHP 5?

Los investigadores sitúan el camino vulnerable más antiguo en PHP 5.4.0, de 2012. El proyecto PHP no publica versiones nuevas para 8.1 ni anteriores; ha dejado los arreglos para 7.4, 8.0 y 8.1 como código fuente, para quien compila y para los proveedores que siguen manteniendo esas ramas. Algunos ya los han aplicado: Ubuntu 22.04 tiene corregido su PHP 8.1 en el paquete 8.1.2-1ubuntu2.28. Si nadie mantiene tu rama, la solución es subir a una versión con soporte.

Tengo WordPress actualizado. ¿Estoy protegido?

No necesariamente. Actualizar WordPress no corrige estas vulnerabilidades: el fallo está en PHP, no en WordPress ni en sus plugins, y en el caso demostrado con Apache y mod_php se dispara antes de que se ejecute el código de la web. Lo que hay que actualizar es el PHP del servidor. La versión se ve en Herramientas, Salud del sitio, Información, Servidor.

¿Puedo protegerme sin actualizar?

Solo de forma parcial y temporal, y son cambios de configuración del servidor que debe hacer quien lo administra. El aviso de PHP propone varias medidas de contención, pero dice expresamente que no hay mitigaciones completas y que actualizar es la única opción segura. Si tu web está en un hosting gestionado, lo que toca es preguntar al proveedor cuándo aplica el parche.

¿Hay que reiniciar algo después de actualizar?

Sí. Los procesos de PHP-FPM o de Apache que ya estaban en marcha siguen usando el PHP antiguo hasta que se reinician. Después del reinicio, conviene comprobar la versión que sirve la web, no solo la de la consola.

Otras noticias

El blog, día a día

92 artículos publicados 22 abr 2026 — 21 abr 2027

¿Te ha resultado útil o quieres comentar algo?

Hablemos →