needhelp
← Volver al blog

NGINX Rift (CVE-2026-42945): Un desbordamiento de montón de 18 años en el módulo de reescritura

por xingwangzhe
NGINX
CVE
Seguridad
RCE
Desbordamiento de Montón
Servidor Web

NGINX Rift (CVE-2026-42945, CVSS 9.2): Un desbordamiento crítico de búfer en el montón en el módulo de reescritura de NGINX, descubierto autónomamente por el sistema de análisis de IA de depthfirst. Introducido en 2008 y afectando 18 años de versiones de NGINX, permite a un atacante no autenticado lograr ejecución remota de código con una sola solicitud HTTP manipulada.


La Vulnerabilidad Que Estaba Oculta a Plena Vista

El 13 de mayo de 2026, F5 y depthfirst divulgaron conjuntamente CVE-2026-42945 — un desbordamiento crítico de búfer en el montón en ngx_http_rewrite_module de NGINX. La vulnerabilidad había estado en el código fuente desde 2008, introducida en NGINX 0.6.27, afectando cada versión posterior hasta 1.30.0.

Lo que hace que este descubrimiento sea particularmente notable es cómo se encontró: no por un investigador humano auditando código manualmente, sino por el sistema autónomo de análisis de vulnerabilidades de depthfirst. El sistema de IA fue dirigido al código fuente de NGINX, y en seis horas marcó el problema de desbordamiento de montón que había eludido la detección humana durante 18 años.

MétricaValor
CVECVE-2026-42945
CVSS v4.09.2 (Crítico)
Descubierto pordepthfirst (análisis autónomo de IA)
Introducido2008 (NGINX 0.6.27)
Oculto durante18 años
Tipo de vulnerabilidadDesbordamiento de búfer en montón (discrepancia de longitud en dos pasos)
Autenticación requeridaNinguna
ImpactoEjecución remota de código (RCE) o caída del worker (DoS)
Versión corregidaNGINX 1.31.0 / 1.30.1

Versiones Afectadas

La vulnerabilidad abarca casi todas las líneas de productos de NGINX:

ProductoVersiones Afectadas
NGINX Open Source0.6.27 hasta 1.30.0
NGINX PlusR32 hasta R36
NGINX Instance Manager2.16.0 hasta 2.21.1
F5 NGINX App Protect WAF4.9.0–4.16.0, 5.1.0–5.8.0
NGINX Ingress Controller3.5.0–3.7.2, 4.0.0–4.0.1, 5.0.0–5.4.1
NGINX Gateway Fabric1.3.0–1.6.2, 2.0.0–2.5.1

Dado que NGINX impulsa aproximadamente un tercio de todos los sitios web a nivel mundial, el radio de explosión de esta vulnerabilidad es enorme.


Inmersión Técnica Profunda

El Diseño de Dos Pasos

Para entender el bug, necesitas entender el motor de scripts de NGINX. Cuando NGINX evalúa una directiva rewrite o set, opera en dos pasos:

  1. Paso de longitud (ngx_http_script_len_code): Calcula el tamaño total del búfer necesario para contener la salida final
  2. Paso de copia (ngx_http_script_run / ngx_http_script_copy_code): Asigna un búfer de ese tamaño y escribe los datos reales

El contrato es simple: el paso 1 te dice exactamente cuántos bytes asignar, el paso 2 escribe exactamente esa cantidad de bytes. Si los dos no coinciden — obtienes un desbordamiento de montón.

Causa Raíz: La Bandera is_args Huérfana

La vulnerabilidad vive en src/http/ngx_http_script.c. Cuando la cadena de reemplazo de una directiva rewrite contiene un signo de interrogación (?), la función ngx_http_script_start_args_code establece una bandera en el motor de scripts:

e->is_args = 1;

Esta bandera señala que los componentes URI subsiguientes deben tratarse como argumentos de consulta y escaparse URI (ej. +%2B, &%26).

El problema: esta bandera nunca se restablece. Permanece establecida en el motor de scripts principal (e) durante el resto del procesamiento de la solicitud.

