summaryrefslogtreecommitdiffstats
path: root/debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch')
-rw-r--r--debian/patches/BUG-MAJOR-h3-reject-header-values-containing-invalid.patch100
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
+