testing session.upload_progress.enabled = Off

Guía de Mitigación de Emergencia: Desactivación de session.upload_progress y Parches para Versiones EOL

php2shell.run Research Lab •

Guía de Mitigación de Emergencia: Desactivación de session.upload_progress y Parches para Versiones EOL

<time datetime="2026-10-23">Verificado: 23 de octubre de 2026</time> · Nivel de severidad operativa: Máxima prioridad (P0)

Ante la confirmación de la explotación activa de las vulnerabilidades PHP2Shell (CVE-2026-109618 y CVE-2026-109619), los administradores de sistemas y equipos de operaciones deben implementar contramedidas inmediatas para salvaguardar sus aplicaciones web.

Esta guía técnica proporciona los procedimientos exactos para neutralizar el vector de ataque con cero tiempo de inactividad (Zero-Downtime) en plataformas Linux de producción, junto con el manual de compilación de parches retrocompatibles para aquellas instalaciones atrapadas en versiones de PHP que han alcanzado el fin de su vida útil (End-of-Life: PHP 8.1, 8.0 y 7.4).


1. Matriz de Prioridad de Respuesta a Incidentes

Nivel de PrioridadÁmbito de AplicaciónAcción RequeridaTiempo de ImplementaciónImpacto en el Negocio
P0 (Inmediato)Todos los servidores web y PHPDesactivar session.upload_progress.enabledMenos de 5 minutosNinguno (Graceful Reload)
P1 (Perímetro)Nginx, HAProxy, WAFDescartar peticiones multipart sospechosas15 minutosNinguno
P2 (Definitivo)PHP con soporte (8.2 a 8.5)Actualizar a versiones oficiales seguras30 a 60 minutosMantenimiento programado
P3 (Sistemas Legacy)Ramas EOL (PHP 8.1 y anteriores)Aplicar parches de código fuente en C2 a 4 horasRequiere compilación y pruebas

2. Mitigación Inmediata con Cero Downtime (En 5 Minutos)

El mecanismo causante del fallo de Use-After-Free y doble liberación de memoria en el núcleo de PHP reside de forma exclusiva en la característica session.upload_progress. Al apagar este interruptor en el motor de configuración, se desactiva por completo la ruta de ejecución vulnerable en lenguaje C.

Paso 2.1: Localización de los archivos php.ini activos

Diferentes interfaces SAPI (PHP-FPM, CLI, Apache mod_php) utilizan árboles de configuración independientes. Identifique las rutas exactas en su sistema:

# Identificar el archivo ini cargado por el CLI
php --ini | grep "Loaded Configuration File"

# Buscar todas las instancias de php.ini en el servidor
find /etc/ -name "php.ini" 2>/dev/null

En entornos Debian y Ubuntu, las rutas habituales son /etc/php/8.x/fpm/php.ini y /etc/php/8.x/cli/php.ini. En CentOS, Rocky Linux, RHEL y servidores cPanel con CloudLinux, la ruta suele ser /etc/php.ini o /opt/cpanel/ea-phpXX/root/etc/php.ini.

Paso 2.2: Desactivación de la directiva

Edite el archivo correspondiente asegurándose de que la directiva no quede comentada con punto y coma:

; Endurecimiento crítico contra CVE-2026-109618 y CVE-2026-109619
[Session]
session.upload_progress.enabled = Off
session.upload_progress.cleanup = On

Para automatizar la aplicación sin riesgo de error humano en múltiples servidores, cree un archivo de extensión directa (drop-in config):

echo -e "; Mitigacion PHP2Shell\nsession.upload_progress.enabled = Off" | sudo tee /etc/php/8.3/mods-available/php2shell.ini
sudo phpenmod php2shell

Paso 2.3: Recarga suave del servicio (Graceful Reload)

Es fundamental no utilizar restart, ya que terminaría de forma abrupta las sesiones HTTP y transacciones activas de sus usuarios. Utilice reload:

# Para sistemas basados en Debian / Ubuntu
sudo systemctl reload php8.3-fpm

# Para sistemas basados en Red Hat / AlmaLinux / Rocky Linux
sudo systemctl reload php-fpm

# Validar que la sintaxis de configuración no contiene errores
sudo php-fpm8.3 -t

3. Endurecimiento Perimetral en Capa de Proxy Inverso (Nginx)

Si gestiona una granja de servidores de gran volumen y requiere una solución de bloqueo global previa a la propagación de cambios en los nodos PHP individuales, configure reglas de contención en su proxy inverso Nginx.

El payload de PHP2Shell inyecta el parámetro PHP_SESSION_UPLOAD_PROGRESS dentro de peticiones con cabecera Content-Type: multipart/form-data.

Configuración Nginx (/etc/nginx/conf.d/php2shell_protection.conf):

# Mapeo de método y comprobación de cabecera multipart
map $request_method $is_post {
    default 0;
    POST 1;
}

