PHP2Shell (CVE-2026-109618 y CVE-2026-109619): cómo saber si estás afectado y cómo parchear

Dos fallos críticos de ejecución remota de código en PHP, corregidos el 21 de octubre de 2026 en las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35. Qué pasa, quién está expuesto, cómo verificar tu versión, qué mitigaciones temporales existen y qué hacer después de parchear.

En este artículo
En 30 segundos

PHP corrigió el 21 de octubre de 2026 dos fallos críticos (CVSS 9,2) que permiten ejecutar código sin autenticación; la única mitigación completa es actualizar a la 8.5.12, 8.4.27, 8.3.36 u 8.2.35, y quien use 8.1 o anterior debe pedir un parche a su proveedor o migrar.

1. Qué pasó#

El 20 de octubre de 2026 el proyecto PHP avisó de un lanzamiento de seguridad urgente para el día siguiente. El 21 de octubre publicó las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35, que corrigen dos vulnerabilidades críticas que permiten ejecución remota de código sin autenticación. Los medios las llaman PHP2Shell.

Fecha (2026)Hecho
20 de octubrePHP anuncia un lanzamiento de seguridad para el 21 de octubre a las 14:00 UTC, con dos fallos críticos (CVSS 9.2), y se reserva adelantarlo si los detalles se hacen públicos
Antes de los parchesEl director técnico de Cloudflare dijo que ya veían ataques tempranos contra ambos fallos; sus reglas de WAF eran temporales
21 de octubreSalen PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, con los avisos publicados en el repositorio de PHP
21 a 22 de octubreQualys informa que a las 12 horas solo 199.000 de 155 millones de instalaciones con versión conocida estaban parcheadas

Hay señales de explotación: Cloudflare dijo que ya veía ataques tempranos contra ambos fallos antes de los parches, y PHP describe un exploit demostrado en Apache con mod_php. El Centro Nacional de Ciberseguridad del Reino Unido pidió actualizar de inmediato o desconectar los sistemas afectados.

Las fuentes difieren en un detalle: los avisos y la página de noticias de PHP fechan los lanzamientos el 21 de octubre, mientras que el registro de cambios de php.net muestra la fecha del 22 para la 8.5.12 y la 8.4.27. Usamos el 21, que es la fecha de los avisos.

Documentación: PHP: archivo de noticias de 2026 ↗

2. Las dos vulnerabilidades#

Ambas tienen CVSS v4.0 de 9,2 (crítica). Según BleepingComputer, fueron descubiertas por Calif, OpenAI y Wiz. Se basan en el mismo problema de fondo: PHP deja memoria corrupta cuando una petición termina de forma anormal.

DatoCVE-2026-109618CVE-2026-109619
AvisoGHSA-w8hw-w9fx-j79wGHSA-6wmf-4rv5-p3rp
Nombre del avisoRCE por corrupción de memoria al quedarse sin memoria (OOM)RCE por estado global obsoleto
CVSS v4.09,2 crítica (AV:N/AC:H/AT:P/PR:N/UI:N)9,2 crítica (AV:N/AC:H/AT:P/PR:N/UI:N)
MecanismoPHP sale de un error de memoria con longjmp() y deja datos de la petición a medio inicializar que el cierre trata como válidosEstado global de una petición sobrevive a su memoria liberada y una petición posterior del mismo worker lo usa antes de reiniciarlo
Impacto confirmadoEjecución remota de código sin autenticación con los permisos del worker webUse-after-free, filtración de memoria y ejecución remota de código sin autenticación
Dónde se confirmóApache mod_php con límites por defectomod_php (trazas de pila fatales de PHP 8.5) y mod_php y PHP-FPM (progreso de subida de sesión)

El primer fallo se activa al quedarse sin memoria. Los avisos describen varias formas de empujar una petición a ese estado sin salir de los límites aparentes: peticiones multipart sin una longitud declarada utilizable, un número ilimitado de encabezados por parte y campos de archivo vacíos con nombres anidados. El segundo necesita dos peticiones atendidas por el mismo worker: una que deja el estado obsoleto y otra que lo usa.

El aviso aclara que el éxito del exploit depende de la compilación de PHP, las extensiones y la disposición de la memoria, por lo que es más difícil en unos entornos que en otros. Eso no lo hace seguro: los investigadores demostraron ejecución de código con límites por defecto.

Documentación: Aviso GHSA-w8hw-w9fx-j79w (CVE-2026-109618) ↗ · Aviso GHSA-6wmf-4rv5-p3rp (CVE-2026-109619) ↗

3. A quién afecta#

Afectan a todas las versiones por debajo de 8.2.35, 8.3.36, 8.4.27 y 8.5.12. Qualys y la prensa incluyen en el riesgo a cualquier instalación que atienda peticiones web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP y LiteSpeed.

