From 80b55971cdebe9321ec6fef8ed4272f3023e8570 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 19 Aug 2021 23:06:58 +0200 Subject: [PATCH] [PATCH] BUG/MEDIUM: h2: match absolute-path not path-absolute for :path RFC7540 states that :path follows RFC3986's path-absolute. However that was a bug introduced in the spec between draft 04 and draft 05 of the spec, which implicitly causes paths starting with "//" to be forbidden. HTTP/1 (and now HTTP core semantics) made it explicit that the request-target in origin-form follows a purposely defined absolute-path defined as 1*(/ segment) to explicitly allow "//". http2bis now fixes this by relying on absolute-path so that "//" becomes valid and matches other versions. Full discussion here: https://lists.w3.org/Archives/Public/ietf-http-wg/2021JulSep/0245.html This issue appeared in haproxy with commit 4b8852c70 ("BUG/MAJOR: h2: verify that :path starts with a '/' before concatenating it") when making the checks on :path fully comply with the spec, and was backported as far as 2.0, so this fix must be backported there as well to allow "//" in H2 again. (cherry picked from commit 46b7dff8f08cb6c5c3004d8874d6c5bc689a4c51) Signed-off-by: Willy Tarreau (cherry picked from commit 512cee88df5c40f1d3901a82cf6643fe9f74229e) Signed-off-by: Willy Tarreau (cherry picked from commit 65b9cf31a1975eb32e6696059c2bf9f0cfca2dff) Signed-off-by: Willy Tarreau Gbp-Pq: Name 0001-BUG-MEDIUM-h2-match-absolute-path-not-path-absolute-.patch --- src/h2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/h2.c b/src/h2.c index 93bbc9a..bda4b05 100644 --- a/src/h2.c +++ b/src/h2.c @@ -238,6 +238,9 @@ static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr, /* 7540#8.1.2.3: :path must not be empty, and must be either * '*' or an RFC3986 "path-absolute" starting with a "/" but * not with "//". + * However, this "path-absolute" was a mistake which was + * later fixed in http2bis as "absolute-path" to match + * HTTP/1, thus also allowing "//". */ if (unlikely(!phdr[H2_PHDR_IDX_PATH].len)) goto fail; @@ -245,9 +248,6 @@ static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr, if (!isteq(phdr[H2_PHDR_IDX_PATH], ist("*"))) goto fail; } - else if (phdr[H2_PHDR_IDX_PATH].len > 1 && - phdr[H2_PHDR_IDX_PATH].ptr[1] == '/') - goto fail; } if (!(flags & HTX_SL_F_HAS_SCHM)) { -- 2.30.2