Incorrect Parsing When Both Content-Length and Transfer-Encoding Are Present
Summary
Hypercorn fails to correctly handle requests that contain both Content-Length and Transfer-Encoding headers, leading to vulnerabilities such as HTTP request smuggling and response splitting.
Details
RFC 9112 says this:
If a message is received with both a
Transfer-Encodingand aContent-Lengthheader field, theTransfer-Encodingoverrides theContent-Length. Such a message might indicate an attempt to perform request smuggling or response splitting and ought to be handled as an error.
This implies that Content-Length and Transfer-Encoding fields can’t exist at the same time, and Transfer-Encoding should override the Content-Length. However, Hypercorn improperly handles requests that contain both Content-Length and Transfer-Encoding fields, failing to reject such requests. An attacker can craft a malicious HTTP request which causes HTTP Request Smuggling or HTTP Response Splitting.
Example
POST / HTTP/1.1\r\n
Host: victim.com\r\n
Content-Length: 4\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n
GET /admin HTTP/1.1\r\n
Host: victim.com\r\n
\r\n
Suggested action
Strictly follow RFC specifications when parsing requests: if both Content-Length and Transfer-Encoding headers are present, the server should prioritize Transfer-Encoding for message body parsing or reject the request outright. For requests that do not conform to the specification, the server should return an error response (e.g., 400 Bad Request ).
PoC
The example request is embedded in the previous section. Send the request to the server, e.g. by echo -ne into nc.
Impact
This bug enables attackers to exploit HTTP request smuggling and response splitting techniques to bypass front-end proxy security checks, thereby delivering malicious requests to the backend server. This may result in sensitive resource disclosure, injection of malicious response content, and other severe consequences.
The version we tested was 84d06b8.
What exactly are you saying the problem is? AFAIK hypercorn (via h11) handles this correctly by prioritizing Transfer-Encoding when both are present (code here), which matches your comment:
if both Content-Length and Transfer-Encoding headers are present, the server should prioritize Transfer-Encoding for message body parsing or reject the request outright
Are you saying you found a situation where it instead prioritizes Content-Length? or are you saying that you think only "reject the request outright" is compatible with the RFC requirement?
What I mean by this was that the server would be better off rejecting such a request, or closing the connection with an error after processing, as according to the RFC 9112 I mentioned above:
Such a message might indicate an attempt to perform request smuggling or response splitting and ought to be handled as an error.