diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch b/debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch new file mode 100644 index 0000000..11ae6f8 --- /dev/null +++ b/debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch @@ -0,0 +1,100 @@ +From: Willy Tarreau <w@1wt.eu> +Date: Tue, 8 Aug 2023 17:18:27 +0200 +Subject: BUG/MAJOR: h3: reject header values containing invalid chars +Origin: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=20a35c4d505475215122d37405ce173075338032 + +In practice it's exactly the same for h3 as 54f53ef7c ("BUG/MAJOR: h2: +reject header values containing invalid chars") was for h2: we must +make sure never to accept NUL/CR/LF in any header value because this +may be used to construct splitted headers on the backend. Hence we +apply the same solution. Here pseudo-headers, headers and trailers are +checked separately, which explains why we have 3 locations instead of +2 for h2 (+1 for response which we don't have here). + +This is marked major for consistency and due to the impact if abused, +but the reality is that at the time of writing, this problem is limited +by the scarcity of the tools which would permit to build such a request +in the first place. But this may change over time. + +This must be backported to 2.6. This depends on the following commit +that exposes the filtering function: + + REORG: http: move has_forbidden_char() from h2.c to http.h + +(cherry picked from commit d13a80abb7c1badaa42045c37cfff79f24f05726) +Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com> +(cherry picked from commit 0404bf14c900d6ac879ec432a198435e0741d835) +Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com> +(cherry picked from commit f58b63af68f239464c29e698a34f08ff3eef862f) + [ad: no http/3 trailer support in 2.6] +Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com> +--- + src/h3.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/src/h3.c b/src/h3.c +index 9b4bc6f096d7..b42d41647e4e 100644 +--- a/src/h3.c ++++ b/src/h3.c +@@ -401,6 +401,7 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, + struct ist scheme = IST_NULL, authority = IST_NULL; + int hdr_idx, ret; + int cookie = -1, last_cookie = -1, i; ++ const char *ctl; + + /* RFC 9114 4.1.2. Malformed Requests and Responses + * +@@ -464,6 +465,24 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, + if (!istmatch(list[hdr_idx].n, ist(":"))) + break; + ++ /* RFC 9114 10.3 Intermediary-Encapsulation Attacks ++ * ++ * While most values that can be encoded will not alter field ++ * parsing, carriage return (ASCII 0x0d), line feed (ASCII 0x0a), ++ * and the null character (ASCII 0x00) might be exploited by an ++ * attacker if they are translated verbatim. Any request or ++ * response that contains a character not permitted in a field ++ * value MUST be treated as malformed ++ */ ++ ++ /* look for forbidden control characters in the pseudo-header value */ ++ ctl = ist_find_ctl(list[hdr_idx].v); ++ if (unlikely(ctl) && http_header_has_forbidden_char(list[hdr_idx].v, ctl)) { ++ TRACE_ERROR("control character present in pseudo-header value", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); ++ len = -1; ++ goto out; ++ } ++ + /* pseudo-header. Malformed name with uppercase character or + * invalid token will be rejected in the else clause. + */ +@@ -561,6 +580,25 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, + } + } + ++ ++ /* RFC 9114 10.3 Intermediary-Encapsulation Attacks ++ * ++ * While most values that can be encoded will not alter field ++ * parsing, carriage return (ASCII 0x0d), line feed (ASCII 0x0a), ++ * and the null character (ASCII 0x00) might be exploited by an ++ * attacker if they are translated verbatim. Any request or ++ * response that contains a character not permitted in a field ++ * value MUST be treated as malformed ++ */ ++ ++ /* look for forbidden control characters in the header value */ ++ ctl = ist_find_ctl(list[hdr_idx].v); ++ if (unlikely(ctl) && http_header_has_forbidden_char(list[hdr_idx].v, ctl)) { ++ TRACE_ERROR("control character present in header value", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); ++ len = -1; ++ goto out; ++ } ++ + if (isteq(list[hdr_idx].n, ist("cookie"))) { + http_cookie_register(list, hdr_idx, &cookie, &last_cookie); + ++hdr_idx; +-- +2.43.0 + |