Respuesta rápida: El HTTP Request Smuggling es un ataque que aprovecha que dos servidores encadenados (un front-end y un back-end) interpretan de forma distinta dónde acaba una petición HTTP. Manipulando las cabeceras Content-Length y Transfer-Encoding "cuelas" parte de una petición que el back-end atribuye a la siguiente, permitiendo saltarte controles, envenenar la caché o robar peticiones de otros usuarios.
¿Qué es el HTTP Request Smuggling?
En la web moderna, tu petición casi nunca llega directa al servidor de aplicación. Pasa por una cadena: un proxy inverso, un CDN o un balanceador (el front-end) reenvía las peticiones a uno o varios servidores de aplicación (el back-end), reutilizando la misma conexión para varias peticiones.
El problema aparece cuando el front-end y el back-end discrepan sobre dónde termina una petición. El HTTP permite indicar el fin del cuerpo de dos maneras: con la cabecera Content-Length (cuántos bytes tiene el cuerpo) o con Transfer-Encoding: chunked (el cuerpo se envía por trozos y acaba con un chunk de tamaño cero). Si uno de los servidores hace caso a una cabecera y el otro a la otra, un atacante puede construir una petición ambigua donde parte de sus bytes se interpreta como el principio de la siguiente petición. Eso es el smuggling: contrabandear una petición dentro de otra.
Es una vulnerabilidad de gama alta que suele puntuar como severidad alta o crítica. Su teoría, junto con otras técnicas complejas, la tienes en Academy › Avanzado.
¿Por qué existe este problema?
La raíz está en dos decisiones de diseño de la web moderna que, combinadas, abren la puerta:
- Conexiones keep-alive reutilizadas. Por rendimiento, el front-end no abre una conexión nueva al back-end por cada petición: reutiliza la misma para muchas, una detrás de otra. Eso significa que si el back-end se desincroniza sobre dónde acaba una petición, la siguiente petición de la cola es de otro usuario. Ahí está el potencial de robo.
- Dos formas de delimitar el cuerpo. El estándar HTTP/1.1 dice que
Transfer-Encoding debe tener prioridad sobre Content-Length, y que una petición con las dos cabeceras es ambigua y debería rechazarse. Pero en la práctica, distintos servidores (Nginx, Apache, IIS, CDNs, balanceadores) han implementado esto de formas ligeramente distintas durante años. Esa inconsistencia es la grieta.
Cuando un atacante manda ambas cabeceras a la vez, o una Transfer-Encoding ofuscada, apuesta a que el front-end y el back-end las traten distinto. Si acierta, desincroniza la conexión. Por eso la corrección de fondo pasa por normalizar cómo se parsean estas cabeceras en toda la cadena.
Las tres variantes: CL.TE, TE.CL y TE.TE
La notación describe qué cabecera prioriza cada servidor. El primer término es el front-end; el segundo, el back-end.
CL.TE
El front-end usa Content-Length y el back-end usa Transfer-Encoding. El front reenvía lo que cree que es una petición según su longitud, pero el back la parsea por chunks y "sobra" contenido que trata como el inicio de la siguiente petición.
POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
El front-end, guiándose por Content-Length: 13, envía todo el bloque. El back-end, guiándose por Transfer-Encoding: chunked, ve el 0 como fin del cuerpo y trata SMUGGLED como el comienzo de la siguiente petición.
TE.CL
Al revés: el front-end usa Transfer-Encoding y el back-end usa Content-Length. El bloque contrabandeado se coloca dentro de un chunk, y el back-end —que solo mira la longitud— deja parte fuera para la petición siguiente.
TE.TE
Ambos soportan Transfer-Encoding, pero uno de los dos puede ser inducido a ignorarla ofuscando la cabecera (por ejemplo, Transfer-Encoding : chunked con un espacio raro, mayúsculas alteradas o valores duplicados). Al conseguir que uno la descarte, el escenario degenera en un CL.TE o TE.CL. La clave aquí es la ofuscación de la cabecera. Variantes típicas de ofuscación que un servidor puede procesar y otro ignorar:
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: chunked
Transfer-Encoding: identity
X: X[\n]Transfer-Encoding: chunked
Cada línea explota un detalle de parseo distinto (un espacio antes de los dos puntos, un valor duplicado, un prefijo raro). El objetivo es siempre el mismo: que uno de los dos servidores respete la cabecera y el otro la descarte.
¿Cómo detectar el smuggling?
Detectarlo sin romper el servicio es un arte. Dos enfoques principales:
1. Técnica de timing (temporización). Envías una petición diseñada para que, si hay desincronización, el back-end espere más bytes que nunca llegan y provoque un retardo. Un tiempo de respuesta anómalo (varios segundos frente a milisegundos) delata la vulnerabilidad. Es la técnica más segura para una primera detección porque no envenena a otros usuarios.
2. Técnica diferencial (confirmación). Envías dos peticiones seguidas: la primera contrabandea un prefijo que altera la respuesta de la segunda. Si la segunda petición devuelve algo distinto de lo normal (un error, otra ruta), confirmas la desincronización. Aquí ya hay que tener cuidado: mal hecho, puedes afectar a peticiones de usuarios reales.
Regla de oro ética: en un programa de bug bounty, detecta con timing, confirma con el mínimo impacto posible y nunca lances pruebas que envenenen respuestas de otros usuarios más allá de lo estrictamente necesario para demostrar el fallo. Documenta y para.
¿Cuál es el impacto?
El smuggling es peligroso porque lo que contrabandeas afecta a la conexión compartida, no solo a ti:
- Bypass de controles de seguridad del front-end. Muchos controles (WAF, autenticación, filtros de ruta) viven en el front-end. Si cuelas una petición que el back-end procesa sin pasar por esos controles, te los saltas. Es una vía habitual para llegar a rutas administrativas bloqueadas.
- Envenenamiento de caché. Puedes lograr que la caché almacene una respuesta maliciosa asociada a una URL legítima, sirviéndosela a otros usuarios. Se solapa con el cache poisoning, y encadenar ambos multiplica el impacto.
- Robo de peticiones de otros usuarios. Al contrabandear un prefijo que "captura" la siguiente petición de la cola, puedes hacer que la petición de otra víctima (con sus cookies o tokens) acabe reflejada en una respuesta que tú controlas. Robo de sesión sin tocar el navegador de la víctima.
- Reflected XSS aumentado. Convertir un XSS que requeriría interacción en uno que se sirve a cualquiera que pase por esa conexión.
Esa capacidad de afectar a terceros es lo que sube el severity: no es un fallo que solo te afecta a ti.
¿Cómo probarlo? La extensión de Burp
La herramienta de referencia es HTTP Request Smuggler, la extensión de Burp Suite creada por James Kettle (el investigador que popularizó estas técnicas modernas). Se instala desde el BApp Store y automatiza gran parte del trabajo:
- Interceptas una petición al objetivo con Burp.
- Lanzas el escaneo de smuggling de la extensión (usa detección por timing).
- Si detecta desincronización, te ayuda a construir el ataque concreto (CL.TE, TE.CL…) con su función de "smuggle probe".
- Confirmas el impacto de forma controlada y documentas la petición mínima.
Trabajar el smuggling a mano exige entender muy bien HTTP a bajo nivel; la extensión reduce el error, pero el criterio sobre qué es seguro probar lo pones tú.
¿Y el smuggling en HTTP/2?
La investigación reciente ha mostrado que el problema no murió con HTTP/2. Cuando un front-end habla HTTP/2 con el cliente pero rebaja (downgrade) la conexión a HTTP/1.1 para hablar con el back-end, puede reintroducir la ambigüedad de las cabeceras al hacer esa traducción. Son las variantes de "H2.CL" y "H2.TE": el front-end HTTP/2 genera cabeceras Content-Length o Transfer-Encoding inconsistentes al convertir. Es terreno avanzado, pero conviene saber que la superficie sigue viva incluso en infraestructuras modernas.
¿Cómo se corrige?
Del lado defensivo, las mitigaciones reales son claras:
- Usar HTTP/2 de extremo a extremo sin downgrade a HTTP/1.1, eliminando la fuente de ambigüedad.
- Normalizar peticiones ambiguas: que el front-end rechace cualquier petición que traiga a la vez
Content-Length y Transfer-Encoding, en lugar de intentar interpretarla.
- Que front-end y back-end usen el mismo servidor/versión o, como mínimo, la misma lógica de parseo, para que nunca discrepen.
- Deshabilitar la reutilización de conexiones al back-end cuando el riesgo lo justifique (tiene coste de rendimiento, pero corta la vía de robo entre usuarios).
Como hunter, entender la defensa mejora tu reporte: puedes explicar no solo el fallo, sino la corrección concreta que el equipo debería aplicar.
Preguntas frecuentes (FAQ)
¿Es peligroso probar request smuggling en un objetivo real?
Puede serlo. Las pruebas diferenciales pueden afectar a peticiones de otros usuarios. Detecta con la técnica de timing (segura), confirma con el mínimo impacto y para en cuanto lo demuestres. Nunca envenenes respuestas de usuarios reales más allá de lo imprescindible.
¿Sirve de algo si el sitio solo tiene un servidor?
El smuggling necesita una cadena de al menos dos sistemas que parseen HTTP (proxy/CDN/balanceador + back-end). Si la petición llega directa a un único servidor sin intermediarios, no hay dos interpretaciones que enfrentar.
¿Qué severidad tiene un request smuggling?
Normalmente alta o crítica, porque permite afectar a otros usuarios: robar sus peticiones, saltarse controles del front-end o envenenar la caché. El impacto exacto depende de qué puedas encadenar.
¿Necesito la extensión de Burp o puedo hacerlo a mano?
Se puede a mano si dominas HTTP a bajo nivel, pero HTTP Request Smuggler reduce muchísimo el margen de error en la detección y la construcción del ataque. Para empezar, la extensión es muy recomendable.
Cómo empezar con el smuggling
Es una técnica avanzada: no es lo primero que atacas de recién llegado. La ruta razonable es dominar antes las familias del OWASP Top 10 a mano, entender bien el ciclo petición/respuesta con un proxy, y luego subir a técnicas de desincronización como esta.
Para llegar preparado, entrena la explotación web con labs que replican reportes reales y estudia la teoría avanzada en Academy › Avanzado. Cuando el ciclo HTTP te sea transparente, el smuggling deja de parecer magia y se convierte en una desincronización que sabes leer, detectar y demostrar con responsabilidad.