apache/trafficserver

Invalid HTTP/1.1 chunk sizes are accepted and forwarded

kenballus opened this issue · 2 comments

ATS's chunked message body validation has problems dealing with malformed chunk sizes. When a chunk size matches the following regular expression: \d+[^\d]+ (i.e. some digits followed by some non-digits) ATS ignores the non-digits and forwards them as-is instead of either normalizing them away or rejecting the request.

Here's an example request that demonstrates the bug:

POST / HTTP/1.1\r\n
Host: whatever\r\n
Transfer-Encoding: chunked\r\n
\r\n
1these-bytes-never-get-validated\r\n
Z\r\n
0\r\n
\r\n

Here's what ATS forwards to its backend:

POST / HTTP/1.1\r\n
Host: whatever\r\n
Client-ip: 172.18.0.1\r\n
X-Forwarded-For: 172.18.0.1\r\n
Via: http/1.1 traffic_server[94a0796c-32b5-413c-8bd6-b2ad4990c576] (ApacheTrafficServer/10.0.0)\r\n
Transfer-Encoding: chunked\r\n
\r\n
1these-bytes-never-get-validated\r\n
Z\r\n
0\r\n
\r\n

Note that the malformed chunk size made it through the transformation. Other reverse proxies (Apache, Caddy, Envoy, HAProxy, nghttpx, LiteSpeed, Pound, Squid, Traefik, Varnish, and more) reject the request. The specification defines that chunk-size = 1*HEXDIG, so this is a correct behavior. Another arguably correct behavior would be to delete the invalid characters upon re-emission (this is what H2O does).

This bug is exploitable for request smuggling to backend servers that interpret chunk sizes as their longest valid prefix. There are many such servers.

Thank you for the report. I'm working on fixing it. If you have security concerns, please contact us by email.
https://apache.org/security/
security@trafficserver.apache.org