La Discrepancia

Cuando una directiva set subsiguiente referencia un grupo de captura de regex (ej. $1), el motor de scripts lo evalúa. Durante el paso de longitud, ngx_http_script_complex_value_code crea un submotor fresco puesto a cero (le):

ngx_http_script_len_code_ctx_t  le;
ngx_memzero(&le, sizeof(ngx_http_script_len_code_ctx_t));

Dado que le.ip y le.is_args son ambos cero, la función de cálculo de longitud ngx_http_script_copy_capture_len_code toma la rama else — devuelve la longitud de captura cruda, sin escapar.

Durante el paso de copia, el código se ejecuta en el motor principal (e), donde e->is_args sigue siendo 1. La función de copia ngx_http_script_copy_capture_code entra en una rama diferente:

if (e->is_args) {
    // Escapa la URI: expande + % & de 1 byte a 3 bytes
    n = ngx_escape_uri(NULL, src, len, NGX_ESCAPE_ARGS);
    // ...asigna y escribe la versión escapada
}

Cada carácter escapable en la URI controlada por el atacante (+, %, &) se expande de 1 byte a 3 bytes. El búfer se dimensionó para la longitud cruda (sin escapar) — la escritura sobrepasa la asignación.

// Paso de longitud mide:   raw_len bytes
// Paso de copia escribe:   raw_len + 2*N bytes  (donde N = caracteres escapables)
//                            ↑↑↑  DESBORDAMIENTO DE MONTÓN

Esta es una violación clásica del contrato de dos pasos, posible porque el estado is_args fue establecido por una directiva rewrite completamente no relacionada y nunca se limpió.

Explotación

Los investigadores de depthfirst desarrollaron una prueba de concepto funcional que demuestra RCE no autenticada contra NGINX con ASLR desactivado. Las propiedades clave que hacen práctica la explotación:

PropiedadDetalle
Tamaño del desbordamientoTotalmente controlado por el atacante (número de +, &, % en URI)
Datos del desbordamientoControlados por el atacante (contenido URI escapado)
ReproducibilidadDeterminista — la misma solicitud siempre desborda de la misma manera
Presupuesto de reintentosInfinito — los workers caídos se regeneran con el mismo diseño de montón
AutenticaciónNinguna requerida — accesible desde internet público

El presupuesto infinito de reintentos es particularmente importante para eludir ASLR. La explotación moderna contra ASLR típicamente requiere fuga de información o fuerza bruta. Debido a que NGINX genera workers de reemplazo con un diseño de montón idéntico después de cada caída, un atacante puede hacer intentos ilimitados sin costo.

Los investigadores describen una técnica teórica: sobrescribiendo progresivamente bytes de puntero a través de solicitudes repetidas, un atacante puede redirigir el flujo de ejecución a un payload controlado, derrotando a ASLR sin un paso explícito de fuga de información.


Condición de Disparo: ¿Estás Afectado?

La vulnerabilidad solo es alcanzable si tu configuración de NGINX contiene un patrón específico:

# Patrón vulnerable:
# 1. Un rewrite con ? en reemplazo Y grupos de captura sin nombre
# 2. Seguido de otro rewrite, if, o set en el mismo ámbito

rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;

El ? en /profile.php?id=$1&tab=$2 establece is_args = 1. Las capturas sin nombre $1, $2 activan la ruta de código vulnerable cuando una directiva subsiguiente las evalúa.

Verifica Tu Configuración

grep -rn 'rewrite.*\?.*\$[0-9]' /etc/nginx/

Si esto devuelve alguna coincidencia, tu configuración está afectada.


Mitigación

Inmediato: Actualizar

VersiónAcción
NGINX Open SourceActualizar a 1.31.0 o 1.30.1
NGINX Plus R36Aplicar R36 P4
NGINX Plus R32Aplicar R32 P6

Solución Alternativa: Grupos de Captura Nombrados

Si no puedes actualizar inmediatamente, reemplaza las capturas sin nombre con capturas nombradas en cada directiva rewrite afectada:

# Vulnerable — capturas sin nombre con ? en reemplazo
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;

