diff --git a/src/h2.c b/src/h2.c index 3cb0af757..5a8c25068 100644 --- a/src/h2.c +++ b/src/h2.c @@ -203,6 +203,17 @@ static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr, } } + /* We're going to concatenate :authority with :path to form a URI. Some + * characters must absolutely be avoided in :authority to make sure not + * to result in a broken concatenation. See the following links for a + * discussion on this topic: + * https://github.com/httpwg/http2-spec/pull/936 + * https://github.com/haproxy/haproxy/issues/2941 + */ + if ((fields & H2_PHDR_FND_AUTH) && + http_authority_has_forbidden_char(phdr[H2_PHDR_IDX_AUTH])) + goto fail; + if (!(flags & HTX_SL_F_HAS_SCHM)) { /* no scheme, use authority only (CONNECT) */ uri = phdr[H2_PHDR_IDX_AUTH]; diff --git a/src/h3.c b/src/h3.c index eb1ff3575..680589a65 100644 --- a/src/h3.c +++ b/src/h3.c @@ -753,6 +753,21 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, goto out; } + /* We're going to concatenate :authority with :path to form a URI. Some + * characters must absolutely be avoided in :authority to make sure not + * to result in a broken concatenation. See the following links for a + * discussion on this topic: + * https://github.com/httpwg/http2-spec/pull/936 + * https://github.com/haproxy/haproxy/issues/2941 + */ + if (http_authority_has_forbidden_char(authority)) { + TRACE_ERROR("invalid character in authority", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); + h3s->err = H3_ERR_MESSAGE_ERROR; + qcc_report_glitch(h3c->qcc, 1); + len = -1; + goto out; + } + if (!istlen(scheme)) { /* No scheme (CONNECT), use :authority only. */ uri = authority;