From fc4fdcb5aaf06167ea60293ff1f8791b7ed9b0c8 Mon Sep 17 00:00:00 2001 From: kirill Date: Wed, 3 Jun 2026 20:00:07 +0000 Subject: [PATCH] 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@ --- usr.sbin/httpd/http.h | 3 ++- usr.sbin/httpd/server_http.c | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) 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 */