Rama de PHPVersión corregidaEstado
8.58.5.12Con soporte
8.48.4.27Con soporte
8.38.3.36Con soporte
8.28.2.35Termina su vida útil el 31 de diciembre de 2026
8.1, 8.0 y 7.4Sin versión corregida oficialFuera de soporte; PHP ofrece parches de código fuente para 7.4, 8.0 y 8.1

El caso más urgente es Apache con mod_php: el aviso describe un exploit que se dispara antes de que corra el código de la aplicación. En PHP-FPM el primer fallo no está demostrado de forma completa, pero PHP validó ejecución de código por la vía de la sesión. La línea de comandos no se menciona.

Las ramas 8.1, 8.0 y 7.4 no reciben actualizaciones del proyecto; PHP ofrece parches de código fuente que debe aplicar tu proveedor. Qualys estima que de 167 millones de instalaciones de PHP que analizó, el 71 % usa versiones sin soporte (de 5.4 a 8.1). Es una cifra de un fabricante de seguridad: úsala como orden de magnitud.

Documentación: Qualys: PHP2Shell, cómo encontrar, mitigar y parchear ↗ · BleepingComputer: parches de emergencia para PHP2Shell ↗

4. Cómo saber si estás afectado#

Mira la versión que sirve las peticiones web, no la que ves en tu terminal: Qualys advierte que php -v puede mostrar una instalación distinta de la que atiende el sitio. Revisa también los contenedores, las ramas paralelas y el PHP que traen los paneles de hosting.

bash
# Versión que sirve las peticiones web (no la del terminal): compara con la del proceso en ejecución
php -v
php-fpm -v || php-fpm8.4 -v
apache2ctl -M 2>/dev/null | grep -i php        # ¿mod_php cargado?
ps aux | grep -E "php-fpm|apache2|httpd|frankenphp" | grep -v grep

# Contenedores: la imagen que corre, no la que tienes en el portátil
docker ps --format "{{.Names}} {{.Image}}"
docker exec NOMBRE php -v

# Tras actualizar: reiniciar de verdad los procesos que atienden peticiones
sudo systemctl restart php8.4-fpm    # o apache2 si usas mod_php
Comandos de referencia; esta guía no los ejecuta porque dependen de tu servidor.

El script compara una versión con las corregidas. Si usas un paquete de una distribución, el número puede seguir siendo antiguo aunque tenga el parche: consulta el aviso de tu proveedor.

python
import re

CORREGIDAS = {(8, 5): 12, (8, 4): 27, (8, 3): 36, (8, 2): 35}   # parche menor corregido por rama

def parsear(version):
    return tuple(int(n) for n in re.findall(r"\d+", version)[:3])

def estado(version):
    mayor, menor, parche = parsear(version)
    if (mayor, menor) in CORREGIDAS:
        minimo = CORREGIDAS[(mayor, menor)]
        if parche >= minimo:
            return "corregida"
        return f"VULNERABLE: actualiza a {mayor}.{menor}.{minimo}"
    if (mayor, menor) > (8, 5):
        return "rama más nueva que las corregidas: revisa los avisos"
    return "SIN VERSION CORREGIDA OFICIAL: pide un build con el parche a tu proveedor o migra"

for v in ["8.5.11", "8.5.12", "8.4.26", "8.4.27", "8.3.36", "8.2.34", "8.1.31", "7.4.33"]:
    print(v, "->", estado(v))
Imprime el estado de ocho versiones: 8.5.11, 8.4.26 y 8.2.34 vulnerables, 8.5.12, 8.4.27 y 8.3.36 corregidas, y 8.1.31 y 7.4.33 sin versión corregida oficial.

5. Cómo parchear#

  • Actualiza a la 8.5.12, 8.4.27, 8.3.36 u 8.2.35 según tu rama. Si estás en 8.1 o anterior, pide a tu proveedor un build con el parche o migra a una rama con soporte.
  • Reinicia los procesos que atienden peticiones (PHP-FPM, Apache, FrankenPHP): actualizar el paquete no basta hasta que los workers cargan la versión nueva.
  • En contenedores, reconstruye la imagen sobre una base con la versión corregida y vuelve a desplegar.
  • En hosting compartido o con panel (Plesk, cPanel), confirma con el proveedor que ya aplicó el parche.
  • Si PHP 8.2 es tu rama, planifica la migración: llega al final de su vida útil el 31 de diciembre de 2026.

Para profundizarParches de seguridad de octubre de 2026: Next.js 16.4.1 y PgBouncer 1.26.1

6. Si no puedes parchear hoy: mitigaciones temporales#

PHP publica ajustes que reducen la exposición, pero insiste en que no hacen seguro un sistema sin parchear: la única mitigación completa es actualizar. Deben aplicarse de forma administrativa (php.ini, el pool de FPM o la configuración del servidor), no con ini_set() ni .user.ini, y hay que reiniciar los workers.

