​HTTP request smuggling​

             In this section, we'll explain HTTP request smuggling attacks and describe how common request smuggling vulnerabilities can arise.

What is HTTP request smuggling?

HTTP request smuggling is a technique for interfering with the way a web site processes sequences of HTTP requests that are received from one or more users. Request smuggling vulnerabilities are often critical in nature, allowing an attacker to bypass security controls, gain unauthorized access to sensitive data, and directly compromise other application users.         

HTTP request smuggling_分块

 

 



Note

HTTP request smuggling was first documented in 2005, and recently repopularized by ​​PortSwigger's research​​ on the topic.             

 

What happens in an HTTP request smuggling attack?

Today's web applications frequently employ chains of HTTP servers between users and the ultimate application logic. Users send requests to a front-end server (sometimes called a load balancer or reverse proxy) and this server forwards requests to one or more back-end servers. This type of architecture is increasingly common, and in some cases unavoidable, in modern cloud-based applications.

When the front-end server forwards HTTP requests to a back-end server, it typically sends several requests over the same back-end network connection, because this is much more efficient and performant. The protocol is very simple: HTTP requests are sent one after another, and the receiving server parses the HTTP request headers to determine where one request ends and the next one begins:         

HTTP request smuggling_分块_02

 

 In this situation, it is crucial that the front-end and back-end systems agree about the boundaries between requests. Otherwise, an attacker might be able to send an ambiguous request that gets interpreted differently by the front-end and back-end systems:

HTTP request smuggling_sed_03

 

 

             Here, the attacker causes part of their front-end request to be interpreted by the back-end server as the start of the next request. It is effectively prepended to the next request, and so can interfere with the way the application processes that request. This is a request smuggling attack, and it can have devastating results.

How do HTTP request smuggling vulnerabilities arise?

Most HTTP request smuggling vulnerabilities arise because the HTTP specification provides two different ways to specify where a request ends: the ​​Content-Length​​ header and the ​​Transfer-Encoding​​ header.

The ​​Content-Length​​ header is straightforward: it specifies the length of the message body in bytes. For example:

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

q=smuggling ​

The ​​Transfer-Encoding​​ header can be used to specify that the message body uses chunked encoding. This means that the message body contains one or more chunks of data. Each chunk consists of the chunk size in bytes (expressed in hexadecimal), followed by a newline, followed by the chunk contents. The message is terminated with a chunk of size zero. For example:

​ POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

b
q=smuggling
0



Note

Many security testers are unaware that chunked encoding can be used in HTTP requests, for two reasons:

  • Burp Suite automatically unpacks chunked encoding to make messages easier to view and edit.
  • Browsers do not normally use chunked encoding in requests, and it is normally seen only in server responses.


Since 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, such that they conflict with each other. The HTTP specification attempts to prevent this problem by stating that if both the ​​Content-Length​​ and ​​Transfer-Encoding​​ headers are present, then the ​ ​Content-Length​​ header should be ignored. This might be sufficient to avoid ambiguity when only a single server is in play, 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 can be induced not to process it if the header is obfuscated in some way.

If the front-end and back-end servers behave differently in relation to the (possibly obfuscated) ​​Transfer-Encoding​​ header, then they might disagree about the boundaries between successive requests, leading to request smuggling vulnerabilities.         

How to perform an HTTP request smuggling attack

Request smuggling attacks involve placing both the ​​Content-Length​​ header and the ​​Transfer-Encoding​​ header into a single HTTP request and manipulating these so that the front-end and back-end servers process the request differently. The exact way in which this is done depends on the behavior of the two servers:

  • CL.TE: the front-end server uses the ​​Content-Length​​ header and the back-end server uses the ​​Transfer-Encoding​​ header.
  • TE.CL: the front-end server uses the ​​Transfer-Encoding​​ header and the back-end server uses the ​​Content-Length​​ header.
  • TE.TE: the front-end and back-end servers both support the ​​Transfer-Encoding​​ header, but one of the servers can be induced not to process it by obfuscating the header in some way.             

 

CL.TE vulnerabilities

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

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

0

SMUGGLED ​

The front-end server processes the ​​Content-Length​​ header and determines that the request body is 13 bytes long, up to the end of ​ ​SMUGGLED​​. This request is forwarded on to the back-end server.

