El 15 de julio F5 publicó el parche de CVE-2026-42533, un desbordamiento de heap en NGINX con CVSS v4 de 9.2 (8.1 en CVSS v3.1) que se dispara con una petición HTTP común, sin autenticación. Lo incómodo no es la nota: es el rango afectado. Según los avisos de seguridad publicados en nginx.org, van de la 0.9.6 a la 1.31.2. Es decir, casi todo NGINX que haya corrido en producción en los últimos quince años.
CVE-2026-42533 es un desbordamiento de heap en el motor de scripting de NGINX, parcheado por F5 el 15 de julio de 2026. Se dispara cuando una expresión combina una captura numerada de una regex previa con la salida de un map basado en regex: las dos pasadas del evaluador miden y escriben cantidades distintas. Afecta de NGINX 0.9.6 a 1.31.2 y se corrige en 1.30.4 y 1.31.3.
¿Qué configuración de NGINX es vulnerable a CVE-2026-42533?

Necesitás tres ingredientes juntos: una fuente de capturas por regex (un location ~, un server_name con regex, un rewrite o un if), un map que use expresiones regulares, y una expresión donde la captura numerada ($1, $2) se evalúe antes que la variable de salida del map. Si falta alguno, no hay bug.
El detalle que rompe la intuición de la mayoría: la captura y la variable del map no tienen que estar en la misma directiva. Los módulos corren un único ciclo de medición/escritura sobre todas las directivas del bloque, así que el disparador puede estar repartido:
location ~ "^/api/(.+)$" {
proxy_set_header X-Path "$1";
proxy_set_header X-Check "$map_var";
proxy_pass http://backend;
}Eso descarta el chequeo mental de "yo no mezclo $1 con maps en la misma línea". Y el problema no vive solo en proxy_set_header: el análisis técnico de Stan Shaw (cyberstan), quien reportó la falla, identifica 13 puntos de llamada afectados que cubren alrededor de 50 directivas, entre ellas return, add_header, proxy_pass, fastcgi_param, root/alias, access_log, set e index. También alcanza al módulo stream.
¿Cómo funciona el bug de las dos pasadas en el motor de scripting?
NGINX evalúa cada expresión dos veces: la pasada LEN mide cuánto va a ocupar el resultado para reservar el buffer, y la pasada VALUE escribe. Las dos leen r->captures, un estado mutable compartido de la request. Cuando un map con regex se evalúa en el medio, ngx_http_regex_exec() pisa ese estado, y las dos pasadas terminan trabajando con números distintos.
De ahí salen dos primitivas, y conviene entender que son opuestas:
- Overflow (la captura pisada es más grande que la original). LEN mide poco, VALUE escribe más. En el caso documentado por Shaw, LEN mide 211 bytes y VALUE escribe 408: 197 bytes de heap sobrescritos con contenido que controla el atacante desde el cuerpo del POST.
- Fuga de información (la captura pisada es más chica). LEN reserva 8.161 bytes, VALUE escribe 2, y los 8.159 restantes se devuelven tal cual: residuo de heap sin inicializar, con punteros a libc y al heap adentro.
—"La pasada LEN midió una captura grande y reservó un buffer grande, pero la pasada VALUE escribe apenas unos pocos bytes", explica Shaw en su análisis. Esa asimetría es todo el bug.
La segunda primitiva es la que eleva el caso de "crash del worker" a algo más serio: la fuga entrega justamente las direcciones que hacen falta para sortear ASLR, en la misma petición GET no autenticada. No hace falta una cadena de exploits con un segundo bug de infofuga; el mismo defecto provee las dos mitades.
¿Por qué estuvo 15 años sin que nadie lo viera?
Porque el bug nació con la feature. La versión 0.9.6, del 21 de marzo de 2011, es exactamente la release en la que el changelog de nginx anuncia que "la directiva map soporta expresiones regulares como valor del primer parámetro". La condición de carrera lógica entre las dos pasadas existe desde ese commit; nunca hubo una ventana segura.
El motivo por el que sobrevivió tanto es más interesante que la antigüedad en sí:
- La complejidad de ataque es alta, según la propia clasificación de F5. No alcanza con tener NGINX expuesto: hace falta una combinación de directivas específica. Eso hace que no aparezca en fuzzing genérico contra una config por defecto.
- El síntoma es ambiguo. Un worker que muere y el master reinicia se lee como "pico de tráfico raro" o "backend que se cayó", no como corrupción de memoria. Sin AddressSanitizer no dispara ninguna alarma.
- El disparador está en la configuración del usuario, no en el código. Auditar
ngx_http_script.clínea por línea no muestra nada malo hasta que modelás qué escribe enr->capturesy cuándo.
Vale registrar el patrón más amplio: The Hacker News señala que este es el tercer heap overflow en el código de evaluación de expresiones de NGINX en dos meses, después de CVE-2026-42945 (mayo) y CVE-2026-9256 en el módulo rewrite. No es un accidente aislado: es un subsistema que está recibiendo atención concentrada de investigadores por primera vez en su historia.
¿Qué versiones de NGINX corrigen CVE-2026-42533?
Actualizá a 1.30.4 (stable) o 1.31.3 (mainline) en NGINX Open Source. En NGINX Plus, a 37.0.3.1 o R36 P7. No hay versión intermedia parcheada: todo lo anterior en cada rama está afectado.
| Producto | Afectado | Corregido en |
|---|---|---|
| NGINX OSS stable | 0.9.6 – 1.30.3 | 1.30.4 |
| NGINX OSS mainline | hasta 1.31.2 | 1.31.3 |
| NGINX Plus | R33–R36 / 37.0.0.1–37.0.2.1 | R36 P7 / 37.0.3.1 |
Dos precisiones importantes:
- El número de versión de tu paquete no va a coincidir con esos. Debian y Ubuntu backportean el parche sobre la versión que ya empaquetan, así que un
nginx -vque diga 1.24 o 1.26 no significa nada por sí solo. Hay que mirar la revisión del paquete y el aviso de la distro — en Ubuntu, la ficha del CVE lista el estado por release y las USN correspondientes. - La misma release cerró otros dos CVEs. CVE-2026-60005 (divulgación de memoria en
ngx_http_slice_module, desde 1.15.8) y CVE-2026-56434 (use-after-free enngx_http_ssi_module, desde 0.8.11), ambos de severidad media. Para el use-after-free de SSI no hay workaround: solo parche.
¿Cómo verifico hoy si mi servidor está en riesgo?
Empezá por volcar la configuración efectiva con nginx -T, que expande todos los include, y buscá si conviven maps con regex y capturas numeradas. Es un triage rápido, no un veredicto:
# versión real del binario en ejecución
nginx -v
# maps declarados (mirá si el primer parámetro usa ~ o ~*)
nginx -T 2>/dev/null | grep -nE '^\s*map\s+'
# fuentes de capturas numeradas
nginx -T 2>/dev/null | grep -nE 'location\s+~|server_name\s+~|rewrite\s+|if\s+\('Si las dos búsquedas devuelven resultados, asumí que estás en el rango de riesgo y pasá al análisis serio. Shaw publicó un escáner estático de configuración —CVE-2026-42533-Config-Scanner, en su repositorio de GitHub— que sigue los includes, contempla el disparo entre directivas distintas, distingue el orden explotable del orden seguro y saca salida JSON. Es análisis estático, no explotación: se puede correr sobre un config en CI sin tocar el servidor.
Un detalle operativo que se pasa por alto seguido: un nginx -s reload no carga el binario nuevo. El reload le pide al master en ejecución que levante workers con la config actualizada, pero el proceso master sigue siendo el binario viejo. Después de actualizar el paquete hay que reiniciar el servicio, o hacer el upgrade en caliente con USR2 + WINCH/QUIT al master. Verificá con ps -o etimes= -p $(cat /run/nginx.pid) que el master arrancó después del update.
¿Alcanza con cambiar a capturas nombradas como mitigación?
No del todo. Pasar los maps a capturas nombradas (?P<nombre>...) es el workaround que recomienda el aviso de F5 y cierra el camino principal, pero deja una variante abierta. Las capturas nombradas escriben en r->variables[] en vez de r->captures[], y ahí se puede reproducir el mismo pisado cuando un map define grupos nombrados idénticos a los de la regex del location.
Shaw dice haber confirmado esa variante con AddressSanitizer y apunta que el aviso de F5 no la menciona. Su observación sobre cualquier arreglo parcial es directa: un fix que guarde y restaure r->captures no cubre este segundo camino. La corrección real que entró en 1.30.4/1.31.3 no hace snapshot del estado sino bounds checking en la pasada VALUE: el motor recibe un puntero end con el límite del buffer y valida antes de cada opcode de escritura. Si la escritura se pasa, devuelve un 500 en lugar de corromper el heap; y la dirección de fuga se cierra calculando el largo realmente escrito.
Traducido a decisión operativa: las capturas nombradas son un puente para ganar horas, no un destino. Si no podés reiniciar NGINX ahora mismo, sirven; si podés parchear, parcheá.
¿Qué implica esto para un cluster de Kubernetes?
Si usás el ingress-nginx de la comunidad, tenés un problema sin salida upstream. El proyecto llegó a end-of-life en marzo de 2026 en la versión 1.15.1 y el repositorio quedó archivado: no hay más releases ni parches de seguridad. El NGINX embebido en esa versión cae dentro del rango vulnerable y no existe una v1.15.2 parcheada.
El agravante es dónde está parado ese proceso. El controlador de ingress termina el tráfico HTTP/HTTPS externo del cluster: el proceso que se corrompe es exactamente el que rutea todo lo que entra hacia los workloads de atrás. Y las plantillas de configuración que genera un ingress controller a partir de anotaciones producen justamente el patrón riesgoso —locations con regex más maps— sin que nadie haya escrito esa combinación a mano.
También están en la lista NGINX Ingress Controller (3.5.0–5.4.2), Gateway Fabric, App Protect WAF (4.9.0–5.8.0) e Instance Manager (2.16.0–2.22.0). Revisá el aviso del producto puntual, no solo la versión de NGINX que reporta el contenedor.
Preguntas frecuentes
¿Hay explotación activa de CVE-2026-42533?
No hay explotación confirmada en la práctica. Al 20 de julio de 2026 no había código de exploit público ni reportes de uso en la naturaleza, y el CVE no figura en el catálogo KEV de CISA. Shaw afirma haber logrado ejecución de código en pruebas propias sobre Ubuntu 24.04 con tasa de éxito de 10 sobre 10, pero retiene los detalles.
¿Cuándo se publica el exploit funcional?
Shaw anunció que publica la PoC y los detalles completos de explotación 21 días después del parche, lo que ubica la ventana a principios de agosto de 2026. El escáner de configuración ya es público desde antes.
¿El impacto confirmado es RCE o denegación de servicio?
El impacto confirmado por F5 es denegación de servicio: crash y reinicio del worker. La ejecución remota de código es posible bajo condiciones específicas y hasta ahora está sostenida por el investigador, no validada públicamente por el fabricante.
¿Un WAF me protege mientras parcheo?
No de forma confiable. La petición que dispara el bug es HTTP legítimo —una URI que matchea tu propia regex— sin payload reconocible por firma; lo que la vuelve peligrosa es la configuración del servidor, no el contenido. Ni el aviso de F5 ni el análisis del investigador proponen reglas de WAF como mitigación: proponen parche o capturas nombradas.
¿Me afecta si uso un fork de nginx?
Probablemente sí, porque el código del motor de scripting es heredado del upstream. Revisá el aviso de seguridad del fork específico y su versión parcheada; no asumas que un número de versión más alto implica el fix. Si te interesa el tema de los forks, tenemos una nota sobre Angie 1.11.8 y qué gana y qué pierde respecto de nginx.
¿Qué hago si no puedo actualizar hoy?
Pasá los maps con regex a capturas nombradas y verificá que ningún map defina grupos nombrados iguales a los de la regex del location, que es la variante que el workaround no cubre. Es una medida temporal: programá el parche a 1.30.4 o 1.31.3 dentro de la ventana previa a la publicación de la PoC.