El 21 de octubre de 2026, el proyecto PHP publicó versiones de emergencia para corregir dos errores críticos que permitían a un atacante no autenticado ejecutar código en un servidor web. El par se identifica como CVE-2026-109618 y CVE-2026-109619 y recibe el nombre de PHP2Shell. Ambos obtienen una puntuación de 9.2 en CVSS v4.0, ambos afectan a cualquier instalación de PHP que sirva HTTP, y los honeypots de Amazon registraron intentos de explotación el 17 de octubre, cuatro días antes de que existiera el parche.
PHP se ejecuta en el 69,3 % de los sitios web cuyo lenguaje del lado del servidor se conoce (W3Techs). Si tienes una API en PHP, un backend Laravel o Symfony, un sitio WordPress o una imagen de contenedor con PHP incorporado, esto te afecta.
Esta guía cubre qué hacen los errores, qué versiones están afectadas, cómo comprobar tus servidores, qué te aportan realmente las mitigaciones y cómo demostrar que tu API sigue funcionando después de aplicar el parche.
TL;DR
| Pregunta | Respuesta |
|---|---|
| ¿Qué es? | Dos errores de seguridad de memoria en el manejo de peticiones de PHP, encadenados hasta lograr ejecución remota de código |
| CVE | CVE-2026-109618 (corrupción por falta de memoria), CVE-2026-109619 (estado obsoleto, use-after-free) |
| Gravedad | CVSS v4.0 9.2 cada uno (los IDs filtrados inicialmente decían 10.0; PHP dice que eso era incorrecto) |
| ¿Requiere autenticación? | No |
| Afectados | Todas las SAPI que sirven HTTP: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed |
| Versiones corregidas | 8.5.12, 8.4.27, 8.3.36, 8.2.35 |
| PHP 8.1 y anteriores | Sin versión oficial; backports mínimos del código fuente para 7.4, 8.0, 8.1; de 5.4 a 7.3 no reciben nada |
| ¿Se ha explotado? | Se han visto intentos desde el 17 de octubre (Amazon), primeros ataques reportados por Cloudflare |
| Solución | Actualizar, reiniciar todos los workers. Los workarounds reducen el riesgo pero no lo eliminan |
Qué es realmente PHP2Shell
Ambos errores comparten una misma causa raíz: PHP puede dejar su memoria en un estado corrupto cuando una petición termina de forma anormal, y el código de limpieza después confía en ese estado corrupto.
CVE-2026-109618: corrupción por falta de memoria durante el arranque de la petición. Cuando PHP analiza los datos de formulario en $_POST, el código de la tabla hash del motor Zend incrementa su contador de entradas antes de asignar la nueva clave. El análisis de Datadog lo rastrea hasta _zend_hash_str_add_or_update_i() en zend_hash.c. Si esa asignación supera el memory_limit, PHP lanza un error fatal y abandona la inserción. El contador ahora incluye un bucket que nunca se configuró. Al apagarse, PHP destruye $_POST y trata cada bucket contado como real.
La parte que debería preocupar a los equipos de API: esto ocurre mientras PHP todavía está analizando el cuerpo de la petición, antes de que se ejecute una sola línea de tu código. Tu middleware de autenticación, tu limitador de peticiones y tu validación de entrada nunca ven la petición. Datadog lo reprodujo con un cuerpo simple application/x-www-form-urlencoded, no con una subida de archivo.
CVE-2026-109619: estado global obsoleto entre peticiones. PHP mantiene cierto estado compartido por worker que apunta a memoria de cada petición. Si un error fatal interrumpe el reinicio de ese estado, o un diagnóstico tardío de apagado lo recrea después de la limpieza, la siguiente petición en el mismo worker lee memoria liberada. PHP confirmó dos rutas:
- Backtraces de error fatal (solo PHP 8.5): un diagnóstico de configuración en una petición posterior lee el estado de backtrace sobrante. Ejecución de comandos confirmada en mod_php.
-
Procesamiento de subidas: después de un error fatal, el progreso de subida de sesión puede dejar estado atrás para una subida posterior. El progreso de subida está activado por defecto y se ejecuta incluso si tu aplicación nunca llama a
session_start(). Ejecución de comandos confirmada en mod_php y PHP-FPM.
El equipo de seguridad de PHP califica mod_php como el de mayor riesgo, ya que el exploit demostrado se dispara desde una sola petición no autenticada antes de que se cargue cualquier código de la aplicación.
Quién lo encontró (y por qué la IA está en los titulares)
Los errores se remontan a código introducido en PHP 5.4.0, así que permanecieron en la base de código durante más de una década. La PHP Foundation dio crédito a Calif, OpenAI y Wiz.
Los reportes de Decrypt y The Next Web dicen que el investigador de Calif Ryan Austin encontró los fallos en agosto durante una auditoría de código fuente asistida por GPT-5.6 Sol de OpenAI. OpenAI dice que su propio equipo encontró una versión más completa en septiembre como parte de su trabajo "Patch the Planet". Wiz dice que encontró ambos errores por su cuenta usando Gemini 4 Argon, Wiz Atlas y GPT-5.6 Sol. El crédito está en disputa; la conclusión no. Las auditorías asistidas por IA están encontrando ahora errores de memoria de hace una década en infraestructura crítica, y los atacantes tienen los mismos modelos.
Cronología: por qué el parche llegó un día antes
| Fecha (2026) | Qué ocurrió |
|---|---|
| Agosto a septiembre | Calif, OpenAI y Wiz reportan los errores de forma privada |
| 17 oct | El honeypot MadPot de Amazon registra un intento de explotación |
| 20 oct | Los IDs CVE se filtran en Hacker News y redes sociales; PHP publica un aviso previo; CERT-EU emite el boletín 2026-018 |
| 21 oct, 14:00 UTC | PHP publica las correcciones, adelantadas desde el 22 de octubre tras la filtración; CISA publica una alerta; Cloudflare reporta ataques tempranos |
| 22 oct | Ninguno de los CVE está todavía en el catálogo KEV de CISA |
Amazon aconseja investigar desde el 17 de octubre (las FAQ de Tenable recogen la cronología completa), no desde la fecha de divulgación. En el momento del lanzamiento, el equipo de PHP dijo que inspeccionó el código proof-of-concept que apareció tras la filtración y no encontró ningún exploit funcional. Desde entonces, watchTowr ha dicho que reprodujo ambos errores. Trata cualquier repositorio de "PoC" que encuentres como sospechoso: el código de exploit no verificado a menudo distribuye malware.
¿Estás afectado? Compruébalo en cinco minutos
1. Comprueba el runtime que sirve el tráfico, no tu portátil. El binario de CLI puede diferir del módulo FPM o Apache en versión y configuración.
# On the server or inside the running container
php -v
php-fpm -v
# Apache mod_php: check the loaded module version
apachectl -M 2>/dev/null | grep -i php
O expónlo una vez desde una ruta protegida y elimínalo después:
<?php echo PHP_VERSION, ' ', PHP_SAPI;
2. Compáralo con las versiones corregidas.
| Rama | Vulnerable | Corregido en |
|---|---|---|
| 8.5 | < 8.5.12 | 8.5.12 |
| 8.4 | < 8.4.27 | 8.4.27 |
| 8.3 | < 8.3.36 | 8.3.36 |
| 8.2 | < 8.2.35 | 8.2.35 |
| 7.4 a 8.1 | Todas | Solo backports del código fuente, o LTS del proveedor |
| 5.4 a 7.3 | Todas | Sin corrección |
Debian, Ubuntu, Red Hat y otras distribuciones a menudo aplican backports de las correcciones sin cambiar la cadena de versión upstream. Si php -v muestra un número más antiguo, lee el boletín de tu distribución antes de alarmarte.
3. Inventaría el PHP oculto. Contenedores construidos con FROM php:8.3-fpm hace meses, appliances de proveedores, compilaciones propias, paneles de administración en subdominios olvidados. Cisco ya ha abierto un boletín para revisar su propia línea de productos. Shodan cuenta más de 1,9 millones de hosts PHP expuestos a Internet; un investigador estima que 1,3 millones o más podrían ser vulnerables.
Cómo aplicar el parche
# Debian / Ubuntu (Ondřej Surý PPA or distro packages)
sudo apt update && sudo apt install --only-upgrade 'php8.*'
# RHEL / Rocky / Alma with Remi
sudo dnf upgrade 'php*'
# Official Docker image: rebuild on a fixed tag
docker pull php:8.4.27-fpm
docker build --pull -t my-api:patched .
Después haz el paso que la mayoría de los equipos olvida: reinicia o reemplaza todos los workers de PHP. Un pool FPM en ejecución mantiene el binario antiguo en memoria. Reinicia php-fpm, recarga Apache y renueva todos los contenedores. CVE-2026-109619 trata sobre estado que vive entre peticiones dentro de un worker, así que un worker sin reiniciar sigue siendo vulnerable.
En 8.1 o versiones anteriores, tienes tres opciones: un paquete LTS del proveedor, compilar desde el backport del código fuente de PHP, o actualizar a 8.2 o superior. CISA recomienda sacar de línea los sistemas PHP que no se puedan parchear, y el NCSC del Reino Unido y el FBI han dicho lo mismo.
Mitigaciones si no puedes aplicar el parche hoy
Estas medidas ganan tiempo. Gina Peter Banyard, del equipo central de PHP, dijo a BleepingComputer que ninguna mitigación bloquea por completo los ataques.
Para CVE-2026-109618:
- Establece
memory_limit=-1donde las aplicaciones no puedan sobrescribirlo (php_admin_valueen el pool de FPM o en la configuración de Apache). Esto bloquea la ruta conocida, pero no todas las formas en que una asignación puede fallar. - Reduce
post_max_size(8M sin subidas, 32M con subidas). - Limita el tamaño del cuerpo de la petición en el proxy inverso (
client_max_body_sizeen nginx), y establece límites de memoria de contenedor o cgroup como frontera de disponibilidad. - No uses límites de proceso
RLIMIT_ASniRLIMIT_DATA. Pueden provocar justamente los fallos de asignación que el exploit necesita.
Para CVE-2026-109619:
- Establece
session.upload_progress.enabled=0en la configuración que se carga antes del análisis de la petición. - En PHP 8.5, establece también
fatal_error_backtraces=0. - Ocultar errores con
display_errors=0o@no sirve de nada. El estado obsoleto sigue existiendo.
En el borde: Cloudflare desplegó reglas WAF para los vectores conocidos en todos los planes, incluido el gratuito. Su CTO las calificó de temporales.
Después de cualquier cambio en php.ini, reinicia todos los workers o no surtirá efecto.
Señales de que ya has sido atacado
Las indicaciones de detección de Datadog se reducen a cuatro señales:
-
Línea de log:
PHP Fatal error: Allowed memory size of ... bytes exhaustedconUnknown on line 0. Eso significa que PHP murió durante el arranque de la petición, antes de que se ejecutara ningún script. -
Caídas de Apache:
AH00052: child pid ... exit signal Segmentation fault (11), probablemente un intento de exploit fallido. - Envíos de formulario extraños: un nombre de campo de varios megabytes de longitud, o bytes binarios y nulos en un campo con nombre vacío.
-
La contundente: un worker web (
php-fpm,apache2,httpd) lanzando un shell.
No confíes en los códigos de estado. El exploit refinado de Datadog devolvía HTTP 200 y el worker seguía funcionando. Revisa los logs hasta el 17 de octubre.
Demuestra que tu API sigue funcionando tras el parche: deja que tu agente lo ejecute
Parchear PHP en producción bajo presión es la forma de descubrir que un salto de versión menor cambió algo. Antes y después de desplegar la corrección, ejecuta tu suite de pruebas de API contra staging, y deja que tu agente de programación lo haga con Apidog CLI.
Configuración (una vez):
npm install -g apidog-cli
apidog auth login --with-token <your-access-token>
apidog test-suite list --project <projectId>
Un solo prompt para Claude Code, Codex o Cursor:
Acabamos de actualizar PHP a 8.4.27 en staging por PHP2Shell. Usa el CLI de Apidog para ejecutar nuestra suite de pruebas de regresión contra el entorno de staging, genera informes HTML y JUnit, y resume cualquier endpoint que falle. Después confirma que un POST con un cuerpo superior a nuestro
client_max_body_sizede nginx se rechaza con 413 en el proxy en lugar de llegar a PHP.
Lo que ejecuta el agente:
apidog test-suite run <testSuiteId> --project <projectId> -e <stagingEnvId>
apidog run --test-suite <testSuiteId> --project <projectId> -e <stagingEnvId> \
-r cli,html,junit --out-dir ./php2shell-reports --upload-report
-r selecciona los reportadores, --out-dir establece dónde se guardan los informes, y --upload-report envía un resumen que puedes abrir en la aplicación Apidog. Añade --notification-failed-event <targetId> para avisar a tu equipo solo cuando algo falle. Coloca la misma línea de apidog run en CI para que cada imagen PHP reconstruida se pruebe antes de desplegarse. La guía de configuración de Claude Code y el recorrido por el pipeline CI/CD cubren ambos en detalle.
Ejecuta la suite una vez en la versión antigua para obtener una línea base, una vez después de la actualización, y compara. Si una prueba que nunca esperabas que fallara falla, lo sabrás antes que tus usuarios. Descarga Apidog para crear y gestionar las suites que ejecuta el CLI.
FAQ
¿Se está explotando PHP2Shell? Amazon vio intentos desde el 17 de octubre y dice que ahora se explota ampliamente; Cloudflare y watchTowr también reportan ataques. CISA no había confirmado la explotación a fecha del 22 de octubre.
¿Mi framework me protege? No. CVE-2026-109618 se dispara mientras PHP analiza el cuerpo, antes de que se cargue Laravel, Symfony o WordPress.
Estoy en hosting compartido. ¿Qué hago? Consulta la página de estado de tu proveedor. SiteGround y otros dicen que ya han parcheado. Si el tuyo no ha dicho nada, pregúntales.
¿Basta con session.upload_progress.enabled=0? No. Cubre una ruta de un CVE. Parchea.
¿Necesito rotar secretos? CVE-2026-109619 permite la divulgación de memoria. Si los logs muestran signos de compromiso desde el 17 de octubre, rota las contraseñas de bases de datos, las claves de API y los secretos de sesión que el proceso PHP pudiera leer.
Conclusión
Actualiza a 8.5.12, 8.4.27, 8.3.36 o 8.2.35. Reinicia todos los workers. Encuentra el PHP del que te habías olvidado. Revisa los logs hasta el 17 de octubre. Después ejecuta tus pruebas de API para que la corrección no se convierta en la próxima caída. Si tu PHP está en 8.1 o anterior, esta es la semana para abandonarlo de una vez.
Top comments (0)