PHP (motor/intérprete) · Ejecución remota de código sin autenticación
PHP corrigió el 21 de octubre dos fallos críticos de corrupción de memoria, conocidos como «PHP2Shell», que permiten ejecutar código en el servidor sin credenciales. CISA ya los da por explotados.
El proyecto PHP publicó el 21 de octubre de 2026 las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35. Corrigen CVE-2026-109618 y CVE-2026-109619, dos fallos de gestión de memoria del propio motor que, según el fabricante, permiten a un atacante remoto sin credenciales ejecutar código con los permisos del proceso web. Los dos tienen una puntuación CVSS v4.0 de 9,2. El riesgo no depende del código de la web, sino de la versión de PHP y de cómo está desplegada. El caso más expuesto es Apache con mod_php. CISA añadió ambos CVE a su catálogo de vulnerabilidades explotadas (KEV) el 26 de octubre.
Materias: vulnerabilidades, ejecución remota de código, PHP, servidores web, parches, explotación activa, CISA KEV
PHP es el lenguaje con el que funciona buena parte de la web, desde WordPress hasta muchas intranets y despachos online. El 21 de octubre el proyecto PHP publicó parches de urgencia para dos fallos del propio intérprete, el programa que ejecuta el código PHP en el servidor. La comunidad los ha llamado «PHP2Shell» porque permiten «sacar una shell», es decir, tomar el control del servidor, con una simple petición web y sin usuario ni contraseña. No es un fallo de una aplicación concreta: basta con que el servidor use una versión vulnerable. Desde el 26 de octubre, la agencia estadounidense CISA los incluye en su lista de vulnerabilidades explotadas en ataques reales.
Descripción
Qué es
Son dos vulnerabilidades distintas en el núcleo de PHP («php-src») que el proyecto publicó juntas el 21 de octubre de 2026:
- CVE-2026-109618 – «RCE via OOM corruption» (aviso GHSA-w8hw-w9fx-j79w). RCE significa remote code execution, ejecución remota de código: el atacante consigue que el servidor ejecute órdenes suyas. OOM significa out of memory, falta de memoria. El fallo está en cómo PHP se recupera cuando una petición agota la memoria que tiene asignada.
- CVE-2026-109619 – «RCE via stale global state» (aviso GHSA-6wmf-4rv5-p3rp). Aquí el problema es un «estado global obsoleto»: datos que una petición deja en memoria compartida y que otra petición posterior reutiliza cuando ya no son válidos.
El fabricante clasifica ambos fallos como críticos, con una puntuación CVSS v4.0 de 9,2. El CVSS es la escala estándar de gravedad de 0 a 10. Las debilidades asignadas son CWE-416 (uso de memoria ya liberada, use-after-free), CWE-755 (manejo incorrecto de condiciones excepcionales), CWE-824 (acceso a puntero no inicializado), CWE-1325 (asignación de memoria mal controlada) y CWE-1419 (inicialización incorrecta de un recurso).
El vector CVSS indica que el ataque se lanza por red, no exige credenciales ni que la víctima haga nada, y tiene un impacto alto en confidencialidad, integridad y disponibilidad. También refleja que la complejidad es «alta» y que deben darse ciertas condiciones previas: el ataque no funciona siempre a la primera y depende de la configuración.
A quién y a qué versiones afecta
- PHP 8.5 anterior a 8.5.12
- PHP 8.4 anterior a 8.4.27
- PHP 8.3 anterior a 8.3.36
- PHP 8.2 anterior a 8.2.35
- PHP 8.1, 8.0, 7.4 y anteriores: ya no reciben versiones oficiales, aunque el proyecto ha publicado parches mínimos solo en código fuente para 7.4, 8.0 y 8.1.
Según el proyecto PHP y el Centro Canadiense de Ciberseguridad, está en riesgo toda instalación de PHP que atienda peticiones web, cualquiera que sea su SAPI, es decir, la forma en que PHP se conecta al servidor web: Apache con mod_php, PHP-FPM, php-cgi, FrankenPHP y LiteSpeed. El grado de riesgo confirmado varía según el caso (lo detallamos abajo). Conviene recordar que PHP también va integrado en muchos productos de terceros, como aparatos de red, paneles de alojamiento o imágenes de contenedores. Revisar solo los servidores propios no da una visión completa.
Mecánica
CVE-2026-109618: corrupción al quedarse sin memoria
Cuando una petición supera el límite de memoria (memory_limit), PHP sale de golpe del punto en que estaba mediante longjmp(), un salto que interrumpe lo que se estaba ejecutando. Según el aviso, en ciertos momentos esa salida brusca ocurre con datos de la petición a medio inicializar. Después, la rutina que cierra la petición trata esos datos inválidos como si fueran correctos. Eso corrompe la memoria y puede acabar en ejecución de código.
Para provocar esa falta de memoria sin superar en apariencia los límites de PHP, el atacante envía formularios multipart, el formato que se usa para subir archivos, manipulados de alguna de estas formas:
- sin una longitud declarada útil, de modo que se salta la comprobación inicial de
post_max_size; - con una cantidad ilimitada de cabeceras por parte, que dentro de PHP ocupan mucha más memoria que en la red;
- con controles de archivo vacíos, que no cuentan para
max_file_uploadspero sí generan estructuras en memoria, y que se multiplican con nombres de campo anidados.
Lo que ha confirmado el fabricante para cada SAPI:
- Apache mod_php: es el caso más grave. El cuerpo de la petición se procesa antes de que se ejecute el código de la aplicación, así que el fallo se activa antes de que la web haga nada. PHP validó una RCE completa por HTTP con los límites por defecto y configuraciones prefork normales.
- PHP-FPM: el análisis del código indica que es vulnerable, pero el aviso dice que no se ha demostrado un exploit completo. Un exploit es el programa o la técnica que aprovecha el fallo.
- FrankenPHP: según el análisis del código, probablemente se comporta como mod_php.
- LiteSpeed (LSAPI): es probable que haya exploits ligados a aplicaciones concretas, pero no están validados.
CVE-2026-109619: estado global obsoleto (use-after-free)
Un mismo proceso de PHP, llamado worker, atiende muchas peticiones seguidas. El fallo se produce en tres pasos:
- Una primera petición deja datos suyos (errores, sesión, objetos) apuntados desde una zona global del worker. Ocurre si se interrumpe por un error fatal, por un tiempo de ejecución agotado o por falta de memoria antes de que esos datos se limpien.
- PHP libera la memoria de esa petición, pero el puntero global sigue apuntando a ella.
- Una petición posterior que llega al mismo worker usa ese puntero antes de su inicialización normal. Es decir, usa memoria ya liberada.
El aviso identifica dos «consumidores» confirmados de ese dato caducado. Uno son los avisos que se generan al aplicar directivas INI por petición, por ejemplo desde .htaccess o php_value en mod_php, o PHP_VALUE en algunos frontales FPM. El otro es la función de progreso de subida de sesión (session.upload_progress), activada por defecto. Los casos confirmados son la opción fatal_error_backtraces de PHP 8.5, que es la base de la RCE confirmada en mod_php, y el ciclo de progreso de subida de sesión, validado en mod_php y en FPM. El impacto descrito es divulgación de memoria: el atacante podría leer datos que el proceso tenga en memoria, como contraseñas, tokens o claves. En determinados escenarios también es posible la ejecución de código con los privilegios del worker.
En los dos casos, si el servidor tiene varios workers o los recicla, el atacante necesita más intentos, pero el riesgo no desaparece. El código se ejecuta con los permisos de la cuenta del servidor web, no como administrador del sistema, aunque desde ahí puede intentar ir más lejos.
Respuesta del creador
El proyecto PHP
El 20 de octubre el equipo de seguridad de PHP avisó de que al día siguiente publicaría una versión crítica. Según BleepingComputer, adelantó el calendario previsto porque se habían filtrado en Internet detalles como los identificadores CVE y las mitigaciones. Las versiones corregidas salieron el 21 de octubre de 2026. Las distribuciones Linux y los proveedores de soporte extendido (LTS) recibieron los parches con antelación. Los avisos atribuyen el hallazgo a varios investigadores (lcfr-hax, sagitzadik-wiz, tomash-areion y amyb-oai). Algunos medios relacionan el descubrimiento con herramientas de inteligencia artificial, pero no lo hemos verificado en fuentes primarias. Según la prensa, PHP calificó como no funcionales las pruebas de concepto publicadas antes del parche. Una prueba de concepto es una demostración pública de cómo aprovechar el fallo.
El 23 de octubre PHP publicó además un aviso informativo sobre otro fallo distinto, CVE-2026-115560, que no queda corregido por estas versiones. Solo afecta a configuraciones poco habituales: aplicaciones que cambian session.serialize_handler en tiempo de ejecución. Hasta la próxima versión, PHP recomienda session.upload_progress.enabled=0.
Autoridades
- CISA (EE. UU.) añadió CVE-2026-109618 y CVE-2026-109619 a su catálogo KEV de vulnerabilidades explotadas el 26 de octubre de 2026. Fijó el 29 de octubre como plazo para que las agencias federales las corrijan.
- El Centro Canadiense de Ciberseguridad (alerta AL26-026, actualizada el 27 de octubre) explica que el 21 de octubre no constaba explotación, y que ahora fuentes abiertas indican que ambos CVE se explotan activamente.
- Según la prensa, el NCSC británico pidió actualizar de inmediato o desconectar los servidores hasta poder parchear, y CERT-EU recomendó aislar las aplicaciones PHP expuestas a Internet.
- No hemos encontrado aviso específico de INCIBE-CERT en el momento de redactar esta nota.
Qué se sabe de los ataques
Según BleepingComputer, Amazon Threat Intelligence afirma que los intentos empezaron el 17 de octubre, cuatro días antes del parche. Amazon reconoce que no sabe cómo obtuvieron los atacantes la información ni si alguno de esos intentos tuvo éxito. Cloudflare y watchTowr también informan de intentos, y la prensa recoge ajustes en las cargas maliciosas para esquivar las reglas de los cortafuegos de aplicaciones web (WAF). Otros analistas, como Dataminr y Recorded Future, señalan que no hay pruebas públicas suficientes para medir cuántos ataques han tenido éxito. En resumen: la explotación está confirmada por CISA, pero su alcance real sigue sin conocerse. No especulamos sobre la autoría.
Parches y mitigaciones
Versiones corregidas
- PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, publicadas el 21 de octubre de 2026.
- Ramas sin soporte (7.4, 8.0 y 8.1): el proyecto ha publicado parches mínimos solo en código fuente. La opción realista es el parche retroportado de su distribución o proveedor LTS, o migrar a una rama con soporte. Ojo: PHP 8.2 deja de tener soporte el 31 de diciembre de 2026.
- Si usa paquetes de una distribución Linux, revise el registro de cambios (changelog): el número de versión puede no reflejar que el parche ya está aplicado.
- En contenedores hay que reconstruir las imágenes. Según una fuente, la etiqueta flotante
php:8.2-fpmseguía apuntando un tiempo a 8.2.34, por lo que es más seguro fijar la versión exacta (p. ej.php:8.2.35-fpm). - Las compilaciones para Windows se volvieron a publicar el 26 de octubre con el sufijo «-1» por un fallo distinto en la librería Brotli. La versión de PHP es la misma.
Qué hacer ya
- Actualizar PHP en todos los servidores, empezando por los expuestos a Internet y los que usan Apache con mod_php.
- Reiniciar Apache, PHP-FPM y cualquier worker persistente. Si no, el proceso seguirá ejecutando el código vulnerable.
- Inventariar productos de terceros, aparatos y contenedores que incluyan PHP, y pedir el parche a sus proveedores.
- Revisar registros en busca de indicios: peticiones multipart anómalas seguidas de errores de límite de memoria, oleadas de errores HTTP 500, cookies
PHPSESSIDinusualmente grandes, reinicios de workers sin explicación y procesos, archivos o conexiones salientes inesperados del usuario del servidor web.
Mitigaciones provisionales (no sustituyen al parche)
El fabricante insiste en que ninguna configuración hace segura una instalación: estas medidas solo reducen la exposición.
- Para CVE-2026-109618: fijar
memory_limit=-1de forma administrativa, para que la aplicación no lo cambie; mantener bajopost_max_size(8M sin subidas de archivos, 32M con subidas); limitar el tamaño de las peticiones en el servidor web o proxy; bloquear multipart si la aplicación no lo usa. No useRLIMIT_ASniRLIMIT_DATAcomo límite de memoria, porque activan la ruta vulnerable. - Para CVE-2026-109619:
session.upload_progress.enabled=0enphp.inio en la configuración del pool o del servidor (no conini_set()ni.user.ini) y reiniciar los workers. PHP recomienda mantenerlo desactivado incluso tras parchear si no se usa. Además, esta medida cubre el fallo pendiente CVE-2026-115560. - En PHP 8.5:
fatal_error_backtraces=0y reiniciar procesos. - Si no se puede parchear de inmediato, plantearse aislar de la red pública las aplicaciones expuestas, como recomiendan CISA, el centro canadiense y el NCSC.
Tras actualizar, tenga en cuenta un cambio de comportamiento: el parche sustituye la salida brusca por un límite de memoria «suave» y otro «duro». Si un proceso alcanza el límite duro, termina sin ejecutar los manejadores de apagado (shutdown handlers). Conviene vigilar las aplicaciones que consumen mucha memoria.
Fuentes
- PHP.net – Anuncios: aviso previo, versiones de seguridad del 21/10/2026 y aviso informativo sobre progreso de subida de sesión
- GitHub php-src – GHSA-w8hw-w9fx-j79w (CVE-2026-109618): RCE via OOM corruption
- GitHub php-src – GHSA-6wmf-4rv5-p3rp (CVE-2026-109619): RCE via stale global state
- CISA – Known Exploited Vulnerabilities Catalog
- Canadian Centre for Cyber Security – AL26-026 Critical vulnerabilities impacting PHP
- BleepingComputer – Amazon says PHP2Shell exploitation began 4 days before patches
- BleepingComputer – PHP ships emergency patches for critical PHP2Shell flaws
- Help Net Security – PHP2Shell PHP vulnerabilities patched
- Tanium – PHP2Shell: responding to CVE-2026-109618 and CVE-2026-109619
- Recorded Future – PHP2Shell Exploitation: Two Critical PHP Flaws Explained
- Una Al Día (Hispasec) – PHP publica parches de urgencia por dos fallos críticos PHP2Shell
- The Hacker News – PHP Issues Emergency Patches for Two Critical PHP2Shell RCE Flaws
- ComputingForGeeks – PHP2Shell CVE-2026-109618: check and patch