PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35: correcciones críticas de ejecución remota de código y cómo parchear sin sorpresas con Docker
El 21 de oct. de 2026 PHP corrigió dos fallos críticos de RCE sin autenticación. Quién está afectado, cómo comprobar la versión que sirve la web y tres trampas de Docker que encontramos.
El 21 de octubre de 2026 el proyecto PHP publicó las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35. Según php.net, corrigen dos vulnerabilidades críticas que pueden permitir la ejecución remota de código sin autenticación. Ambas tienen una puntuación CVSS v4.0 de 9.2. Si sirves peticiones web con PHP, planifica actualizar hoy.
Qué se corrigió
El aviso de seguridad del proyecto describe dos problemas:
- CVE-2026-109618 (GHSA-w8hw-w9fx-j79w, «RCE via OOM corruption»): el manejo de falta de memoria puede interrumpir PHP mientras los datos de la petición están solo parcialmente inicializados, y la limpieza de la petición trata datos no válidos como válidos.
- CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp, «RCE via stale global state»): el estado propio de una petición puede sobrevivir a la liberación de su memoria, y una petición posterior del mismo worker lo usa antes de que se restablezca.
Están afectadas todas las versiones anteriores a 8.2.35, 8.3.36, 8.4.27 y 8.5.12. El aviso indica que actualizar es la única corrección completa.
Quién está afectado
Todo lo que sirva peticiones web con PHP. Los avisos de GitHub tratan Apache mod_php, PHP-FPM, LiteSpeed (LSAPI) y FrankenPHP. El anuncio de php.net dice que el riesgo es mayor para mod_php, «con un exploit demostrado en el que una petición no autenticada puede desencadenar el ataque antes de que se ejecute código de la aplicación».
Según los avisos, PHP-FPM parece susceptible por análisis del código fuente y se validó una ruta por el ciclo de vida de las sesiones para el segundo fallo; para FrankenPHP, el análisis indica que probablemente es susceptible a ataques independientes de la aplicación en el primer fallo. Los detalles varían según la SAPI, así que trata todas las SAPI web como en riesgo.
Una aclaración: php.net habla de un exploit demostrado. No encontramos una fuente primaria que confirme ataques reales en curso, así que no lo afirmamos.
Versiones y fin de soporte
- Corregido en 8.5.12, 8.4.27, 8.3.36, 8.2.35.
- PHP 8.2 llega al fin de su vida útil el 31 de diciembre de 2026.
- PHP 8.1 y anteriores ya no reciben actualizaciones del proyecto. El aviso dice que algunos proveedores ofrecen backports.
- El rastreador de seguridad de Debian lista correcciones en bookworm (php8.2 8.2.35-1
deb12u1) y trixie (php8.4 8.4.27-1deb13u1) cuando lo consultamos.
Si no puedes actualizar de inmediato
El aviso enumera mitigaciones parciales que no hacen segura una instalación:
memory_limit = -1 ; con php_admin_value para que no se sobrescriba
session.upload_progress.enabled = 0 ; luego reinicia los workers
; solo PHP 8.5:
fatal_error_backtraces = 0
También sugiere reducir post_max_size (8M sin subidas, 32M con subidas), limitar partes multipart, cabeceras y subidas, o bloquear peticiones multipart en el frontend si no las usas.
Comprueba la versión que realmente se ejecuta
php -v muestra la versión de CLI, no necesariamente la que responde a las peticiones HTTP. Comprueba la SAPI web:
# dentro del contenedor o en el host que sirve el tráfico
php -r 'echo PHP_VERSION, " ", PHP_SAPI, PHP_EOL;' # solo CLI, una pista
php-fpm -v # binario de FPM
La respuesta fiable es preguntar a un proceso web en ejecución: una página temporal que imprima PHP_VERSION y PHP_SAPI (bórrala después y nunca dejes phpinfo() público).
Después reinicia todos los procesos PHP. Un binario nuevo en disco no cambia nada para los procesos que ya están en marcha. Los workers de larga duración (Octane, RoadRunner, modo worker de FrankenPHP, workers de colas, planificadores) conservan el código antiguo hasta que se reinician.
Qué hicimos en Woodander
Parcheamos nuestra propia infraestructura el mismo día. Tres cosas nos costaron tiempo y afectan a la mayoría de configuraciones con Docker.
1. Las imágenes van por detrás de la publicación. Horas después del lanzamiento, la imagen dunglas/frankenphp:1-php8.4-bookworm seguía con PHP 8.4.26, mientras la oficial php:8.4-zts-bookworm ya tenía 8.4.27. Construimos nuestra propia base: la imagen oficial de PHP ZTS más el binario de FrankenPHP copiado de la imagen upstream (enlaza libphp.so de forma dinámica). Verificamos que la SAPI web servía 8.4.27 y volveremos a upstream cuando la reconstruyan. Ojo: frankenphp version sigue mostrando la versión de PHP contra la que se compiló el binario, así que verifica con una petición real, no con el banner.
2. El registro de paquetes estaba saturado. PECL devolvió errores 504 mientras todos reconstruían, y nuestra compilación de la extensión redis falló. El tarball de la etiqueta de phpredis en GitHub no es un sustituto directo: le falta el submódulo liblzf. Reintentar cuando PECL se recuperó funcionó. Cachea o incluye en tu repositorio las compilaciones de extensiones y conserva una imagen buena conocida para volver atrás.
3. ufw no protege los puertos publicados por Docker. Una regla de ufw «permitir solo Cloudflare» no se aplica a los puertos que publica Docker, porque las reglas de iptables de Docker se evalúan primero. Pon la restricción en la cadena DOCKER-USER o usa Cloudflare Tunnel para que el origen no tenga puerto público. Comprueba desde fuera:
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' http://YOUR_ORIGIN_IP:PORT/
Si responde, el origen es accesible directamente, diga lo que diga ufw. Esto importa más mientras parcheas.
Lista de comprobación
- Haz una instantánea del servidor o conserva la etiqueta de la imagen anterior.
- Actualiza a la versión corregida de tu rama (o a un paquete del proveedor con el backport).
- Reinicia todo lo que ejecute PHP: FPM, Apache, FrankenPHP, workers de colas, planificadores.
- Verifica la versión de cada proceso a través de la SAPI web.
- Asegúrate de que el origen no sea accesible directamente si dependes de un CDN o un firewall.
- Busca signos de compromiso: archivos desconocidos en directorios web y de subidas, tareas cron nuevas, procesos inusuales, conexiones salientes inesperadas y logs de PHP con cierres inesperados o errores fatales. El aviso señala que unos logs limpios no demuestran seguridad.