logo svg
logo

February 9, 2025

HTTP Request Smuggling Attack: Detection, Prevention, and Mitigation

Discover how HTTP Request Smuggling works, the risks it poses to web applications, and the best strategies to detect, prevent, and mitigate it

Anas Eladly

Anas Eladly

Featured Image

What are Front-End Servers?To fully understand HTTP request smuggling attack, one must first understand the concept of Front-end servers.

What are Front-End Servers?

Front-end servers are the gatekeepers of the internet, serving as the bridge between incoming internet traffic and backend systems. They play an important role in ensuring the availability, scalability, and security of web services. Let's start by looking at the key components that make up front-end server architectures.

Load Balancers:

Devices or software (like NGINX, and AWS Elastic Load Balancer) that distribute incoming traffic across multiple backend servers to balance load and ensure availability.

They distribute requests to different servers, preventing any one server from being overwhelmed, and ensuring high availability and fault tolerance.

Load balancers

Load balancers illustration

Reverse Proxy Servers:

Reverse proxies sit between clients and application servers, directing client requests for processing. They enhance security, aid in load balancing, and obscure the origin IP addresses of backend systems, thus preventing clients from detecting the servers' actual locations. NGINX and Apache exemplify reverse proxies that manage traffic efficiently and bolster system security.

Reverse Proxy

Reverse proxy illustration

Content Delivery Networks (CDNs):

CDNs are the speed enhancers of the internet, designed to optimize delivery speed and bandwidth usage by caching content in multiple geographical locations closer to users. By reducing latency and improving page load times, CDNs like Cloudflare and Akamai significantly enhance the user experience.

Load balancers

Load balancers illustration

Web Application Firewalls (WAFs):

Web Application Firewalls are specialized firewalls for web applications. They monitor, filter, and block harmful traffic before it reaches web servers. WAFs play a crucial role in protecting web applications from various attacks, including SQL injection, cross-site scripting (XSS), and of course, HTTP request smuggling.

Now we need to understand how HTTP protocol works, specifically how HTTP/1.1 handles the content length, this will come in useful later on.

How does HTTP/1.1 process request length ?

in HTTP/1.1 there are 2 ways that the server process incoming request length, the most known is Content-Length header and the not so well known Transfer-Encoding header

Content length header:

The Content-Length (CL) header is widely known and the mostly used option crucial for indicating the exact size (in bytes) of the request body and endline terminators \r\n .

In scenarios where the request body is sent in one continuous block, this header helps the server determine when the request has ended, ensuring that the full message is properly received and processed.

html
POST /login HTTP/1.1
Host: example.com
Content-Length: 34

username=admin&password=123456\r\n
\r\n

Transfer-Encoding header:

On the other hand, the Transfer-Encoding: chunked (TL) header is used when the request body is sent in smaller, segmented chunks, rather than a single block.

The server first reads the chunk size and processes these chunks sequentially then it concludes the message until it receives a chunk of size zero, which signals the end of the request.

html
POST /data HTTP/1.1
Host: example.com
Transfer-Encoding: chunked

7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
0\r\n
\r\n

The misuse of the two of these headers can lead to HTTP request smuggling. This attack exploits discrepancies in how different front-end servers interpret these headers.

HTTP Request smuggling:

Normal http request flow

Normal http request flow

HTTP request smuggling attack

HTTP request smuggling attack

The vulnerability arises when there is a difference in how frontend and back-end servers parse the length of an HTTP request.

This desynchronization typically occurs because different servers interpret the same request using conflicting rules (i.e., Content Length vs. Transfer-Encoding)

Example Code:

Here you can see an example code that shows how the request smuggle attack is executed

POST / HTTP/1.1
Host: victim.com
Content-Length: 67
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

Z
0
GET /smuggled HTTP/1.1
Host: victim.com
X: X

where the attacker injects both Content-Length and Transfer-Encoding headers into the same request leading to a desynchronization between the front-end and back-end servers

Request smuggling types:

