diff options
| author | Hauke Mehrtens | 2026-06-13 00:40:15 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-15 23:30:15 +0000 |
| commit | ae015e099986ceace44975cb69629841a2d58d37 (patch) | |
| tree | c02f54e973bc643ce9dc6c02ccc6dff483d249e3 | |
| parent | 1b624f8f814ed568608d756512892416e0431d77 (diff) | |
| download | uhttpd-ae015e099986ceace44975cb69629841a2d58d37.tar.gz | |
client: reject unhandled Transfer-Encoding values
client_parse_header() lowercases header names but compared the
Transfer-Encoding value with a case-sensitive strcmp(val, "chunked").
RFC 9112 6.1 requires transfer-coding tokens to be matched
case-insensitively, so a request with "Transfer-Encoding: Chunked" was
accepted but chunked framing was never enabled. The declared body was
then left unread and, on a keep-alive connection, parsed as the next
HTTP request (request smuggling).
Match "chunked" with strcasecmp and reject any other transfer-coding we
do not implement with 501, instead of silently ignoring it and losing
track of the message framing.
Link: https://github.com/openwrt/uhttpd/security/advisories/GHSA-mcfg-c4r7-pjpf
Reported-by: @dyingc
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
| -rw-r--r-- | client.c | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -403,8 +403,16 @@ static void client_parse_header(struct client *cl, char *data) } r->content_length = (int)length; } else if (!strcmp(data, "transfer-encoding")) { - if (!strcmp(val, "chunked")) + /* RFC 9112 6.1: transfer-coding tokens are case-insensitive. + * Reject any coding we do not implement instead of silently + * ignoring it, otherwise the body framing would be unknown and + * the unread body could be parsed as the next request. */ + if (!strcasecmp(val, "chunked")) { r->transfer_chunked = true; + } else { + uh_header_error(cl, 501, "Not Implemented"); + return; + } } else if (!strcmp(data, "connection")) { if (!strcasecmp(val, "close")) r->connection_close = true; |