Escritos

Dentro de PHP CVE-2026-115560: el desajuste entre Session Upload Progress y el serialize handler

Más allá del clickbait sobre el aviso CVE-2026-115560 de PHP (CVSS 6.4): cómo los cambios en tiempo de ejecución de session.serialize_handler chocan con session.upload_progress y provocan PHP Object Injection, y la mitigación de una línea en php.ini.

Furkan Özay24 de octubre de 2026 · 4 min de lectura
czCZAY.DEV // EDITORIALES
GÜVENLIK

#Güvenlik · 4 MIN DE LECTURA

FURKAN ÖZAYVOL. 2026 // #2AD7

Cada vez que aparece un nuevo CVE en el ecosistema de PHP, los titulares sensacionalistas gritan de inmediato sobre "tomas de control totales del servidor sin autenticación". Cuando el PHP Group publicó CVE-2026-115560 (CVSS 6.4) (GHSA-4966-6377-397r), los rumores lo confundieron rápidamente con fallos de los wrappers HTTP.

Como ingenieros de backend, nuestro trabajo no es entrar en pánico por los titulares, sino leer el aviso de seguridad original y entender la ruta de ejecución exacta. Vamos a desmenuzar qué es realmente CVE-2026-115560, por qué ocurre, qué aplicaciones están realmente afectadas y cómo neutralizarlo con una sola línea en php.ini.

· · ·

1. El mecanismo central: cómo serializa PHP las sesiones

PHP admite varios formatos internos (session.serialize_handler) para codificar la superglobal $_SESSION antes de escribirla en disco o en Redis:

  1. php (predeterminado): Formatea las entradas como key|serialized_value (usando el carácter pipe | como delimitador).
  2. php_serialize (introducido en PHP 5.5.4): Formatea todo el array de sesión con el serialize() estándar, sin delimitadores pipe especiales.

Mientras una aplicación use exactamente el mismo serializador al escribir y al leer una sesión, todo es seguro. El peligro surge cuando los datos se escriben con php_serialize (que permite caracteres | sin escapar dentro de las cadenas) y luego se leen con el handler php (que trata todo lo que hay después de | como un objeto PHP serializado).

· · ·

2. Dónde entra en juego session.upload_progress

Cuando session.upload_progress.enabled = 1 está activo en php.ini, PHP inspecciona las subidas de archivos multipart ANTES de que el código de tu aplicación (index.php) empiece a ejecutarse. Si la subida contiene un campo PHP_SESSION_UPLOAD_PROGRESS, el motor de PHP inicializa automáticamente la sesión durante la fase de arranque de la solicitud, usando el serializador predeterminado definido en php.ini.

El fallo de CVE-2026-115560

¿Qué pasa si tu código PHP cambia después el handler en tiempo de ejecución con lo siguiente?

php
// Changing the serializer dynamically at runtime before session_start()
ini_set('session.serialize_handler', 'php_serialize');
session_start();

Como el rastreador de progreso de subida ya inicializó las estructuras de sesión esperando un handler distinto, se produce un desajuste de serializador entre el payload del progreso de subida y el decodificador de sesión en tiempo de ejecución.

Un atacante puede enviar una subida multipart con un payload que empiece con un carácter pipe (|O:8:"Exploit":...). Cuando el handler desajustado deserializa el archivo de sesión, se desencadena una PHP Object Injection (deserialización de datos no confiables).

Información: ¿Por qué puntúa CVSS 6.4 y no 9.8?

A diferencia de los fallos de RCE universales, CVE-2026-115560 requiere dos condiciones previas concretas: session.upload_progress.enabled debe estar activado Y la aplicación debe sobrescribir dinámicamente session.serialize_handler en tiempo de ejecución mediante ini_set(). Las aplicaciones estándar de Laravel o Symfony que configuran las sesiones de forma estática no están expuestas al desajuste en tiempo de ejecución.

· · ·

3. Mitigación inmediata y versiones de PHP parcheadas

Paso 1: actualiza PHP

El equipo de PHP corrigió este desajuste del ciclo de vida en las versiones de seguridad oficiales de octubre de 2026:

  • PHP 8.3.x ➔ Actualiza a la versión parcheada
  • PHP 8.4.x / 8.5.x ➔ Actualiza a la versión parcheada

Paso 2: desactiva session.upload_progress en php.ini

Las aplicaciones web modernas siguen el progreso de subida de archivos en el cliente con JavaScript (XMLHttpRequest.upload.onprogress o streams de Fetch), lo que hace que el seguimiento heredado del progreso de subida en sesiones del lado del servidor de PHP sea totalmente redundante, además de una superficie de ataque recurrente.

Abre el php.ini de producción y desactívalo de forma permanente:

ini
; Disable legacy server-side upload progress session injection
session.upload_progress.enabled = 0

Reinicia php-fpm (systemctl reload php8.3-fpm) y todo el vector de ataque quedará cerrado de forma permanente.

Hoja de ruta y herramienta interactivas

Sigue leyendo