Detecting HTTP Request Smuggling with Qualys WAS

Sheela Sarva

Last updated on: December 20, 2022

HTTP Request Smuggling (HRS) is a web application vulnerability that enables an attacker to craft a single request that hides a second request within the body of the first request.

HRS enables the following types of attack:

  • Web cache poisoning
  • Web cache deception
  • Session hijacking
  • Cross-site scripting (XSS)
  • Bypassing a web application firewall (WAF)

HRS is possible because of the HTTP specification, which allows for two ways to signal the end of an HTTP request. The end of the request as per the specification is confirmed using either the Content-Length header or the Transfer-Encoding: chunked header. By using both headers, an attacker can craft a single request that hides a second request within the body of the other request, thereby smuggling the second request.

With many web applications, an HTTP request traverses through a chain of entities between the client software and the final web application server. Among others, these entities may include:

  • Caching server
  • Proxy server
  • Load balancer
  • WAF
  • Web server

According to the paper from Seebug, a request smuggling attack would be executed differently depending on the type of servers involved and their configurations.

  1. CL:CL attack method – The front-end server processes the first Content-Length header, and the back-end server processes the second Content-Length header or vice-versa.
  2. CL:TE attack method – The front-end server processes the Content-Length header, and the back-end server processes the Transfer-Encoding header.
  3. TE:CL attack method – The front-end server processes the Transfer-Encoding header, and the back-end server processes the Content-Length header.
  4. TE:TE attack method – 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.

Qualys Web Application Scanning (WAS) recently released QID 150300 as an initial detection for the HRS vulnerability. Due to the potential of false positives with other methods, Qualys WAS only tests using the CL:TE attack method. Steps to reproduce the issue manually are provided below. While remediation can be challenging, we provide some recommendations at the end of this article.

The Process of Smuggling a Request

The request smuggling occurs due to poisoning of the socket in the first request which allows the attacker to have control of the back end server. In order to get started the first request should have both transfer-encoding and content-length headers.

Consider the scenario where on the same connection a legitimate user and attacker are sending requests to the server. A valid request from the legitimate user reaches the back-end server traversing through the front-end server.

The attacker sends a request with both Content-Length and Transfer-Encoding set to “chunked”. The front-end server processes the content length and the back-end server processes the requests based on transfer-encoding. Due to the value being set to “chunked” the back-end server waits for further requests. Multiple requests of this nature will allow the malicious code from the attacker to be merged with legitimate user requests and also allow the attacker to get access to the data from the server.

Process of Request Smuggling
Image credit: Christopher Elgee via SANS

Qualys WAS Detection Logic and Manual Reproduction Steps Using OWASP ZAP

QID 150300 was recently released in Qualys WAS as an initial detection for the HRS vulnerability. Due to the potential of false positives with other methods, the only test performed by WAS at this time is the CL:TE method.

Qualys WAS makes multiple requests in order to identify and confirm the presence of the vulnerability. On the first request, WAS expects a 200 response in order to proceed with the next request. If a 200 response is not received for the first request, additional requests are not sent.

With the information here, you can manually confirm the vulnerability using OWASP ZAP. Please ensure you have ZAP 2.9.0 or later installed and configured as a proxy in your web browser. Manually send the requests below using ZAP to reproduce the issue.

Request #1:

Response #1 – 200 response received:

Only if a 200 response is received on the first request, WAS then proceeds to send a second, specially-crafted request as follows. If a 403, 405, or 501 response is received, it indicates that the server tried to process a request using the “GPOST” method, which is not a valid HTTP method. Any of these response codes means that WAS smuggled a request, so QID 150300 will be reported.

Request #2:

Response #2 – 403, 405, or 501 response received:

How to Configure Qualys WAS to test for HRS

Create a custom search list, ensure that QID 150300 is included, and launch a scan using that search list.

If an HRS vulnerability is found, you will see QID 150300 reported as follows.

Note: Although QID 150300 is a “confirmed” vulnerability, it is also included in the Experimental detection scope category. This is because there are several different methods/approaches to test for the vulnerability and WAS employs only one of the methods currently (CL:TE). This method is not prone to false positives, so a confirmed vulnerability is appropriate instead of potential. So although the QID is marked as experimental, it is very likely to be a true positive if reported.

Once the vulnerability has been remediated, you can retest the detection to ensure the changes are effective. 

How to Remediate HRS

Remediation of HTTP request smuggling vulnerabilities is a challenge. It may not be something a typical application developer would be able to fix, because it involves the network architecture and configuration settings of various servers involved in processing the HTTP requests sent by clients.

Included below are several recommendations along with references to assist in the process.

  • Ensure the various entities that process the HTTP requests follow the same protocol
  • Same header should be used across all the entities that process the requests. Either use Transfer-Encoding or Content-Length
  • Use HTTP/2 for back-end connections
  • Configure your WAF to detect and block ambiguous requests
  • Disable reuse of back-end connections which could result in degradation of performance of your server



Contributions were made to this blog post by Dave Ferguson, Director of Web Application Security, Qualys.

Share your Comments


Your email address will not be published. Required fields are marked *