diff --git a/include/haproxy/http.h b/include/haproxy/http.h index e28f3cc90..f7f804d7d 100644 --- a/include/haproxy/http.h +++ b/include/haproxy/http.h @@ -197,6 +197,21 @@ static inline int http_header_has_forbidden_char(const struct ist ist, const cha return 0; } +/* Check that method only contains token as required. + * See RFC 9110 9. Methods + */ +static inline int http_method_has_forbidden_char(const struct ist ist) +{ + const char *start = istptr(ist); + + do { + if (!HTTP_IS_TOKEN(*start)) + return 1; + start++; + } while (start < istend(ist)); + return 0; +} + /* Looks into for forbidden characters for :path values (0x00..0x1F, * 0x20, 0x23), starting at pointer which must be within . * Returns non-zero if such a character is found, 0 otherwise. When run on diff --git a/src/h3.c b/src/h3.c index 2aa4fa78e..fac9846d9 100644 --- a/src/h3.c +++ b/src/h3.c @@ -630,6 +630,15 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, len = -1; goto out; } + + if (!istlen(list[hdr_idx].v) || http_method_has_forbidden_char(list[hdr_idx].v)) { + TRACE_ERROR("invalid method pseudo-header", 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; + } + meth = list[hdr_idx].v; } else if (isteq(list[hdr_idx].n, ist(":path"))) {