HTTP request smuggling has many types each representing how each of the front-end and back-end servers handle the length of the request

Where the front-end server uses the Content-Length header to determine the request's length, but the back-end server uses the Transfer-Encoding header.

Where The front-end server interprets the request using Transfer-Encoding, while the back-end server uses Content-Length.

Where both the front-end and back-end servers use Transfer-Encoding to process requests, but differences in how they handle chunked data and the parsing of the header can lead to smuggling.

Refers to scenarios where the Content-Length header is present and has a value other than zero, indicating that the request body has content. The back-end ignores the Content-Length header (which is treated as 0), but the front-end parses it.

CL.TE:

In the CL.TE variation of HTTP request smuggling, an attacker adds both the Content-Length and Transfer-Encoding headers within a single HTTP request. The front-end server prioritizes the Content-Length header, while the back-end server gives priority to the Transfer-Encoding: chunked header

In this attack scenario, the attacker includes both headers in a way that the Content-Length header parses the entire length of the malicious request, including additional data intended for smuggling.

CL.TE attack

CL.TE attack

The Front-End server uses the Content-Length header to interpreting the entire request body, forwarding the complete request to the back-end server.

CL.TE attack

CL.TE attack

Conversely, the Back-End server uses Transfer-Encoding: chunked to parse the request.

The server stops reading at the end of the first valid chunk, as defined by the chunked transfer encoding.

leaving a portion of the request not parsed.

CL.TE attack

CL.TE attack

The not parsed portion of the attacker’s request is then smuggled to the next request in the stream allowing the attacker to manipulate incoming victim’s requests

CL.TE attack

CL.TE attack

TE.Cl:

in TE.CL variation The Front-end server prioritizes the Transfer-Encoding: chunked header, while the back-end server gives precedence to the Content-Length: header

In this attack scenario,

Unlike in the CL.TE variant, the front-end server in the TE.CL scenario prioritizes the Transfer-Encoding: chunked header. It processes the request body up to the point where it encounters a zero-length chunk, marking the perceived end of the request.

TE.CL attack

TE.CL attack

The Front-End server uses the Transfer-Encoding: chunked header to interpreting the entire request body, forwarding the complete request to the back-end server.

TE.CL attack

TE.CL attack

The back-end server, conversely, gives precedence to the Content-Length header.

as it reads the byte length provided by the header, it will not read the the entire request, leaving some if it to be smuggled to the next request in the stream

TE.CL attack

TE.CL attack

The part of the request which is not parsed by the Back-End is then smuggled to the next request in the stream allowing the attacker to manipulate incoming victim’s requests

TE.CL attack

TE.CL attack

TE.TE:

In TE.TE variation Both The Front-end and Back-End servers prioritizes the Transfer-Encoding: chunked header.

This means that the attacker will have to force one of the servers to ignore that header in order to make it use the Content-Length: Header The attacker can achieve this using obfuscation.

Where the attacker obfuscate the Transfer-Encoding: chunked header to force one of the servers to use the Content-Length header resulting in a normal TE.CL or CL.TE attack

Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked 
Transfer-Encoding: X

Transfer-Encoding:[tab]chunked

[space]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

Exploiting request smuggling attack:

HTTP request smuggling attack can be exploited by attacks in multiple ways including:

Attackers can manipulate the backend server to redirect users to malicious websites by smuggling requests that alter the backends’ response location.

Request smuggling allows attackers to bypass front-end security mechanisms (such as WAFs or input validation) by injecting malicious requests that go undetected by the front-end server but are processed by the backend.

Attackers can leverage request smuggling to inject malicious scripts, turning low-risk Reflected XSS or Self XSS into more severe exploits by altering the request flow.

The attacker can hijack other users' HTTP requests by smuggling their request into the backend server's processing queue, potentially accessing sensitive information.

Attackers can manipulate the request queue such that responses intended for legitimate users are sent to the attacker instead. This allows them to hijack sensitive data or responses not meant for them.

