diff --git a/usr.sbin/httpd/http.h b/usr.sbin/httpd/http.h index 7fc6f6f33a3..e09c7c1123a 100644 --- a/usr.sbin/httpd/http.h +++ b/usr.sbin/httpd/http.h @@ -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 @@ -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; diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c index 0a600cdfd98..5ecb65c1026 100644 --- a/usr.sbin/httpd/server_http.c +++ b/usr.sbin/httpd/server_http.c @@ -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 @@ -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 */