AjusteValorProtege de
memory_limit-1, fijado con php_admin_valueCVE-2026-109618
post_max_size8M sin subidas; 32M con subidasCVE-2026-109618
upload_max_filesizeMenor que post_max_sizeCVE-2026-109618
session.upload_progress.enabled0 en php.ini, el pool de FPM o el servidor; no con ini_set() ni .user.iniCVE-2026-109619
fatal_error_backtraces0, solo en PHP 8.5CVE-2026-109619 (la vía confirmada de PHP 8.5)
pm.max_requests1, solo en FPM y con costo de rendimientoCVE-2026-109619
python
import re

def a_mb(valor):
    m = re.fullmatch(r"(\d+)\s*([KMG]?)", valor.strip().upper())
    if not m:
        return None
    return int(m.group(1)) * {"": 1 / 1024**2, "K": 1 / 1024, "M": 1, "G": 1024}[m.group(2)]

def auditar(ini, version):
    """Revisa las mitigaciones temporales que PHP lista; no sustituyen al parche."""
    cfg = dict(l.split("=", 1) for l in (x.split(";")[0].strip() for x in ini.splitlines()) if "=" in l)
    cfg = {k.strip(): v.strip() for k, v in cfg.items()}
    faltan = []
    if cfg.get("memory_limit") != "-1":
        faltan.append("memory_limit = -1 (fijado como php_admin_value)")
    limite = a_mb(cfg.get("post_max_size", "8M"))
    if limite is None or limite > 32:
        faltan.append("post_max_size <= 32M (8M si no hay subidas)")
    if cfg.get("session.upload_progress.enabled", "1").lower() not in ("0", "off"):
        faltan.append("session.upload_progress.enabled = 0")
    if parsear(version)[:2] == (8, 5) and cfg.get("fatal_error_backtraces", "1").lower() not in ("0", "off"):
        faltan.append("fatal_error_backtraces = 0 (solo PHP 8.5)")
    return faltan

def parsear(version):
    return tuple(int(n) for n in re.findall(r"\d+", version)[:3])

parcial = "memory_limit = -1\npost_max_size = 8M ; sin subidas\nsession.upload_progress.enabled = 0\n"
print(auditar(parcial, "8.4.26"))
print(auditar(parcial, "8.5.11"))
print(auditar("memory_limit = 128M\npost_max_size = 64M\n", "8.3.35"))
Revisa las mitigaciones de las dos vulnerabilidades en un archivo de configuración. Con el ejemplo imprime una lista vacía, la que falta en PHP 8.5, y las tres que faltan en una configuración sin endurecer.

Dos advertencias del aviso: no uses límites de proceso RLIMIT_AS ni RLIMIT_DATA, porque pueden activar justo la ruta vulnerable, y ocultar errores con error_reporting, display_errors o el operador @ no ayuda. Además, memory_limit = -1 solo sirve si ninguna aplicación puede volver a fijar un límite finito.

7. Después de parchear#

Qualys informa que los investigadores demostraron la filtración de memoria de los workers sin autenticación, lo que puede exponer contraseñas, tokens y claves de API. Si tu servidor estuvo expuesto con una versión vulnerable, trata los secretos que pasaron por PHP como posiblemente comprometidos.

  • Rota las credenciales de base de datos, las claves de API y los tokens de sesión que manejaba esa aplicación.
  • Revisa los registros del servidor y de PHP desde el 20 de octubre: peticiones multipart extrañas o muy grandes, errores fatales repetidos y reinicios de workers.
  • Busca archivos nuevos o modificados en el directorio web y en carpetas de subida.
  • Mantén una regla de WAF que limite o bloquee multipart donde no lo uses, como medida adicional, no como sustituto del parche.
  • Anota la fecha y la versión en que parcheaste cada servidor.

Estas recomendaciones son de buena práctica, no del aviso de PHP; adáptalas a tu entorno y a tu equipo de seguridad.

8. Mantén tus cifras al día#

Las versiones, los identificadores y las mitigaciones son las de los avisos publicados hasta el 22 de octubre de 2026. Pueden aparecer nuevos avisos y detalles de exploración; revisa el repositorio de seguridad de PHP y el aviso de tu distribución.

  • Suscríbete a los avisos de seguridad de PHP y de tu proveedor.
  • Mantén un inventario de qué versión de PHP corre en cada servidor y contenedor.
  • Automatiza una alerta cuando una versión quede por debajo de la corregida.

Fuentes y alcance

Documentación consultada el 22 de octubre de 2026. Los ejemplos y criterios de decisión son propuestas editoriales; adáptalos al contrato de tu aplicación y valídalos en tu entorno de pruebas autorizado.

Compara estas opciones

Compara soluciones cloud

Revisa tarifas, límites, condiciones y fuentes de cada opción.

Abrir comparador
Asesoría

¿Tu caso es distinto?

Cuéntanos tu contexto y las opciones que estás evaluando. Te respondemos con criterios y fuentes, sin suscripciones automáticas.

Solicita asesoría