Open redirect

The most basic exploitation for the request smuggling, often used as a POC in testing.

Where the attacker Smuggles a a request that redirects the next victim to a completely different attacker controlled host

Open redirect exploitation

You may notice the attacker added an X parameter in the smuggled request, the reason for this is to prevent parsing errors, as stacking both the smuggled request and the victim’s request leads to parsing errors

so the attacker adds X parameter to pass the previous victim’s request as a parameter value, completely ignoring that request and using the attacker’s smuggled request

X parameter

X parameter added to fix the request structure

Chaining with self / Reflected XSS:

In some conditions when the website is vulnerable to self XSS the impact is often neglectable,

but the attacker can chain this useless self XSS with a request smuggling making it a more serious threat.

Where the attacker smuggle a request containing the self XSS payload, the request is then smuggled to the victim, which forces the victim to send the request containing the XSS payload

POST / HTTP/1.1
Host: vuln website
Cookie: {your cookies}
Transfer-Encoding: chunked
Content-Length: 100

0

GET /POST?postID=2 HTTP/1.1
User-Agent: X"><script>alert("XSS")</script>
Content-Type: applications/x-www-form-urlencoded
Content-Length: 5

X=1

In the Below scenario the attacker found a self XSS in the User-Agent header He then chained it with Request smuggling, forcing the victim to execute the XSS payload himself leading to a more impactful finding.

Escalating XSS using request smuggling

Escalating XSS using request smuggling

Note that the same scenario also works with Reflected XSS

Where you spam sending the poisoned request using tools like Burp intruder leading to deliver the XSS payload to multiple users escalating the finding’s impact.

Escalating reflected XSS using request smuggling

Escalating reflected XSS using request smuggling

Bypassing front-end controls:

Most Access controls and security policies are implemented through the Front-End servers.

therefore using request smuggling, an attacker can just smuggle a malicious request that violates those security policies through the firewall

Most checks are done through Front end servers

Most checks are done through Front end servers

The attacker will craft a request smuggle attack, which smuggles a malicious request that bypasses the front-end checks ( because the request is smuggled so it is not parsed by the WAF )

Bypassing Front-End controls using request smuggling

Bypassing Front-End controls using request smuggling

Stealing users requests:

As previously stated with the X parameter in the smuggled request

the previous victim request is assigned as a parameter value to that request

This was previously implemented to prevent having repeating request headers

But what if that X parameter is replaced by a parameter that is stored in the website Like a comment or a profile BIO ?

This means that the victim’s request will be stored in that comment and later viewed in the website including the victim’s sensitive info like Cookies and Tokens leading to ATO.

Stealing users requests using request smuggling

Stealing users requests using request smuggling

Stollen user request

Stollen user request

Response queue poisoning

In HTTP, each user typically has an independent request-response cycle with the server. That means for every request sent, the server processes it and sends back a response in order.

However, in certain cases, particularly when dealing with HTTP/1.1 persistent connections (also known as keep-alive connections), multiple requests from different clients may share the same connection queue before being processed. This creates a response queue where the responses are expected to be returned in the same order as the requests were received.

Response queue

Response queue

In normal Request smuggling attack, the attacker can only affect the user after him in the response queue

Request smuggling attack

Request smuggling attack

If the attacker smuggled an entire full request instead of the normal "half request", it forces the server to only parse the first request and then the smuggled request’s response gets served to the victim after the attacker

Response queue poisoning

Response queue poisoning

Response Queue Poisoning is the most dangerous request smuggling scenario, as it completely corrupts server responses.

Response queue poisoning attack

Response queue poisoning attack

Mitigating Request smuggling

As a developer it is critical to make sure your infrastructure is safe against request smuggling attacks.

There are multiple safeguards to make sure is implemented.

Ensure all proxies, load balancers, and servers interpret headers consistently.

Reject requests with both Content-Length and Transfer-Encoding headers.

Align front-end and back-end servers to follow the same request parsing rules.