HTTP Noir: The Dark Art of Smuggling Bytes
This is a story about HTTP smuggling and how it is considered bad because it represents a security vulnerability that can be exploited by attackers to bring down the normal functionality of web applications, bypass security mechanisms, and potentially gain unauthorized access to sensitive information.
What is HTTP? : HTTP stands for Hypertext Transfer Protocol, and it is a fundamental protocol used for communication on the internet, enabling the transfer of various types of data such as text, images, videos, etc. It is an application layer protocol within the TCP/IP model.
Notes about HTTP:
- HTTP is considered stateless, meaning each request from a client to a server is independent. Server does not remember info about the previous requests from (even) the same client.
- HTTPS (Hypertext Transfer Protocol Secure) is an extension of HTTP that uses encryption (TLS/SSL) to secure the data which hides data like username, password when we log in to web apps.
What is application layer? : Application layer is the top layer of the Transmission Control Protocol/Internet Protocol (TCP/IP), which is a conceptual framework that standardizes the protocols used for communication over the internet. It consists of four layers: Network, Internet, Transport, and Application.
What is TLS/SSL? : TLS (Transport Layer Security) and SSL (Secure Sockets Layer) are cryptographic protocols designed to provide secure communication over a computer network, such as the internet, which is used to hide our username and passwords and other sensitive information through the internet.
Most instances of HTTP request smuggling vulnerabilities starts from the HTTP/1 specification, which offers two methods for specifying the end of a request: the Content-Length
header and the Transfer-Encoding
header.
Content-Length
header indicates the length of the message body in bytes, while theTransfer-Encoding
header signals the use of chunked encoding, Which means the message body consists of one or more data chunks. Each chunk includes in the bytes size (expressed in hexadecimal) followed by a newline and the chunk contents.
There are 3 main ways to exploit HTTP request smuggling vulnerabilities:
- CL.TE: attacker manipulates the
Content-Length
header of the front-end server andTransfer-Encoding
header of the back-end server. - TE.CL: attacker manipulates the
Transfer-Encoding
header of the front-end server andContent-Length
header of the back-end server. - TE.TE: attacker manipulates the
Transfer-Encoding
header twice in succession. The attacker exploits the system's interpretation of consecutiveTransfer-Encoding
headers, potentially causing confusion or mishandling of the request.
CL = Content Length
TE = Transfer Encoding
HTTP/1.1 -> One TCP connection per HTTP req res cycle
If we want to get 100 photos, it used to call 100 requests for each photos
HTTP/2 -> persistent call, It passes "connection: Keep-alive" as an header
which will be one req for 100 photos
But if we don't want that then we need to pass "connection: close" as an header
Let’s understand this by using burp suite and intercepting requests.
CL.TE
In this example, the front-end server uses the Content-Length
header and doesn’t support Transfer-Encoding
, but the backend understands it, we intercept a request like this
and then put it into repeater and change the request like this
The server understands Transfer-Encoding
which takes the body as chunked encoding, it processes the first chunk which has 0 in it and the server treats it as 0 length and terminates the request, leftover G
is unprocessed and treated as the start of next request.
But on the second time, the G
will get appended before POST, and the server will get a GPOST
as method.
TE.CL
Here, the front-end server uses the Transfer-Encoding
header and the back-end server uses the Content-Length
header. We will perform a simple HTTP request smuggling attack.
We intercept the request and send it to repeater, and change it like this:
The 5c
is the hexadecimal of 92 which is the total value of the rest of the request body.
The server is sending Transfer-Encoding
which we are passing as chunked and setting Content-length
as 4. After the text Transfer-Encoding: chunked
the server will see \r\n
2 times → 2 bytes and then 5c
→ 2 more bytes, which totals as 4 bytes, same as the mentioned Content-length
and it ends the request and treats the rest as a separate request.
In this example the server understands Content-length
so it will stop till 5c
as it’ll match the exact Content-length
passed and on the next request it’ll start from the GPOST
.
TE.TE
Here, the front-end and back-end servers both supports the Transfer-Encoding
header.
On the first request the server will accept Transfer-Encoding
: chunked but on the second request the Transfer-Encoding
is passed with some unknown element (here: HelloWorld) and this obfuscates Transfer-Encoding
and the server switches to Content-Length
here, and we make this exactly like a TE.CL experiment.
Mitigating HTTP smuggling Vulnerability:
1. Update and Patch:
Ensure that the web server, application server, and any intermediary devices are using the latest versions and have all security patches applied. Vendor updates often include security fixes, so staying up-to-date is crucial.
2. Security Headers:
Implement security headers in the web application to enhance security. Headers like Content-Length, Transfer-Encoding, and Connection should be set explicitly to avoid ambiguity. Use the Content-Security-Policy header to control the resources that can be loaded.
3. Web Application Firewall (WAF):
Implement a WAF that is configured to detect and block HTTP smuggling attacks. Latest WAFs often have rules specifically designed to identify and prevent various types of web attacks, including HTTP smuggling.
4. HTTP/2 Adoption:
Consider updating to HTTP/2, which has a more robust framing mechanism than HTTP/1.1, making it less susceptible to some HTTP smuggling techniques.