1071
client - "POST /foobar.html" and "GET /page_to_poison.html". If the response is cacheable,
the proxy caches the contents of "poison.html" under the URL "page_to_poison.html", and the
cache is poisoned! Any client requesting "page_to_poison.html" from the proxy would receive the
"poison.html" page.
When a website includes both a proxy server and a web server, some protection against this
type of attack can be achieved by installing a web application firewall, or using a web server that
includes a stricter HTTP parsing procedure or make all webpages non-cacheable.
Additionally, if a web application includes a Java servlet for processing requests, the servlet can
check for multiple "Content-Length" headers and if they are found the servlet can return an error
response thereby preventing the poison page to be cached, as shown below.
Example Language: Java (Good)
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
// Set up response writer object
...
try {
// check for multiple content length headers
Enumeration contentLengthHeaders = request.getHeaders("Content-Length");
int count = 0;
while (contentLengthHeaders.hasMoreElements()) {
count++;
}
if (count > 1) {
// output error response
}
else {
// process request
}
} catch (Exception ex) {...}
}
Example 2:
In the following example, a malformed HTTP request is sent to a website that includes a web
server with a firewall with the intent of bypassing the web server firewall to smuggle malicious code
into the system.
Example Language: (Attack)
POST /page.asp HTTP/1.1
Host: www.website.com
Connection: Keep-Alive
Content-Length: 49223
zzz...zzz ["z" x 49152]
POST /page.asp HTTP/1.0
Connection: Keep-Alive
Content-Length: 30
POST /page.asp HTTP/1.0
Bla: POST /page.asp?cmd.exe HTTP/1.0
Connection: Keep-Alive
When this request is sent to the web server, the first POST request has a content-length of 49,223
bytes, and the firewall treats the line with 49,152 copies of "z" and the lines with an additional lines
with 71 bytes as its body (49,152+71=49,223). The firewall then continues to parse what it thinks is
the second request starting with the line with the third POST request.
Note that there is no CRLF after the "Bla: " header so the POST in the line is parsed as the value of
the "Bla:" header. Although the line contains the pattern identified with a worm ("cmd.exe"), it is not
blocked, since it is considered part of a header value. Therefore, "cmd.exe" is smuggled through
the firewall.
CWE Version 4.14
CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
CWE-444: Inconsistent Interpretation of HTTP
Requests ('HTTP Request/Response Smuggling') 1072
When the request is passed through the firewall the web server the first request is ignored because
the web server does not find an expected "Content-Type: application/x-www-form-urlencoded"
header, and starts parsing the second request.
This second request has a content-length of 30 bytes, which is exactly the length of the next two
lines up to the space after the "Bla:" header. And unlike the firewall, the web server processes the
final POST as a separate third request and the "cmd.exe" worm is smuggled through the firewall to
the web server.
To avoid this attack a Web server firewall product must be used that is designed to prevent this
type of attack.
Example 3:
The interpretation of HTTP responses can be manipulated if response headers include a space
between the header name and colon, or if HTTP 1.1 headers are sent through a proxy configured
for HTTP 1.0, allowing for HTTP response smuggling. This can be exploited in web browsers and
other applications when used in combination with various proxy servers. For instance, the HTTP
response interpreted by the front-end/client HTTP agent/entity - in this case the web browser - can
interpret a single response from an adversary-compromised web server as being two responses
from two different web sites. In the Example below, notice the extra space after the Content-Length
and Set-Cookie headers.
Example Language: (Attack)
HTTP/1.1 200 OK
Date: Fri, 08 Aug 2016 08:12:31 GMT
Server: Apache (Unix)
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html
Content-Length : 2345
Transfer-Encoding: chunked
Set-Cookie : token="Malicious Code"
<HTML> ... "Malicious Code"
Observed Examples
Reference Description
CVE-2022-24766 SSL/TLS-capable proxy allows HTTP smuggling when used in tandem with
HTTP/1.0 services, due to inconsistent interpretation and input sanitization of
HTTP messages within the body of another message
https://www.cve.org/CVERecord?id=CVE-2022-24766
CVE-2021-37147 Chain: caching proxy server has improper input validation (CWE-20) of
headers, allowing HTTP response smuggling (CWE-444) using an "LF line
ending"
https://www.cve.org/CVERecord?id=CVE-2021-37147
CVE-2020-8287 Node.js platform allows request smuggling via two Transfer-Encoding headers
https://www.cve.org/CVERecord?id=CVE-2020-8287
CVE-2006-6276 Web servers allow request smuggling via inconsistent HTTP headers.
https://www.cve.org/CVERecord?id=CVE-2006-6276
CVE-2005-2088 HTTP server allows request smuggling with both a "Transfer-Encoding:
chunked" header and a Content-Length header
https://www.cve.org/CVERecord?id=CVE-2005-2088
CVE-2005-2089 HTTP server allows request smuggling with both a "Transfer-Encoding:
chunked" header and a Content-Length header
https://www.cve.org/CVERecord?id=CVE-2005-2089
MemberOf Relationships
CWE Version 4.14
CWE-446: UI Discrepancy for Security Feature
CWE-446: UI Discrepancy for Security Feature