logo
    • Home
    • Categories
    • About
  • en-languageEnglish
SecurityBy Pierre Colart

HTTP request smuggling

Context

HTTP request smuggling is a malicious technique that disrupts the processing of HTTP requests received from one or more users on a website, thereby exposing critical vulnerabilities. Attackers can exploit these vulnerabilities to bypass security measures, gain unauthorized access to sensitive data, and directly compromise other users of the application.

Today's web applications often use chains of HTTP servers between users and the final application logic. Users send requests to a front-end server, which forwards them to one or more downstream servers. This type of architecture is becoming increasingly common and, in some cases, unavoidable in modern cloud-based applications.

When the front-end server forwards HTTP requests to a downstream server, it usually sends several requests over the same underlying network connection, as this is much more efficient and performant. The protocol is simple: HTTP requests are sent one after the other, and the receiving server analyzes the HTTP request headers to determine where one request ends and the next one begins.

In this situation, it is crucial that the front-end and back-end systems establish clear boundaries between requests. Without this, an attacker could send an ambiguous request that would be interpreted differently by the front-end and back-end systems.

During an HTTP request smuggling attack, the attacker manipulates a part of their front-end request to be interpreted by the back-end server as the beginning of the next request. This part is added to the beginning of the next request, which can interfere with how the application processes that request. The consequences can be disastrous.

Most HTTP request smuggling vulnerabilities stem from the fact that the HTTP specification offers two different methods to define where a request ends in the header: Content-Length and Transfer-Encoding.

Content-Length is simple: it specifies the length of the message body in bytes. For example:

During a HTTP request smuggling attack, the attacker manipulates a part of their front-end request to be interpreted by the back-end server as the beginning of the next request. This part is added to the beginning of the next request, which can interfere with how the application processes that request. The consequences can be disastrous.

Most HTTP request smuggling vulnerabilities stem from the fact that the HTTP specification offers two different methods to define where a request ends in the header: Content-Length and Transfer-Encoding.

Content-Length is simple: it specifies the length of the message body in bytes. For example:

 POST /search HTTP/1.1
Host: website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

q=smuggling

Given that the HTTP specification provides two different methods for specifying the length of HTTP messages, it is possible for a single message to use both methods at once, causing conflicts. The HTTP specification tries to avoid this problem by stating that if both Content-Length and Transfer-Encoding headers are present, the Content-Length header should be ignored. This may be sufficient to avoid ambiguity when a single server is involved, but not when two or more servers are chained together. In this situation, problems can arise for two reasons:

  • Some servers do not support the Transfer-Encoding header in requests.
  • Some servers that do support the Transfer-Encoding header may be induced not to process it if the header is obscured in some way.

If the frontend and backend servers behave differently with respect to the (possibly obscured) Transfer-Encoding header, they may then disagree on the boundaries between successive requests, leading to HTTP request smuggling vulnerabilities.

How it works

HTTP request smuggling attacks involve placing both the Content-Length header and the Transfer-Encoding header in a single HTTP request and manipulating them so that the frontend and backend servers treat the request differently. The exact way this is done depends on the behavior of the two servers:

  • CL.TE: The frontend server uses the Content-Length header and the backend server uses the Transfer-Encoding header.
  • TE.CL: The frontend server uses the Transfer-Encoding header and the backend server uses the Content-Length header.
  • TE.TE: Both the frontend and backend servers support the Transfer-Encoding header, but one of the servers may be induced not to process it by obscuring the header in some way.

CL.TE vulnerabilities

Here, the frontend server uses the Content-Length header and the backend server uses the Transfer-Encoding header. We can perform a simple HTTP request smuggling attack as follows:

 POST / HTTP/1.1
Host: website.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

The front-end server processes the Transfer-Encoding header and determines that the body of the request is encoded using chunked encoding. It reads the first chunk size, which is 13 in this case, and then reads the chunk itself, which is "SMUGGLED". The front-end server then sends this request to the back-end server.

The back-end server processes the Content-Length header and determines that the body of the request has a length of 13 bytes, which includes the "SMUGGLED" string. It then reads the entire request, including the chunked encoding and the "SMUGGLED" string.

This vulnerability is less common than CL.TE vulnerabilities, but it is still present in some environments.

 POST / HTTP/1.1
Host: website.com
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

The front-end server processes the Transfer-Encoding header and thus treats the message body as using chunked encoding. It processes the first block, which is supposed to have a length of 8 bytes, up to the beginning of the line following SMUGGLED. It processes the second block, which is declared to be of zero length, and is thus treated as terminating the request. This request is forwarded to the main server.

The main server processes the Content-Length header and determines that the request body has a length of 3 bytes, up to the beginning of the line following 8. The following bytes, starting with SMUGGLED, are not processed and the main server will treat them as the beginning of the next request in the sequence.

TE.TE vulnerabilities

Here, both the front-end and main servers support the Transfer-Encoding header, but one of the servers may be induced not to process it by obfuscating the header in some way. There are potentially infinite ways to obscure the Transfer-Encoding header. For example:

 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

Each of these techniques involves a subtle deviation from the HTTP specification. In the real world, the implementation of a protocol specification rarely adheres with absolute precision, and it is common for different implementations to tolerate variations from the specification. To discover a TE.TE vulnerability, it is necessary to find a variation of the Transfer-Encoding header such that only one of the front-end or main servers processes it, while the other server ignores it.

Depending on whether the front-end server or the back-end server can be made not to process the obfuscated Transfer-Encoding header, the rest of the attack will take the same form as for the CL.TE or TE.CL vulnerabilities already described.

Browser-powered smuggling

The request smuggling techniques you've learned so far rely on intentionally malformed requests sent using dedicated hacking tools. In fact, it's possible to perform the same attacks using requests that are entirely compatible with the browser that desynchronize the two servers using a perfectly normal Content-Length header. This even allows you to launch client-side variants of these attacks, which prompt the victim's browser to poison its own connection to the vulnerable website. Not only does this expose single-server sites to smuggling attacks, but it even allows you to attack sites that you don't have direct access to.

How to prevent vulnerabilities

To prevent HTTP request smuggling vulnerabilities, the following high-level measures are recommended:

  • Use end-to-end HTTP/2 and disable HTTP downgrade if possible. HTTP/2 uses a robust mechanism for determining request length and, when used end-to-end, is inherently protected against request smuggling. If HTTP downgrade cannot be avoided, it is important to validate the rewritten request against the HTTP/1.1 specification by rejecting requests that contain newlines in headers, colons in header names, and spaces in the request method.

  • Ensure that the front-end server normalizes ambiguous requests and that the main server rejects those that are still ambiguous, closing the TCP connection in the process.

  • Never assume that requests will have no body, as this is the root cause of CL.0 and client-side desynchronization vulnerabilities.

  • By default, ignore the connection if server-level exceptions are triggered when processing requests.

  • If traffic is routed through a forwarding proxy, ensure that upstream HTTP/2 is enabled if possible.

Pierre Colart

Passionate developer and architect who wants to share their world and discoveries in order to make things simpler for everyone.

See profil

Latest posts

Sequences, Time Series and Prediction

© 2023 Switch case. Made with by Pierre Colart