1
0
mirror of https://github.com/openbsd/src.git synced 2026-06-18 07:13:36 +02:00

httpd: reject CL.TE request framing

RFC 9112 sections 6.1 and 6.3 identify a request containing both
Transfer-Encoding and Content-Length as ambiguous request smuggling
input. httpd is the origin server, not an intermediary, so it should not
rewrite the message and continue processing it.

Reject chunked requests that also carry Content-Length before method
specific body handling or FastCGI parameter generation; this avoids
exposing inconsistent framing metadata to applications.

Reproted by: Stuart Thomas

OK: rsaodwski@
This commit is contained in:
kirill
2026-06-03 20:00:07 +00:00
parent 690673315b
commit fc4fdcb5aa
2 changed files with 16 additions and 2 deletions
+2 -1
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: http.h,v 1.17 2024/03/24 10:53:27 job Exp $ */
/* $OpenBSD: http.h,v 1.18 2026/06/03 20:00:07 kirill Exp $ */
/*
* Copyright (c) 2012 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -241,6 +241,7 @@ struct http_descriptor {
char *http_host;
enum httpmethod http_method;
int http_chunked;
int http_cl;
char *http_version;
unsigned int http_status;
+14 -1
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: server_http.c,v 1.164 2026/06/03 19:25:06 rsadowski Exp $ */
/* $OpenBSD: server_http.c,v 1.165 2026/06/03 20:00:07 kirill Exp $ */
/*
* Copyright (c) 2020 Matthias Pressfreund <mpfr@fn.de>
@@ -118,6 +118,7 @@ server_httpdesc_free(struct http_descriptor *desc)
desc->http_lastheader = NULL;
desc->http_method = 0;
desc->http_chunked = 0;
desc->http_cl = 0;
}
int
@@ -384,6 +385,7 @@ server_read_http(struct bufferevent *bev, void *arg)
server_abort_http(clt, 500, errstr);
goto abort;
}
desc->http_cl = 1;
}
if (strcasecmp("Transfer-Encoding", key) == 0 &&
@@ -406,6 +408,17 @@ server_read_http(struct bufferevent *bev, void *arg)
return;
}
/*
* RFC 9112 sections 6.1 and 6.3 forbid sending
* Content-Length with Transfer-Encoding and identify
* this framing ambiguity as request smuggling input.
* httpd is an origin server, so reject it.
*/
if (desc->http_chunked && desc->http_cl) {
server_abort_http(clt, 400, "malformed");
return;
}
switch (desc->http_method) {
case HTTP_METHOD_CONNECT:
/* No body allowed */