The back-end server processes the ​​Transfer-Encoding​​ header, and so treats the message body as using chunked encoding. It processes the first chunk, which is stated to be zero length, and so is treated as terminating the request. The following bytes, ​ ​SMUGGLED​​, are left unprocessed, and the back-end server will treat these as being the start of the next request in the sequence.


LAB ​​HTTP request smuggling, basic CL.TE vulnerability​​ Not solved


​POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Transfer-Encoding: chunked

0

G         ​


因为是CL.TE(前端认定长度CL,后端认定分块TE)

前端看到长度是6,就读取6个字节,0\r\n\r\nG,将数据包全部发到后端

后端认定是分块,读到0\r\n就结束了,后端服务器的缓冲区里还留下了一个G,这个G就会留在缓冲区里(通常10s后会过期)和下一个请求拼接到一起


 


 


TE.CL vulnerabilities

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

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

8
SMUGGLED
0



Note

To send this request using Burp Repeater, you will first need to go to the Repeater menu and ensure that the "Update Content-Length" option is unchecked.

You need to include the trailing sequence ​​\r\n\r\n​​ following the final ​​0​​.

The front-end server processes the ​​Transfer-Encoding​​ header, and so treats the message body as using chunked encoding. It processes the first chunk, which is stated to be 8 bytes long, up to the start of the line following ​ ​SMUGGLED​​. It processes the second chunk, which is stated to be zero length, and so is treated as terminating the request. This request is forwarded on to the back-end server.

The back-end server processes the ​​Content-Length​​ header and determines that the request body is 3 bytes long, up to the start of the line following ​ ​8​​. The following bytes, starting with ​​SMUGGLED​​, are left unprocessed, and the back-end server will treat these as being the start of the next request in the sequence.


LAB ​​HTTP request smuggling, basic TE.CL vulnerability​​ Not solved


​POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0​

 

 




Note

You need to include the trailing sequence ​​\r\n\r\n​​ following the final ​​0​​.         


因为是TE.CL(前端认定是分块TE,后端认定长度CL)

5c是十六进制的数据,转为十进制为92,就是5c下面的数据包的长度

前端认为这是一个TE数据包,第一个数据块的长度是5c(92),遇到0结束

所以会将整个数据包都发送给后端服务器处理

后端服务器认定CL,CL的长度是4,所以只截取到5c

5c明明是两个字符为什么长度是4? 因为还有一个你看不到的\r\n

而下面的GPOST...会被后端认为是另一个http数据包


 


 


TE.TE behavior: obfuscating the TE header

Here, the front-end and back-end servers both support the ​​Transfer-Encoding​​ header, but one of the servers can be induced not to process it by obfuscating the header in some way.

There are potentially endless ways to obfuscate 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 departure from the HTTP specification. Real-world code that implements a protocol specification rarely adheres to it with absolute precision, and it is common for different implementations to tolerate different variations from the specification. To uncover a TE.TE vulnerability, it is necessary to find some variation of the ​​Transfer-Encoding​​ header such that only one of the front-end or back-end servers processes it, while the other server ignores it.

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


LAB ​​HTTP request smuggling, obfuscating the TE header​​ Not solved



Read more

​Finding HTTP request smuggling vulnerabilities​​ ​


​Exploiting HTTP request smuggling vulnerabilities​

 


How to prevent HTTP request smuggling vulnerabilities

HTTP request smuggling vulnerabilities arise in situations where a front-end server forwards multiple requests to a back-end server over the same network connection, and the protocol used for the back-end connections carries the risk that the two servers disagree about the boundaries between requests. Some generic ways to prevent HTTP request smuggling vulnerabilities arising are as follows:

  • Disable reuse of back-end connections, so that each back-end request is sent over a separate network connection.
  • Use HTTP/2 for back-end connections, as this protocol prevents ambiguity about the boundaries between requests.
  • Use exactly the same web server software for the front-end and back-end servers, so that they agree about the boundaries between requests.

In some cases, vulnerabilities can be avoided by making the front-end server normalize ambiguous requests or making the back-end server reject ambiguous requests and close the network connection. However, these approaches are potentially more error-prone than the generic mitigations identified above.



Read more

​Find HTTP request smuggling vulnerabilities using Burp Suite's web vulnerability scanner​