HTTP Request Smuggling
What is HTTP Request Smuggling?
HTTP Request Smuggling is a vulnerability that takes advantage of the misconfiguration in parsing one or more HTTP devices or entities that are in the data flow, between the user and the web server. Devices like cache server, proxy server, web application firewall, etc. are exploitable. In HRS attack multiple specially-crafted HTTP requests are delivered, which causes the two attacked entities to see two different sets of requests, allowing the hacker to smuggle a request to one device without the other device being aware of it. This opens multiple attack possibilities to exploit in an application like web cache poisoning, session hijacking, cross-site scripting, and web application firewall bypass.
How does an HTTP Request Smuggling work?
Web applications nowadays employ series of HTTP servers between users and the final application logic. Users send requests to a front-end server (like a proxy server, load balancer, or a WAF, etc.) and this server forwards requests to one or more back-end servers.
When the front-end server forwards HTTP requests to a back-end server, it generally sends several requests over the same back-end network connection. The 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.
In this scenario, it is important that the front-end and back-end systems agree about the boundaries between the requests. Or else an attacker might be able to send a malicious request that gets interpreted differently by the front-end and back-end systems.
This leads an attacker to cause part of their front-end request to be interpreted by the backend server as the start of the next request. The back-end server considers it to be the next request, and so thus the attacker interferes with the way the application processes the request.
Different Test Scenarios in HTTP Request Smuggling
The HTTP Request Smuggling vulnerability gets exploited because the HTTP specification provides two different methods to specify where a request end.
1. Content-Length Header: It’s an HTTP header that specifies the length of the message body in bytes. For example-
POST /search HTTP/1.1
2.Transfer-Encoding Header: The HTTP header uses chunked encoding to deliver the message body. This means chunks of data are included in the message body. Each chunk consists of the chunk size in bytes which is 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
The above-mentioned HTTP methods specify the length of HTTP messages; however, both methods cannot be used in a single request. In such a case, the server will reject/ ignore the instance of Content-Header to avoid ambiguity when only a single server is used. But in the case where multiple servers are chained together, it results in a problem in specifying the boundaries between the successive requests due to the below 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.
How to perform HTTP Request Smuggling in an attack scenario
HTTP Request Smuggling through web cache server leads to poisoning the cache server. Consider a POST request with two conflicting “Content-Length” header values. Let Demo be the DNS name of the web server behind the proxy. Let “example.html” be a static page on the web server. The HRS attack exploits the inconsistency between the two servers as below.
- POST http://Demo/example2.html HTTP/1.1\r\n
- Host: Demo\r\n
- Connection: Keep-Alive \r\n
- Content-Type: application/x-www-form-urlencoded\r\n
- Content-Length: 0\r\n
- Content-Length: 44\r\n
- GET /example1.html HTTP/1.1\r\n
- Host: Demo\r\n
- Ola: [space after the “Ola:”, but no CRLF]
- GET http://Demo/page_to_example1.html HTTP/1.1\r\n
- Host: Demo\r\n
- Connection: Keep-Alive\r\n
When this request is sent to the web server via a proxy server, the proxy server parses the POST request in lines 1-7 (in blue) and encounters the two “Content-Length” headers. It ignores the first header and assumes the request has a body of length 44 bytes. Thus, it treats the data in lines 8-10 as the first request’s body. The proxy then parses lines 11-14 (in red) treating it as the client’s second request and forwards the request to a web server.
Unlike the proxy, the Web server uses the first “Content-Length” header as the first POST request with nobody, and the second request is the GET in line 8, treating GET in line 11 as the value of the “Ola” header in line 10.
The requests the Web server sees are “POST /example2.html” (from line 1) and “GET /example1.html” (from line 8), so it sends back two responses with the contents of the pages, respectively. The proxy matches these responses to the two requests it thinks were sent by the client – “POST /example2.html” (line 1) and “GET /page_to_example1.html” (line11). Since the response is cacheable the proxy caches the contents of “example1.html” under the URL “page_to_example1.html”, and thus the cache is poisoned. Any client requesting “page_to_example1.html” from the proxy would receive the “example1.html” page.
Prevention of HTTP Request Smuggling vulnerabilities
HTTP request smuggling vulnerabilities are identified in scenarios where a front-end server forwards multiple requests to a back-end server over the same network connection. The protocol used for the back-end connections carries the risk that the two servers disagree about the boundaries between requests. The more layers you introduce between the user and the web server (Load balancers, CDNs, reverse proxies, etc.) the more likely you are to be vulnerable.
HRS can be mitigated by implementing below mentioned security strategies-
- Disabling backend connection reuse completely. This makes it to transfer each back-end request sent over a separate network connection.
- Configuring to use HTTP/2 in the back-end connections. The protocol will prevent uncertainty about the boundaries between the requests.
- All the front-end and back-end servers run the same web server software with the same configurations, agreeing on the boundaries between the requests.
- Normalize the ambiguous requests by reconfiguring the front-end server before routing them onward.
HTTP request smuggling is an exploit in 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. It is a major threat to web applications, parsing security-critical functions and tolerating ambiguous messages thus leading the users expose to multiple security risks.
Attack & Pen Test Team
Varutra Consulting Pvt. Ltd.