Introduction
Imperva Release Notes provide information on changes and enhancements to our Cloud WAF product in each release. In October 2019 a series of changes were implemented to protect Imperva Cloud WAF customers against HTTP Request Smuggling attacks (learn more here). Further updates have been made over the past 60 days; these changes have also been detailed in in Release Notes. This article will explain recent updates, detail the attack technique that precipitated them and explain why it is important to be protected against such attacks.
What is HTTP Smuggling?
An HTTP Request Smuggling attack includes HTTP requests aiming to cause two devices in a chain of HTTP servers to see different sets of requests. This allows the hacker to smuggle a request to one device without the other device being aware of it. While this hacking technique was discussed widely in 2005, today there are still attempts to use HTTP request smuggling in order to make Web Application Firewall miss the request.
Recent changes to Imperva Cloud and On-Premises WAF include additional mitigation rules to insure that such attacks fail.
How do these vulnerabilities arise?
These attacks involve placing both Content length and Transfer Encoding headers into a single HTTP request and manipulating them so that the front-end and back-end server process the request differently. Both Cloud and On-Prem WAFs act as the "front-end" server, and the origin server acts as the "back-end“. The thing is that there are 2 different ways according to RFC to specify where the request ends: Content-Length and Transfer-Encoding header. The Content-Length header is straightforward: it specifies the length of the message body in bytes:
POST /search HTTP/1.1
Host: website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
The Transfer-Encoding header can be used to specify that the message body uses chunked encoding. This means that the message body contains one or more chunks of data. Each chunk consists of the chunk size in bytes (expressed in hexadecimal), followed by a newline, followed by the chunk contents. The message is terminated with a chunk of size zero.
POST /search HTTP/1.1
Host: website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
b
q=smuggling
0
The exploit:
Since both headers are allowed, it is possible to use both of them in the same request to specify its boundaries.If two or more servers that process this request are chained together, there is a possibility one of the servers will process these headers differently than the other/s. For example, some servers do not support the Transfer-Encoding header or treat it differently if it is obfuscated in some way. If the front-end and back-end servers behave differently in relation to the Transfer-Encoding header, then this may cause conflicts in the boundaries between successive requests, leading to request smuggling vulnerabilities.
How does Imperva protect against HTTP Request Smuggling?
Whereas in the past such requests were passed on to the customer origin servers, today our Cloud and On-Premises WAF block requests with header anomalies with a request parsing error (Error Code 3 – “There was an error in processing the request”).
The following requests are blocked:
- Multiple Content-Length headers with different values.
- Multiple Content-Type headers with different values.
- Spaces or tabs before the first header.
- A header in the following format: <header-name><header-value>, with no separating colon.
- \r or \n in a header name.
- Transfer-Encoding: chunked and Content-Length headers are both specified, but the total body length (raw, including chunking metadata) does not match the Content-Length value.
- The Transfer-Encoding header contains an illegal value.
- Multiple Transfer-Encoding headers with different values.
Examples of requests blocked by our WAF after the recent implementations:
Duplicate Content Type:
HTTP/1.1 200
Server: nginx/1.16.1
Date: Wed, 06 Nov 2019 01:46:00 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Content-Type: text/plain
.
.
.
Content-Length inconsistent with Transfer-Encoding:
POST /w HTTP/1.1
Accept: application/json; charset=utf-8
Content-Type: application/json; charset=UTF-8
Content-Length: 62719
.
.
.
Transfer-Encoding: chunked
User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-J510MN Build/MMB29M)
.
.
Some our customers were not aware that many of their legitimate end-users send requests with multiple Content–Length headers or insufficient Transfer-Encoding and Content-Length headers.
In the event these customers would like to maintain existing configuration, specific vulnerability enforcements can be disabled until the end-users are notified of this change in.