server {
    listen 443 ssl http2;
    server_name midominio.com;

    # Ajuste de buffer para análisis de cuerpo inicial
    client_body_buffer_size 128k;

    location / {
        # Regla ModSecurity / Coraza para descartar peticiones maliciosas
        # SecRule REQUEST_HEADERS:Content-Type "@rx (?i)multipart/form-data" \
        #     "id:10261091,phase:2,chain,deny,status:403,log,msg:'Bloqueo de PHP2Shell en Nginx'"
        # SecRule REQUEST_BODY "@rx (?i)PHP_SESSION_UPLOAD_PROGRESS"

        proxy_pass http://backend_php_pool;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Recargue Nginx sin corte de tráfico:

sudo nginx -t && sudo systemctl reload nginx

4. Parcheo y Compilación en Código Fuente para PHP 8.1 EOL

Las organizaciones que ejecutan versiones de PHP declaradas obsoletas (como PHP 8.1, PHP 8.0 o PHP 7.4) no recibirán actualizaciones automáticas mediante apt upgrade o yum update. Para entornos que no puedan migrar inmediatamente de versión, se debe aplicar el parche correctivo directamente en el árbol de código fuente en lenguaje C.

El Parche en C para ext/session/session.c:

Este cambio asegura que el puntero residual cached_post_bytes sea liberado y puesto a NULL de manera explícita cuando el ciclo de sesión se reinicializa o aborta, eliminando la condición de Use-After-Free:

--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1480,6 +1480,12 @@ PHP_SESSION_API void php_session_cleanup(void)
 	if (PS(cached_post_bytes)) {
 		efree(PS(cached_post_bytes));
 		PS(cached_post_bytes) = NULL;
+	}
+
+	/* CVE-2026-109619: Prevencion de punteros colgantes en el estado global */
+	if (PS(upload_progress_key)) {
+		zend_string_release(PS(upload_progress_key));
+		PS(upload_progress_key) = NULL;
 	}
 }

Proceso de Compilación e Instalación Segura:

# 1. Instalar dependencias del sistema
sudo apt-get update && sudo apt-get build-dep -y php8.1

# 2. Descargar código fuente de la rama EOL
git clone --depth 1 --branch PHP-8.1.31 https://github.com/php/php-src.git
cd php-src

# 3. Aplicar el parche correctivo
patch -p1 < /ruta/al/parche-php2shell.patch

# 4. Configurar con soporte FPM y optimizaciones de seguridad
./buildconf --force
./configure --prefix=/opt/php8.1-hardened \
            --enable-fpm \
            --with-fpm-user=www-data \
            --with-fpm-group=www-data \
            --with-openssl \
            --with-zlib \
            --with-curl \
            --enable-mbstring

# 5. Compilar y ejecutar pruebas de regresión
make -j$(nproc)
make test
sudo make install

5. Script Automatizado de Verificación de Cumplimiento

Incorpore el siguiente script en sus canalizaciones de CI/CD o herramientas de automatización (Ansible, Puppet, Chef) para auditar el estado de seguridad de sus servidores de forma periódica:

#!/usr/bin/env bash
# Auditoria de Estado de Seguridad contra PHP2Shell
set -euo pipefail

echo "========================================="
echo "   REPORTE DE AUDITORÍA PHP2SHELL        "
echo "========================================="
echo "Servidor: $(hostname -f)"
echo "Fecha de verificación: $(date -u)"

PHP_BIN=$(command -v php || true)
if [ -z "$PHP_BIN" ]; then
    echo "[-] No se detectó instalación de PHP en el PATH."
    exit 0
fi

CURRENT_VER=$(php -r "echo PHP_VERSION;")
echo "[+] Versión de PHP activa: ${CURRENT_VER}"

PROGRESS_STATUS=$(php -r "echo ini_get('session.upload_progress.enabled') ? 'EXPUESTO' : 'PROTEGIDO';")
echo "[+] Estado de session.upload_progress: ${PROGRESS_STATUS}"

if [ "$PROGRESS_STATUS" == "PROTEGIDO" ]; then
    echo "========================================="
    echo "RESULTADO: [APROBADO] El servidor está protegido contra RCE no autenticado."
    echo "========================================="
    exit 0
else
    echo "========================================="
    echo "RESULTADO: [CRÍTICO] El servidor está EXPUESTO. Desactive session.upload_progress.enabled de inmediato."
    echo "========================================="
    exit 1
fi

6. Consideraciones Especiales en Entornos Docker, Kubernetes y Paneles de Control

En infraestructuras modernas donde las aplicaciones PHP se ejecutan en contenedores efímeros o bajo paneles de control automatizados (como cPanel, Plesk o DirectAdmin), la mitigación requiere consideraciones operativas adicionales para evitar que los cambios se reviertan automáticamente:

Contenedores Docker y Clústeres Kubernetes

En arquitecturas basadas en imágenes de Docker (como php:8.2-fpm-alpine o wordpress:php8.3), modificar el archivo de configuración en un contenedor en ejecución solo proporciona protección temporal, ya que cualquier recreación del pod o escalado horizontal restaurará la imagen vulnerable.

La solución adecuada consiste en inyectar la directiva en la etapa de construcción del contenedor o mediante un ConfigMap montado como volumen:

# Dockerfile endurecido contra PHP2Shell
FROM php:8.3-fpm-alpine

# Inyectar configuración de mitigación permanente
RUN echo "session.upload_progress.enabled = Off" > /usr/local/etc/php/conf.d/docker-php-ext-php2shell.ini

USER www-data
CMD ["php-fpm"]

En clústeres de Kubernetes, cree un recurso de tipo ConfigMap y móntelo en /usr/local/etc/php/conf.d/security.ini de su Deployment, asegurando que todos los pods replicados nazcan con la vulnerabilidad cerrada desde el primer segundo de vida.

Servidores cPanel / WHM con EasyApache 4

En servidores con cPanel, las modificaciones manuales directas en /etc/php.ini pueden ser sobreescritas durante las tareas de mantenimiento nocturno de upcp. La forma recomendada de fijar la configuración consiste en utilizar la interfaz de MultiPHP INI Editor en WHM, o bien aplicar la directiva en cada perfil individual en /opt/cpanel/ea-php*/root/etc/php.d/local.ini. Tras realizar el ajuste, ejecute /scripts/restartsrv_apache_php_fpm para propagar los cambios a todos los VirtualHosts de los clientes.