Request Smuggling in HTTP/2 Downgrades

Reading time: 6 minutes

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

HTTP/2 se considera generalmente inmune al request-smuggling clásico porque la longitud de cada marco DATA es explícita. Esa protección desaparece tan pronto como un proxy de front-end “downgradea” la solicitud a HTTP/1.x antes de reenviarla a un back-end. En el momento en que dos parsers diferentes (el front-end HTTP/2 y el back-end HTTP/1) intentan acordar dónde termina una solicitud y comienza la siguiente, todos los viejos trucos de desincronización regresan, además de algunos nuevos.


Por qué ocurren los downgrades

  1. Los navegadores ya hablan HTTP/2, pero mucha infraestructura de origen heredada aún solo entiende HTTP/1.1.
  2. Los proxies inversos (CDNs, WAFs, balanceadores de carga) por lo tanto terminan TLS + HTTP/2 en el borde y reescriben cada solicitud como HTTP/1.1 para el origen.
  3. El paso de traducción tiene que crear tanto Content-Length y/o Transfer-Encoding: chunked encabezados para que el origen pueda determinar la longitud del cuerpo.

Siempre que el front-end confíe en la longitud del marco HTTP/2 pero el back-end confíe en CL o TE, un atacante puede forzarlos a discrepar.


Dos clases primitivas dominantes

VarianteLongitud del front-endLongitud del back-endCarga útil típica
H2.TEMarco HTTP/2Transfer-Encoding: chunkedIncluir un cuerpo de mensaje chunked adicional cuyo final 0\r\n\r\n no se envía, por lo que el back-end espera la “siguiente” solicitud proporcionada por el atacante.
H2.CLMarco HTTP/2Content-LengthEnviar un CL más pequeño que el cuerpo real, por lo que el back-end lee más allá del límite hacia la siguiente solicitud.

Estos son idénticos en espíritu a los clásicos TE.CL / CL.TE, solo que con HTTP/2 reemplazando uno de los parsers.


Identificando una cadena de downgrade

  1. Usa ALPN en un apretón de manos TLS (openssl s_client -alpn h2 -connect host:443) o curl:
bash
curl -v --http2 https://target

Si * Using HTTP2 aparece, el borde habla H2. 2. Envía una solicitud CL/TE deliberadamente malformada sobre HTTP/2 (Burp Repeater ahora tiene un menú desplegable para forzar HTTP/2). Si la respuesta es un error HTTP/1.1 como 400 Bad chunk, tienes prueba de que el borde convirtió el tráfico para un parser HTTP/1 aguas abajo.


Flujo de explotación (ejemplo H2.TE)

http
:method: POST
:path: /login
:scheme: https
:authority: example.com
content-length: 13      # ignored by the edge
transfer-encoding: chunked

5;ext=1\r\nHELLO\r\n
0\r\n\r\nGET /admin HTTP/1.1\r\nHost: internal\r\nX: X
  1. El front-end lee exactamente 13 bytes (HELLO\r\n0\r\n\r\nGE), piensa que la solicitud ha terminado y reenvía esa cantidad al origen.
  2. El back-end confía en el encabezado TE, sigue leyendo hasta que ve el segundo 0\r\n\r\n, consumiendo así el prefijo de la segunda solicitud del atacante (GET /admin …).
  3. El resto (GET /admin …) se trata como una nueva solicitud en cola detrás de la de la víctima.

Reemplace la solicitud suplantada con:

  • POST /api/logout para forzar la fijación de sesión
  • GET /users/1234 para robar un recurso específico de la víctima

h2c smuggling (actualizaciones en texto claro)

Un estudio de 2023 mostró que si un front-end pasa el encabezado HTTP/1.1 Upgrade: h2c a un back-end que soporta HTTP/2 en texto claro, un atacante puede tunelizar frames HTTP/2 en bruto a través de un borde que solo validó HTTP/1.1. Esto elude la normalización de encabezados, las reglas de WAF e incluso la terminación TLS.

Requisitos clave:

  • El borde reenvía tanto Connection: Upgrade como Upgrade: h2c sin cambios.
  • El origen incrementa a HTTP/2 y mantiene la semántica de reutilización de conexiones que permite la cola de solicitudes.

La mitigación es simple: eliminar o codificar en duro el encabezado Upgrade en el borde, excepto para WebSockets.


CVEs notables del mundo real (2022-2025)

  • CVE-2023-25690 – Las reglas de reescritura de mod_proxy de Apache HTTP Server podrían encadenarse para dividir y suplantar solicitudes. (corregido en 2.4.56)
  • CVE-2023-25950 – Suplantación de solicitudes/respuestas en HAProxy 2.7/2.6 cuando el analizador HTX manejaba incorrectamente las solicitudes en tubería.
  • CVE-2022-41721 – Go MaxBytesHandler causó que los bytes restantes del cuerpo se analizaran como frames HTTP/2, habilitando la suplantación entre protocolos.

Herramientas

  • Burp Request Smuggler – desde v1.26, prueba automáticamente H2.TE/H2.CL y soporte ALPN oculto. Habilite “HTTP/2 probing” en las opciones de la extensión.
  • h2cSmuggler – PoC en Python de Bishop Fox para automatizar el ataque de actualización en texto claro:
bash
python3 h2csmuggler.py -u https://target -x 'GET /admin HTTP/1.1\r\nHost: target\r\n\r\n'
  • curl/hyper – creación de cargas útiles manuales: curl --http2-prior-knowledge -X POST --data-binary @payload.raw https://target.

Medidas defensivas

  1. HTTP/2 de extremo a extremo – eliminar completamente la traducción de degradación.
  2. Fuente única de verdad de longitud – al degradar, siempre genere un Content-Length válido y elimine cualquier encabezado Content-Length/Transfer-Encoding proporcionado por el usuario.
  3. Normalizar antes de enrutar – aplicar la sanitización de encabezados antes de la lógica de enrutamiento/reescritura.
  4. Aislamiento de conexiones – no reutilizar conexiones TCP de back-end entre usuarios; “una solicitud por conexión” derrota a los exploits basados en cola.
  5. Eliminar Upgrade a menos que sea WebSocket – previene el tunelizado h2c.

Referencias

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks