CVE-2026-42945: El RCE de 18 Años Oculto en NGINX
El 13 de mayo de 2026, F5 publicó un advisory para CVE-2026-42945 — un heap buffer overflow en ngx_http_rewrite_module de NGINX que existe desde la versión 0.6.27, publicada en 2008.
18 años de exposición silenciosa. Cada instancia de NGINX con reglas rewrite y directivas set cargaba este bug. Ya hay un proof-of-concept público en GitHub que consigue ejecución remota de código sin autenticación.
CVSS: 9.2 Crítico.
El Bug: Mismatch de Memoria en Dos Pasadas
El motor de scripts interno de NGINX procesa directivas en dos pasadas:
- Pasada de longitud — calcula cuánta memoria asignar
- Pasada de copia — escribe datos en el buffer asignado
La vulnerabilidad es un desajuste de estado entre ambas pasadas.
Cuando una directiva rewrite contiene un signo de interrogación (?), activa permanentemente un flag interno: is_args = 1 en el motor de scripts principal. Este flag cambia cómo se procesan ciertos caracteres URI — específicamente, activa ngx_escape_uri para expandir ciertos bytes de 1 a 3 bytes (percent-encoding).
El problema:
- En la pasada de longitud, NGINX usa un sub-motor inicializado a cero donde
is_args = 0. Calcula el tamaño del buffer sin considerar la expansión por percent-encoding. - En la pasada de copia, el motor principal ejecuta con
is_args = 1.ngx_escape_uriexpande bytes escapables a 3x su tamaño.
Resultado: se escriben más datos de los asignados. Heap buffer overflow clásico.
Pasada longitud: is_args=0 → calcula N bytes necesarios
Pasada copia: is_args=1 → escribe N + (2 × bytes_escapables) → overflow
Por Qué Importa
No es un overflow teórico. Los investigadores de depthfirst lograron ejecución de código fiable y repetible encadenando:
- Manipulación del heap mediante patrones de request controlados
- Spraying de estructuras cleanup falsas via POST bodies
- Explotación de la arquitectura multi-proceso determinista de NGINX
La naturaleza determinista del modelo de procesos de NGINX es clave — hace predecible el layout del heap, convirtiendo un overflow probabilístico en un exploit fiable. El PoC funciona en sistemas con ASLR desactivado; con ASLR activo la explotación es más difícil pero no imposible dado el proceso determinista.
Condiciones de Activación
El patrón de configuración que activa esta vulnerabilidad es común:
server {
location /api {
set $backend "upstream";
rewrite ^/api/(.*)\?(.*)$ /v2/$1?$2 break;
proxy_pass http://$backend;
}
}
Cualquier configuración que combine rewrite (con ? en el patrón o reemplazo) y directivas set es potencialmente vulnerable. Es un patrón estándar en API gateways, reverse proxies y setups de normalización de URLs.
Versiones Afectadas
Todo desde 2008 hasta el parche:
| Producto | Afectado | Parcheado |
|---|---|---|
| NGINX Open Source | 0.6.27 – 1.30.0 | 1.30.1 / 1.31.0 |
| NGINX Plus | R32 – R36 | R36 P1 / R37 |
| NGINX Instance Manager | 2.16.0 – 2.21.1 | 2.21.2 |
| NGINX Ingress Controller | 3.5.0 – 5.4.1 | 3.7.3 / 4.0.2 / 5.4.2 |
| NGINX Gateway Fabric | 1.3.0 – 2.5.1 | 1.6.3 / 2.5.2 |
| F5 WAF for NGINX | 5.9.0 – 5.12.1 | 5.12.2 |
Por Qué Nadie lo Detectó en 18 Años
Este bug es invisible para análisis estático por pattern-matching. Razones:
El overflow depende de estado en runtime. El flag
is_argsse activa por la ejecución de una directiva previa, no por el código en el punto del overflow. Ninguna función individual está “mal” de forma aislada.El patrón two-pass es correcto por diseño. Es una optimización legítima — calcular tamaño, asignar, escribir. El bug es que dos contextos de ejecución diferentes calculan vs. escriben.
El trigger requiere combinaciones específicas de config. No toda instancia NGINX usa
rewrite+setjuntos con?en el patrón. Fuzzing con configs por defecto nunca tocaría este path.Los auditores se centran en la pasada de copia. Si auditas
ngx_escape_uri, hace exactamente lo que debe — encoding correcto. El bug está upstream: el cálculo de longitud usó asunciones diferentes.El patrón two-pass existe en todas partes. No es un diseño exclusivo de NGINX. Cualquier sistema que separe el cálculo de tamaño de la escritura de datos — serializadores, encoders de protocolo, motores de templates — carga el mismo riesgo. La pregunta es si ambas pasadas comparten las mismas asunciones de estado. En NGINX, no era así.
Esta es la clase de vulnerabilidad que el scanning de código con IA (como el nuevo AWS Security Agent) dice detectar — bugs que requieren entender trust boundaries, data flows y estado a través de múltiples contextos de ejecución. Si esas herramientas realmente detectarían esta instancia específica es otra pregunta. El bug requiere trazar un flag activado en la ejecución de una directiva hasta la asignación de memoria de otra directiva distinta — eso es razonamiento de estado multi-paso, no pattern matching.
Acciones Inmediatas
Si ejecutas NGINX (probablemente sí):
- Comprueba tu versión:
nginx -v - Si es inferior a 1.30.1: actualiza ahora
- Audita tus configs buscando el patrón vulnerable:
# Buscar directivas rewrite con ? en el mismo server/location block que set
grep -rn "rewrite" /etc/nginx/ | grep "?"
grep -rn "set \$" /etc/nginx/
Si ambos aparecen en el mismo bloque server o location: estás en el path vulnerable.
Si no puedes parchear inmediatamente:
- Coloca una capa WAF adicional delante de las instancias NGINX afectadas
- Restringe acceso externo a paths que usen patrones rewrite + set
- Monitoriza tamaños anómalos de POST body (el exploit usa POST para heap spraying)
La Lección de Fondo
Dieciocho años. Millones de despliegues. Incontables auditorías de código. Y un RCE crítico vivía en uno de los proyectos open-source más revisados de la historia.
El bug no se escondía en código oscuro. ngx_http_rewrite_module es funcionalidad core. El problema es que la vulnerabilidad abarca dos contextos de ejecución — no existe en ninguna función individual. Hay que entender la máquina de estados para verlo.
Es exactamente el tipo de bug que justifica revisión de seguridad arquitectural sobre SAST por pattern-matching. Herramientas que razonan sobre estado, data flow y contexto de ejecución detectarán lo que grep nunca podrá.
Parchea tu NGINX. Y después piensa en qué más puede estar oculto en tus implementaciones de dos pasadas.
Si te ha resultado útil este análisis, puede que también te interese Harness Engineering: 6 Capas de Defensa para Claude Code — cómo protejo sistemas de agentes IA de exactamente esta clase de vulnerabilidad por state-mismatch.