HTTP Request Splitting, popularly known as HTTP Request Smuggling, deals with smuggling malicious payload in a normal request. The vulnerability arises when the front or the backend server misinterprets the two requests for one.
The scenario is based on many factors but focuses mainly on these HTTP headers – “Content-Length” and “Transfer-Encoding”. By manipulating these two headers, we can exploit this vulnerability.
Before getting your hands dirty, you must familiarize yourself with key concepts to understand this attack. We’ll answer a few questions to build a strong knowledge base and clarify the basics.
We usually indicate to the server that the request starts with a request line which includes the request method like GET/POST while the end is determined by the Content-Length header along with CRLF (Carriage Return and Line Feed), which is represented as following /r/n.
The Content-Length header indicates the size of the request body. It specifies the length of the body in a numeric format.
The Transfer-Encoding header can determine the size of the request. Transfer encoding header utilizes the following encoding techniques:
For the purpose of this vulnerability, we are going to use “chunked” encoding. The chunked encoding splits the data into separate chunks, each chunk is prefixed by a hexadecimal number indicating the chunk’s size. The end of the request is indicated by a 0 followed by a trailing CRLF sequence.
With all that out of the way, let’s look at how to handle requests on the server side. It is typical nowadays to see a web app set up with a frontend server (reverse proxy) that relays the incoming requests from the client to one or more backend servers.
The illustration below shows the flow of requests from client to server.
User1 and User2 send a request, and the frontend server receives the requests and forwards them to the backend server, after which the backend server identifies which request belongs to which user and does the required processing.
During this process, the front and backend servers should agree on the start and end of a request. This is where your attack vector lies.
To sum it all up, you can trick the frontend and backend servers into smuggling another request inside a request by using the Content-Length header and the Transfer-Encoding header. And sending a non-suspicious request which will work its way through regular security checks. The illustration below gives you a visual representation of the process and the intended result.
The attacker sends a malformed request. It passes through the front end, and at the back, gets prefixed to User2’s request.
Since you know what Content-Length and Transfer-Encoding headers are, you need to know if both headers are present in the request. How does the server handle such a request?
The RFC 2616 section 4.4 mentions the solution to this type of problem.
If a message is received with both the Transfer-Encoding header field and Content-Length header field, the latter MUST be ignored.
You must use both Content-Length and Transfer-Encoding headers to carry out this attack. It depends on how the servers are configured to accept the headers. Depending on the headers accepted by both the frontend and backend servers, we have created a table to simplify these attacks.
Imagine a scenario where a lab is set up with a frontend and backend server, but the frontend server doesn’t support chunked encoding. Additionally, there’s an admin panel at the ‘admin’ endpoint, but access to it is blocked by the frontend server.
To solve the lab, smuggle a request to the backend server that accesses the admin panel and deletes the user, Carlos.
Note: For CL-TE, you should ensure to checkmark the Update Content-Length option in the settings icon in the repeater tab.
The Content-Length header is automatically updated and you can enter any value as long as it is numeric.
Since you will include another request (/admin) in our request body, we need to indicate an end to the first request (/login).
In the CL-TE attack, the frontend server is concerned with Content-Length handled by the Update Content-Length option in the repeater tab. For Transfer-Encoding, you need to manually add a hexadecimal length in the request body.
Here is the content:
‘csrf=iZhHz0aOnl1VEsNAHaETtL0Z9E1JRlqr&username=carlos&password=carlos.’
In base-10 is 71, which, then converted to base-16 or hexadecimal, comes out to be 47.
After this, you need to include the 0 indicating that our request ends here, followed by two /r/n sequences, which are important.
Note: We have indicated the CRLF sequence in a red rectangle for understanding purposes only. You just need to make sure to leave a single line after 0. In this case, it is line 13.
Now you need to create a malicious payload. As the payload is interpreted as a new request by the backend server, you need to include a new request line.
We need to access the admin panel in this example, so we will include ‘GET /admin HTTP/1.1’ in the request line. We will also include the Host header and set its value to localhost.
Since we keep the connection alive with the backend, we need to send the request twice over the same TCP connection.
Hitting Send for the first time will give a 200 OK response. After hitting Send for the second time, you will get a 400 Bad request response which says `”error”:”Duplicate header names are not allowed”`.
This means the server still considers these two requests as a single request. To fix this, we need to add the Content-Length header and the Content-Type header.
Since we have included the Content-Length header, it is mandatory to have some content in the body. Here I have included `Mission Successful`.
After clicking Send for the second time, we get a 200 OK response along with access to the admin panel. And a link to delete the user Carlos.
Now we need to replace ‘/admin’ with ‘/admin/delete?username=carlos’ in the request line.
This completes the lab.
HTTP Request Smuggling is a type of web application vulnerability that can affect any software or system that processes HTTP requests and forwards them to another server or service. This can include web servers, reverse proxies, load balancers, and other types of web infrastructure. In general, any system that processes multiple requests in parallel and forwards them to another system can be vulnerable to HTTP Request Smuggling. If it does not properly handle the transfer of headers and other information between the requests.
An attacker can exploit this vulnerability by crafting a specially-crafted HTTP request that is able to “smuggle” another request through the system. This allows the attacker to bypass security controls or perform other malicious actions. The specific impact of an HTTP Request Smuggling vulnerability can vary depending on the details of the vulnerability and the systems that are affected. But it may allow an attacker to access sensitive data, perform unauthorized actions, or launch a denial of service attack.
It’s also important to mention that this vulnerability can affect different types of systems and applications, including those that use HTTP/1.1 and HTTP/2 protocols.
So far, you must be clear that in this attack, both the front and the backend servers use different mechanisms to determine the boundaries between the requests.
Here are some recommendations to fix the vulnerability:
HTTP Request Smuggling is an underrated and powerful vulnerability, and its complexity and partially blind nature make it one of a kind. This attack can have serious consequences including access control bypass, redirection to malicious websites, and many more. Don’t let your business face any such issues, let SecureLayer7 help you to keep things safe and secure.