hypercorn icon indicating copy to clipboard operation
hypercorn copied to clipboard

Incorrect Parsing When Both Content-Length and Transfer-Encoding Are Present

Open TUO-Wu opened this issue 9 months ago • 2 comments

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-Encoding and a Content-Length header field, the Transfer-Encoding overrides the Content-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.

TUO-Wu avatar Mar 11 '25 03:03 TUO-Wu

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?

njsmith avatar Mar 11 '25 03:03 njsmith

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.

TUO-Wu avatar Mar 11 '25 03:03 TUO-Wu