Actualización de seguridad de PHP 2026: guía de corrección de PHP2Shell (CVSS 9.2)
El 21 de octubre de 2026 PHP publicó las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35 para cerrar dos vulnerabilidades de ejecución remota de código explotables sin autenticación. Si su servidor, el servidor de un cliente o el hosting compartido de su agencia ejecuta PHP, esto es una tarea de actualización para hoy mismo, no un punto del mapa de ruta.
La divulgación en sí fue inusual. El 20 de octubre el equipo de seguridad de PHP publicó un aviso anticipado, programó la publicación para el 21 de octubre a las 14:00 UTC y se reservó el derecho de adelantarla. Los identificadores CVE se filtraron un día antes de la divulgación, acompañados de afirmaciones exageradas sobre la gravedad y las versiones afectadas. Los mantenedores de las distribuciones ya habían recibido los parches, y varios CERT nacionales empezaron a publicar recomendaciones antes incluso de que el código fuera público. Dicho de otro modo: una vez publicada la versión corregida, nadie tenía una excusa legítima para demorarse.
Dos vulnerabilidades, una versión de emergencia
Ninguno de los dos fallos es un error de lógica en una aplicación. Ambos residen en cómo PHP prepara y desmonta cada petición, y por eso ninguna actualización de framework, de plugin ni regla de WAF sustituye a la actualización del intérprete.
CVE-2026-109618 — RCE por corrupción en el manejo de la falta de memoria. Cuando PHP agota la memoria disponible, aborta la petición en lugar de continuar. El aviso describe una vía en la que esa interrupción corta a PHP mientras los datos internos de la petición están inicializados solo parcialmente, de modo que el paso de limpieza posterior trata como válidos los datos inválidos. Un atacante que consiga llevar el uso de memoria al límite puede influir en lo que ocurre a continuación. Esta es la vulnerabilidad que vuelve tan contraintuitivo el consejo de mitigación: el fabricante pide a los administradores que eviten que PHP alcance su propio techo de memoria, no que lo ajusten más abajo.
CVE-2026-109619 — RCE por estado global residual. El estado interno propiedad de una petición puede sobrevivir a la liberación de la memoria que lo respaldaba. La siguiente petición que atienda el mismo proceso worker puede consumir ese estado residual antes de que la inicialización normal lo restablezca. En un worker de larga vida — exactamente lo que son PHP-FPM, mod_php y LiteSpeed — la reutilización de memoria es una condición normal y permanente, y por eso no hablamos de un caso excepcional propio de configuraciones exóticas.
| Identificador | Qué es | Gravedad | Corregido en |
|---|---|---|---|
| CVE-2026-109618 GHSA-w8hw-w9fx-j79w |
El manejo de la falta de memoria interrumpe a PHP con los datos de la petición parcialmente inicializados; la limpieza posterior confía en datos inválidos | CVSS v4.0 9.2 | 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35 |
| CVE-2026-109619 GHSA-6wmf-4rv5-p3rp |
El estado de una petición sobrevive tras liberarse su memoria; una petición posterior en el mismo worker lo usa antes de la reinicialización | CVSS v4.0 9.2 | 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35 |
El nombre PHP2Shell no es una denominación oficial del proyecto PHP; surgió de investigadores y fabricantes de seguridad y se popularizó, así que lo verá en la salida de los escáneres, en boletines de proveedores de hosting y en avisos de CERT que se refieren exactamente a estos dos CVE.
Quién está realmente expuesto
El aviso es claro: todas las instalaciones de PHP que atienden peticiones web están en riesgo. Eso incluye PHP-FPM detrás de nginx o Apache, Apache con mod_php, php-cgi, LiteSpeed y FrankenPHP. La diferencia entre ellas está en cuánto trabajo tiene que hacer el atacante.
| Configuración | Riesgo | Motivo |
|---|---|---|
| Apache con mod_php | Máximo | El aviso describe un exploit demostrado en el que una petición sin autenticar desencadena el ataque antes de que se ejecute cualquier código de la aplicación |
| PHP-FPM (nginx, Apache como proxy) | Alto | Los workers de larga vida reutilizan el estado de las peticiones; el worker suele ejecutarse con el mismo usuario que el sitio |
| LiteSpeed, php-cgi, FrankenPHP | Alto | Mencionadas en el aviso como configuraciones dentro del alcance que atienden peticiones |
| Hosting gestionado y compartido | Varía — pregunte | Suelen estar parcheados en la capa de la plataforma, pero usted no puede verlo; su tarea es conseguir por escrito la versión integrada y la fecha del parche |
| Tareas cron y scripts de CLI | Más bajo, pero actualice igualmente | No exponen una superficie de peticiones pública, pero comparten el mismo binario y a menudo guardan credenciales |
Si aloja WordPress, WooCommerce, Laravel, Magento, ERPs del entorno de Magento o cualquier portal de reservas en PHP para su empresa comercial, entra en las tres primeras filas aunque el código de la aplicación sea impecable. Para una visión más amplia de quién debería gestionar el entorno de ejecución en primer lugar, consulte nuestra guía sobre externalización de TI en Turquía.
Compruebe su versión en dos minutos
La trampa aquí es la aritmética de versiones. Las distribuciones entregan PHP 8.3.6 o 8.2.x durante años e incorporan las correcciones de seguridad al mismo número de versión visible, de modo que php -v por sí solo no le dice si está protegido. Compare tres cosas.
1. La versión visible de PHP y la SAPI que atiende el tráfico.
php -i | grep -E 'PHP Version|memory_limit|session.upload_progress.enabled|fatal_error_backtraces'
systemctl list-units --type=service --state=running | grep -Ei 'php|apache|nginx|litespeed'
2. La versión del paquete de la distribución, no la versión upstream. En Debian y Ubuntu, el changelog es la respuesta honesta; en sistemas RPM, consulte el changelog del paquete.
zcat /usr/share/doc/php8.3-cli/changelog.Debian.gz | grep -iE 'CVE-2026-10961[89]'
apt-cache policy php8.3-fpm | head -4
# RPM-based hosts
rpm -q php && rpm -q --changelog php | grep -iE 'CVE-2026-10961[89]'
Si el changelog menciona ambos CVE en la versión instalada, está parcheado aunque php -v siga diciendo 8.3.6. Esa es la diferencia entre una respuesta de seguridad real y una superstición de números de versión.
3. Si el proceso en ejecución cargó el binario parcheado. Una actualización de paquete que no va seguida de un reinicio deja el código antiguo en memoria. Compare la hora de inicio del servicio con la hora de instalación del paquete:
stat -c '%y %n' /usr/sbin/php-fpm8.3
En cPanel, Plesk, DirectAdmin o una plataforma gestionada, el equivalente es el selector de PHP junto con el boletín de seguridad del propio proveedor: identifique la versión integrada que su sitio tiene realmente asignada, no la más novedosa que anuncie el panel. Si su proveedor de hosting no puede indicarle una fecha de parcheo, considere el sitio como no parcheado. Nuestros servicios de infraestructura digital cubren esta auditoría y la propia actualización; también puede simplemente contactar con nosotros con su stack y le diremos qué comprobaríamos.
Versiones corregidas y el abismo del fin de soporte
PHP mantiene cada rama dos años de desarrollo activo y dos años más de correcciones de seguridad. Esa política es la que produjo cuatro correcciones simultáneas el 21 de octubre — y también la que deja a las ramas antiguas a su suerte.
| Rama | Versión corregida | Estado tras este aviso |
|---|---|---|
| PHP 8.5 | 8.5.12 | Con soporte activo |
| PHP 8.4 | 8.4.27 | Con soporte activo |
| PHP 8.3 | 8.3.36 | Fase de soporte de seguridad |
| PHP 8.2 | 8.2.35 | El soporte de seguridad termina el 31 de diciembre de 2026 — planifique el salto ya |
| PHP 8.1 y anteriores | Sin versión upstream | Solo backports de los distribuidores; el proyecto PHP publicó backports mínimos de código fuente para 7.4, 8.0 y 8.1 para quienes compilan desde el código fuente |
Dos advertencias prácticas del aviso. Primera: si instala PHP desde un repositorio de la comunidad en lugar de desde su distribución, ese repositorio puede quedar rezagado respecto a la ventana de seguridad: los mantenedores de los paquetes Remi, de uso muy extendido, declararon que no tendrían actualizaciones el mismo día, así que la vía segura son los paquetes de su distribución o una compilación desde el código fuente. Segunda: si está en PHP 8.1 o anterior, «esperar a que nuestro proveedor de hosting actúe» es una decisión de seguridad que usted toma en nombre de sus clientes — documéntela o cámbiela.
Parchee un servidor en producción sin provocar un incidente
Las actualizaciones de seguridad dentro de la misma rama menor rara vez rompen una aplicación; los reinicios sin probar, sí. El orden siguiente es el que usamos en plataformas comerciales en producción, y mantiene corta la ventana de riesgo sin jugarse el sitio.
- Primero, una instantánea. Una instantánea de hipervisor o de volumen cuya restauración haya probado realmente se recupera en minutos, y hace que la decisión de parchear resulte barata.
- Reproduzca la versión en staging. Misma rama, mismas extensiones, mismos archivos de configuración de PHP y una copia de los datos de producción. Pruebe los flujos de compra, solicitud de cotización y pago, no solo la página de inicio.
- Actualice el conjunto de paquetes como una unidad. Mezclar un CLI actualizado con un binario de FPM antiguo es la manera de acabar con un
php -vparcheado y una ruta web sin parchear:apt-get update && apt-get install --only-upgrade 'php8.3-*', odnf update --security 'php*'en servidores RPM. - Reinicie el proceso que atiende las peticiones y compruebe que se reinició.
systemctl restart php8.3-fpm(o recargue Apache / reinicie LiteSpeed), y después verifique de nuevo la hora de inicio del servicio y repita las consultas de versión y changelog. - Vigile el registro de errores durante una hora. Los mensajes de OOM, las firmas nuevas de errores fatales y las tasas inusuales de 5xx son señales de que los ajustes de mitigación descritos más abajo pueden necesitar un ajuste fino — no razones para posponer la actualización.
- Registre la evidencia. Versión del paquete, línea del changelog que menciona ambos CVE y hora del reinicio. Los clientes, los auditores y las revisiones de controles tipo ISO 27001 piden exactamente esto, y guardarlo lleva diez segundos.
Cuando la actualización tenga que esperar — una integración de ERP validada, un calendario de publicaciones embargado, un circuito de aprobación del cliente — ponga ese mismo día un control compensatorio delante, en lugar de dejar el puerto abierto a la espera. Eso es lo que recomendaron los avisos de los CERT nacionales exactamente para esta situación: aislar de la red pública las aplicaciones PHP expuestas a internet cuando no es posible parchear de inmediato.
Mitigaciones temporales: estreche la ventana, no la cierre
El aviso de PHP afirma sin rodeos que no existe una mitigación completa y que actualizar es la única opción segura. Trate lo siguiente como una cobertura de días, no de semanas, aplicada en un nivel que la aplicación no pueda anular y con todos los workers reiniciados después.
Contra CVE-2026-109618 (la vía de la falta de memoria)
- Deje que PHP agote la memoria de la máquina en lugar de su propio límite:
memory_limit = -1, idealmente comophp_admin_value memory_limit = -1para que el código de la aplicación no pueda restablecer el techo. - Mantenga pequeños los cuerpos de petición en el intérprete: la orientación del aviso es de unos 8 MB cuando no hay subidas de archivos y de unos 32 MB cuando las hay, con
upload_max_filesizepor debajo depost_max_size. - Aplique los límites costosos en el proxy, porque el daño está en la petición decodificada, no en el tamaño transmitido: tamaño total del cuerpo decodificado, número de campos de entrada, número de partes multipart, número de cabeceras, profundidad de anidamiento — y cubra también las peticiones que llegan sin un
Content-Lengthutilizable. - Contenga el radio de impacto con un límite de memoria de contenedor o cgroup dimensionado para que un worker terminado sea un evento de disponibilidad, no del servidor completo. No lo sustituya por
RLIMIT_ASniRLIMIT_DATA: esos disparan precisamente el fallo de asignación que está en la vía vulnerable.
Contra CVE-2026-109619 (la vía del estado residual)
- Desactive el progreso de subida de sesiones con
session.upload_progress.enabled = 0, definido en php.ini, en el pool de FPM o en la configuración del servidor — en algún lugar que se aplique antes del análisis de la petición. Después reinicie todos los workers, porque FPM comparte entre peticiones el estado de los módulos ya inicializado.ini_set()y.user.inillegan demasiado tarde para servir de algo. - En PHP 8.5, defina
fatal_error_backtraces = 0y reinicie. - Elimine los ajustes por petición que sean inválidos o estén obsoletos y que por ello emiten diagnósticos durante la inicialización temprana. Suprimir el mensaje con
error_reporting,display_errorso@no elimina la ruta de código. - Busque errores fatales accesibles para el atacante y tiempos de espera de larga duración en los gestores de subida e importación, el código de callbacks y las rutinas de limpieza — los mismos lugares donde viven ambos fallos.
Un CDN o un WAF delante del origen sigue justificando su coste: la limitación de tasa, el bloqueo de formas de petición anómalas y el parcheo virtual reducen el ruido y frenan el escaneo oportunista. Son un reductor de velocidad para un atacante dirigido, no un control que pueda dar por cerrado como remediación.
Qué preguntar hoy a su proveedor de hosting
Los guiones del soporte responden a esta pregunta con «siempre estamos parcheados». Pida, en cambio, evidencia que pueda archivar:
- La versión de PHP integrada asignada a nuestra cuenta, y si se trata de un paquete de la distribución o de una compilación del proveedor.
- La fecha en la que las correcciones de CVE-2026-109618 y CVE-2026-109619 llegaron a su parque de servidores, junto con la cadena de versión del paquete interno.
- Si la corrección se aplica a la SAPI que atiende nuestro sitio (FPM, LiteSpeed, mod_php) y a cualquier nodo de staging o de copia de seguridad que pudiéramos restaurar.
- Si la plataforma aún no está parcheada: qué control compensatorio hay implantado y hasta cuándo.
- Su política habitual para las ramas al final de su vida útil — qué le ocurre a mi sitio el 1 de enero de 2027, cuando termina el soporte de seguridad de PHP 8.2.
Un proveedor que responde a esas cinco preguntas en un solo correo es un proveedor que merece la pena conservar. Uno que contesta con texto de marketing abre una conversación de migración; se aplica la misma diligencia que en nuestro trabajo de evaluación de brechas de ISO 27001, donde lo que se entrega es evidencia, no tranquilidad.
¿Debe asumir que ha sido comprometido?
No automáticamente — pero compruébelo en lugar de suponerlo, sobre todo si el servidor estuvo expuesto a internet durante la ventana anterior a su parche.
- Busque procesos, puertos en escucha y entradas de cron que usted no haya creado, además de conexiones salientes desde el usuario del worker de PHP.
- Compare los directorios modificables de la aplicación contra una fuente de verdad del despliegue: archivos PHP nuevos, directorios de subidas modificados, carpetas temporales ejecutables sin explicación.
- Busque en los registros web ráfagas de peticiones en torno a las horas de la divulgación, cuerpos multipart inusualmente grandes o peticiones que devolvieron 500 con firmas de OOM en el registro de errores de PHP.
- Compruebe que el binario parcheado se está ejecutando de verdad — la comparación de horas de reinicio anterior lo responde.
- Si algo parece estar mal, trátelo como un incidente: preserve el disco y los registros, rote todas las credenciales que la aplicación pueda leer y reconstruya el servidor desde una imagen conocida como buena. Reinstalar el paquete de PHP sobre un servidor comprometido no es una remediación.
Un ejemplo práctico de nuestra propia infraestructura
Operamos worldwidetradex.com sobre Ubuntu 24.04 LTS con nginx y PHP-FPM, así que el 22 de octubre nos aplicamos a nosotros mismos las comprobaciones anteriores. Los resultados ilustran bien por qué importa la aritmética de versiones:
php -v informó de PHP 8.3.6 — un número que, comparado con el PHP upstream, parece tener tres años de antigüedad y resulta alarmante.
dpkg -l informó de 8.3.6-0ubuntu0.24.04.13, y el changelog de Debian incluido en el paquete para esa versión exacta enumera CVE-2026-109618 y CVE-2026-109619 con el parche del distribuidor aplicado. apt-cache policy mostró la versión instalada igual a la candidata, así que no quedaba nada más reciente pendiente.
Conclusión: parcheado a través del backport de la distribución, atendido por PHP-FPM en lugar de mod_php y con el servicio de FPM reiniciado después de la actualización del paquete. El mismo ejercicio, cinco comandos, y podemos mostrar la evidencia a cualquier cliente que la pida.
La lección sirve para cualquier stack: su postura de seguridad es la versión del paquete, más el changelog, más el reinicio; no la cadena de versión de marketing del panel de hosting.
Convierta el parcheo en rutina, no en heroísmo
PHP2Shell no es memorable por exótico; es memorable porque el intérprete sobre el que funciona la mayor parte de la web tenía un fallo crítico, explotable antes de la autenticación, y miles de servidores tuvieron que reaccionar en cuestión de horas. Los equipos que durmieron tranquilos no tuvieron suerte — tenían automatización.
- Actualizaciones de seguridad desatendidas para el intérprete, con la versión y el reinicio registrados automáticamente.
- Un inventario que sepa qué SAPI y qué rama de PHP usa cada sitio, incluidos el staging, las copias de seguridad y aquel WordPress de 2019.
- Una ruta de restauración ensayada, para que «parchear ya» nunca se ponga en la balanza contra «no podemos revertir».
- Un plan de ramas: nada en una versión de PHP cuyo soporte de seguridad termine dentro de los próximos doce meses.
- Un responsable con nombre por servidor y una ruta de escalado por escrito para los días en que un parche llega a las 14:00 UTC de un miércoles.
Si prefiere comprar esa capacidad en lugar de dotarla de personal propio, nos hacemos cargo de la operación de plataformas PHP en producción — cadencia de parcheo, monitorización, copias de seguridad y restauraciones documentadas — como parte de nuestro trabajo de infraestructura gestionada. Empiece con un breve resumen de sus necesidades y las cantidades: solicite una cotización.
Preguntas frecuentes
¿Se puede afirmar que mi sitio web está comprometido si ejecuta una versión de PHP sin parchear?
No necesariamente. Una instalación de PHP sin parchear y expuesta a internet está expuesta, y el escaneo comenzó en torno a la divulgación, pero exposición no es compromiso. Parchee primero y ejecute después los pasos de verificación anteriores; considere el servidor comprometido solo ante evidencia, y si encuentra alguna, reconstruya en lugar de limpiar.
Mi proveedor dice que tenemos PHP 8.3.6. ¿Está parcheado o no?
Depende de la compilación. Los paquetes de las distribuciones incorporan las correcciones de los CVE conservando el número de versión upstream, de modo que un PHP 8.3.6 de Ubuntu 24.04 o Debian puede incluir ya ambas correcciones. Pida la versión completa del paquete y la línea del changelog que nombra CVE-2026-109618 y CVE-2026-109619; en plataformas gestionadas, pida en su lugar la fecha del parche.
¿Me protegen de PHP2Shell las actualizaciones de plugins, temas o frameworks?
No. Ambos fallos están en la preparación y el desmontaje de la petición dentro del intérprete de PHP, no en el código de la aplicación. Las actualizaciones de la aplicación siguen siendo una buena higiene y un WAF frena el tráfico oportunista, pero solo la actualización del intérprete elimina la vulnerabilidad.
¿Basta con fijar un límite de memoria más bajo para bloquear el fallo de falta de memoria?
Todo lo contrario. La orientación provisional del aviso para CVE-2026-109618 es evitar que PHP se interrumpa al alcanzar su propio techo de memoria — memory_limit = -1, definido de modo que el código de la aplicación no pueda anularlo — y después limitar la complejidad de las peticiones en el proxy y contener el worker con un límite de contenedor o cgroup. Un límite de PHP más ajustado queda dentro del modo de fallo que se está explotando.
Estamos en PHP 8.1 o anterior, que no recibió versión upstream. ¿Qué hacemos?
Pásese a una rama con soporte si puede; esa es la respuesta duradera. Si no puede, tome la corrección de su distribución o de su proveedor, que es la única fuente realista, o aplique los backports mínimos de código fuente que el proyecto PHP publicó para 7.4, 8.0 y 8.1 si compila desde el código fuente. Registre esa decisión, porque cambia su perfil de riesgo cada mes que la mantenga.
¿Es arriesgado actualizar de PHP 8.3 a 8.3.36 en una tienda en producción?
Una actualización de seguridad dentro de la misma rama menor cambia el binario del intérprete, no el lenguaje, así que la mayoría de las aplicaciones no se ven afectadas. El riesgo es operativo: conjuntos de paquetes parciales, un reinicio olvidado o una configuración que solo aparece bajo carga. Haga una instantánea, actualice todo el conjunto de paquetes de PHP, reinicie el proceso que atiende las peticiones y verifique — y hágalo primero en staging cuando la plataforma sea compleja.
Fuentes
- PHP — aviso de seguridad «Critical remote code execution vulnerabilities, update now» y anuncios de publicación del 21 de octubre de 2026, incluida la guía de mitigación y el calendario de soporte de las versiones con soporte.
- Avisos de seguridad de GitHub para el repositorio de PHP: GHSA-w8hw-w9fx-j79w (CVE-2026-109618) y GHSA-6wmf-4rv5-p3rp (CVE-2026-109619).
- CERT-EU — Security Advisory 2026-018, «Critical Vulnerabilities in PHP», que cita ambos CVE.
- Infosecurity Magazine — «Critical PHP Vulnerabilities Leaked Ahead of Scheduled Security Patches» (21 de octubre de 2026) y «PHP2Shell Exploitation Attempt Detected by Amazon Four Days Before Vulnerability Disclosure» (22 de octubre de 2026).
¿Quiere que nos encarguemos de la actualización? Para hablar del parcheo, de una auditoría de versiones, de la migración a una plataforma PHP gestionada y parcheada o de la infraestructura que la rodea, contáctenos o llame al +90 505 679 78 03.