Saltearse al contenido

HTTP Request Smuggling

Cuando una petición pasa por un front-end (proxy, CDN, load balancer) antes de llegar al back-end, ambos tienen que coincidir en dónde termina una petición y empieza la siguiente. Si discrepan al interpretar la longitud del cuerpo, el atacante “cuela” parte de su petición en el principio de la petición del siguiente usuario. Eso es request smuggling: envenenar la cola de peticiones compartida.

flowchart LR
    A[Atacante] -->|"petición ambigua (CL.TE / TE.CL)"| F[Front-end]
    F -->|"la ve como una"| B[Back-end]
    B -. "la back-end la divide en dos (desync)" .-> V["Prefijo inyectado en la<br/>siguiente petición de otra víctima"]

El bug no está en una máquina, está en el desacuerdo entre dos. El front reenvía por una conexión keep-alive al back, y si uno cuenta el cuerpo por Content-Length y el otro por Transfer-Encoding: chunked, una petición cuidadosamente malformada se parte de forma distinta en cada lado. El resto de la petición “sobrante” se antepone a la de la víctima que use esa misma conexión.

Según qué cabecera prioriza cada extremo:

  • CL.TE: el front usa Content-Length, el back usa Transfer-Encoding.
  • TE.CL: el front usa Transfer-Encoding, el back usa Content-Length.
  • TE.TE: ambos soportan Transfer-Encoding pero uno se puede ofuscar para que lo ignore (Transfer-Encoding: xchunked, espacios, doble cabecera).
POST / HTTP/1.1
Host: target
Content-Length: 6
Transfer-Encoding: chunked
0
G

Si el back prioriza chunked, ve la petición terminada en 0\r\n\r\n y la G queda al principio del buffer → se antepone a la siguiente petición (GPOST ...).

  • Detección por timing: una petición CL.TE/TE.CL malformada hace que el back espere bytes que nunca llegan → retardo medible. Es la técnica de Burp.
  • Prueba ofuscaciones de Transfer-Encoding: espacio antes de :, tab, \n como separador, doble TE, valor con mayúsculas raras.
  • HTTP/2 → HTTP/1.1 downgrade: el front habla H2 y traduce a H1 al back; Content-Length/chunked inconsistentes o cabeceras que H2 permite y H1 no (H2.CL, H2.TE, CRLF en valores).

Una vez confirmado el desync:

  • Robo de peticiones de otros usuarios: smuggle un prefijo que capture la siguiente petición (con su cookie) y la refleje a un endpoint que controlas.
  • Bypass de controles del front: el front filtra /admin, pero smuggleas una petición a /admin que el front no inspecciona.
  • Response queue poisoning: desalineas peticiones y respuestas → un usuario recibe la respuesta de otro.
  • Cache poisoning encadenado: smuggling + caché envenena respuestas para todos.
  • Conversión de XSS/open redirect en algo que afecta a víctimas sin interacción.
# CL.TE conceptual: prefijo que queda en cola para la víctima
POST / HTTP/1.1
Host: target
Content-Length: 4
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
X-Ignore: X
  • Burp Suite — extensión HTTP Request Smuggler (James Kettle): detección por timing, probe de desync, H2 downgrade.
  • Turbo Intruder — para enviar las peticiones con control fino del framing.
  • h2csmuggler — para desync vía HTTP/2 cleartext upgrade.

Secuestro de sesiones de otros usuarios, bypass de autenticación/autorización del front, envenenamiento de caché masivo, exfiltración de credenciales en tránsito.

  • Peticiones con ambas Content-Length y Transfer-Encoding.
  • Transfer-Encoding ofuscado (espacios, valores no estándar, duplicado).
  • Respuestas que no cuadran con la petición del cliente; usuarios viendo datos ajenos.

Loguea cabeceras de framing crudas; alerta sobre CL+TE simultáneos y sobre TE malformado.

  • Usa HTTP/2 de extremo a extremo sin downgrade a HTTP/1.1 en el salto interno (elimina la clase entera cuando se mantiene H2).
  • Normaliza/rechaza en el front peticiones con CL+TE o TE ambiguo; una sola interpretación en toda la cadena.
  • Front y back con el mismo servidor/versión y config de parsing; deshabilita el reuso de conexión back-end si no es seguro.
  • Rechaza cabeceras duplicadas y valores no conformes a RFC 7230.
  • WAF/reverse-proxy actualizados (muchos parches de smuggling son de config/versión).

Invalida caché, rota sesiones afectadas, parchea/alinea el parsing de front y back, deshabilita keep-alive hacia el back si es necesario.

  • James Kettle — “HTTP Desync Attacks” (2019) y “HTTP/2” (2021) — investigación fundacional; afectó a grandes CDNs y a miles de sitios.
  • CVE-2019-18277 (HAProxy), CVE-2021-33193 (Apache mod_http2) — smuggling en servidores/proxys populares.
  • Netflix, PayPal y otros — desync críticos divulgados en la investigación de HTTP Request Smuggling de James Kettle (PortSwigger).
  • Múltiples avisos de Varnish, Squid, nginx y balanceadores por discrepancias de framing.
  • ¿El front reenvía al back por keep-alive? (prerequisito)
  • ¿Detección por timing (CL.TE / TE.CL) muestra desync?
  • ¿Ofuscar Transfer-Encoding cambia la interpretación? (TE.TE)
  • ¿Hay downgrade HTTP/2→HTTP/1.1 con CL/TE inconsistente? (H2.CL/H2.TE)
  • ¿Se puede anteponer una petición a la de otro usuario?
  • ¿Se saltan controles del front (/admin) por smuggling?
  • ¿El framing (CL+TE) se rechaza o se normaliza en el front?