4 New Variants of HTTP Request Smuggling Attack
Amit Klein, VP of Security Research at SafeBreach who presented the findings today at the Black Hat security conference, said that the attacks highlight how web servers and HTTP proxy servers are still susceptible to HTTP request smuggling even after 15 years since they were first documented.
What is HTTP Request Smuggling?
HTTP request smuggling (or HTTP Desyncing) is a technique employed to interfere with the way a website processes sequences of HTTP requests that are received from one or more users.
Vulnerabilities related to HTTP request smuggling typically arise when the front-end (a load balancer or proxy) and the back-end servers interpret the boundary of an HTTP request differently, thereby allowing a bad actor to send (or “smuggle”) an ambiguous request that gets prepended to the next legitimate user request.
This desynchronization of requests can be exploited to hijack credentials, inject responses to users, and even steal data from a victim's request and exfiltrate the information to an attacker-controlled server.
The technique was first demonstrated in 2005 by a group of researchers from Watchfire, including Klein, Chaim Linhart, Ronen Heled, and Steve Orrin. But in the last five years, a number of improvements have been devised, significantly expanding on the attack surface to splice requests into others and “gain maximum privilege access to internal APIs,” poison web caches, and compromise login pages of popular applications.
The new variants disclosed by Klein involve using various proxy-server combinations, including Aprelium's Abyss, Microsoft IIS, Apache, and Tomcat in the web-server mode, and Nginx, Squid, HAProxy, Caddy, and Traefik in the HTTP proxy mode.
The list of all new four new variants is as below, including an old one that the researcher successfully exploited in his experiments.
- Variant 1: “Header SP/CR junk: …”
- Variant 2 – “Wait for It”
- Variant 3 – HTTP/1.2 to bypass mod_security-like defense
- Variant 4 – a plain solution
- Variant 5 – “CR header”
When handling HTTP requests containing two Content-Length header fields, Abyss, for example, was found to accept the second header as valid, whereas Squid used the first Content-Length header, thus leading the two servers to interpret the requests differently and achieve request smuggling.
In situations where Abyss gets an HTTP request with a body whose length is less than the specified Content-Length value, it waits for 30 seconds to fulfill the request, but not before ignoring the remaining body of the request. Klein found that this also results in discrepancies between Squid and Abyss, with the latter interpreting portions of the outbound HTTP request as a second request.
A third variant of the attack uses HTTP/1.2 to circumvent WAF defenses as defined in OWASP ModSecurity Core Rule Set (CRS) for preventing HTTP request smuggling attacks craft a malicious payload that triggers the behavior.
Lastly, Klein discovered that using the “Content-Type: text/plain” header field was sufficient to bypass paranoia level checks 1 and 2 specified in CRS and yield an HTTP Request Smuggling vulnerability.
What Are the Possible Defenses?
After the findings were disclosed to Aprelium, Squid, and OWASP CRS, the issues were fixed in Abyss X1 v2.14, Squid versions 4.12, and 5.0.3 and CRS v3.3.0.
Calling for normalization of outbound HTTP Requests from proxy servers, Klein stressed the need for an open source, robust web application firewall solution that's capable of handling HTTP Request Smuggling attacks.
“ModSecurity (combined with CRS) is indeed an open source project, but as for robustness and genericity, mod_security has several drawbacks,” Klein noted. “It doesn't provide full protection against HTTP Request Smuggling [and] it is only available for Apache, IIS and nginx.”
To this end, Klein has published a C++-based library that ensures that all incoming HTTP requests are entirely valid, compliant, and unambiguous by enforcing strict adherence to HTTP header format and request line format. It can be accessed from GitHub here.