# Mitigado — capturas nombradas evitan la ruta de código vulnerable
rewrite ^/users/(?<user_id>[0-9]+)/profile/(?<section>.*)$ /profile.php?id=$user_id&tab=$section last;

Las capturas nombradas ((?<name>...)) no pasan por la lógica de escape vulnerable, porque la función ngx_http_script_copy_capture_code solo aplica escape URI a capturas sin nombre. Este cambio de configuración elimina la superficie de ataque sin una actualización binaria.

Verificar la Corrección

# Verificar versión
nginx -v

# Después de actualizar, verificar: debe ser 1.31.0 o 1.30.1+
nginx -v 2>&1 | grep -E '1\.31\.0|1\.30\.[1-9]'

Línea de Tiempo

FechaEvento
2008Vulnerabilidad introducida en NGINX 0.6.27 (commit de inicialización del módulo de reescritura)
2026-04Sistema autónomo de depthfirst escanea código fuente de NGINX, marca desbordamiento de montón en 6 horas
2026-04-24F5 confirma el problema y coordina la divulgación
2026-05-13F5 publica NGINX 1.31.0 / 1.30.1 con corrección; CVE-2026-42945 publicado
2026-05-14Este artículo publicado

Implicaciones Más Amplias: Vulnerabilidades Descubiertas por IA

CVE-2026-42945 es notable no solo por su gravedad, sino por cómo fue descubierto. Un sistema de IA autónomo encontró un bug en un código fuente que ha sido auditado por miles de ingenieros, investigadores de seguridad y contribuyentes de código abierto durante 18 años — en seis horas.

Esto sigue un patrón que hemos visto acelerarse en 2026:

VulnerabilidadDescubierto porTiempo en encontrar
Copy Fail (LPE kernel Linux)Xint Code (IA)~1 hora
Dirty Frag (LPE kernel Linux)Humano (Hyunwoo Kim)Auditoría manual
CVE-2026-42945 (NGINX Rift)depthfirst (IA autónoma)6 horas
CVE-2026-42946 (sobrelectura NGINX)depthfirst (IA autónoma)Mismo escaneo

La brecha entre lo que un sistema de IA determinado puede encontrar y lo que los revisores humanos han capturado históricamente está creciendo rápidamente. Para los mantenedores de infraestructura crítica, esto significa:

  1. Asume que hay más bugs sin descubrir en tus dependencias — los encontrados hasta ahora son solo lo que la generación actual de herramientas de IA puede capturar
  2. Minimiza la superficie de ataque — elimina módulos no utilizados, desactiva características innecesarias, usa el principio de mínima funcionalidad
  3. Defensa en profundidad — incluso si un componente se compromete, otras capas deberían limitar el radio de explosión

NGINX mismo es un caso interesante: es conocido por su código fuente limpio y su sólido historial de seguridad. Y sin embargo, un RCE crítico de 18 años estaba oculto a plena vista. Si NGINX no está a salvo de esta clase de bug, ningún código fuente en C lo está.


Conclusión

CVE-2026-42945 (NGINX Rift) es un desbordamiento crítico de montón en uno de los proyectos de software más ampliamente desplegados en internet. No requiere autenticación, puede ser activado desde internet público, y le da a un atacante ejecución completa de código en el proceso worker de NGINX.

Si ejecutas NGINX, asume que estás afectado — a menos que hayas verificado que tu configuración no contiene el patrón de rewrite vulnerable, o que hayas actualizado a 1.31.0 / 1.30.1.

La vida útil de 18 años de este bug es un recordatorio contundente: nuestra infraestructura se sostiene con código que nunca ha sido auditado exhaustivamente por herramientas modernas. La era de IA del descubrimiento de vulnerabilidades apenas comienza, y deberíamos esperar más revelaciones como esta — no menos.


Referencias


Infografía

Diagrama de desbordamiento de montón NGINX Rift

Figura 1: NGINX Rift — cómo la discrepancia de longitud del búfer de dos pasos produce un desbordamiento de montón

Compartir esta página