From 8fc0d2fbd5ac3a5b065a692ec9380d4da2aebd23 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 17 Jun 2025 11:33:53 +0200 Subject: [PATCH] MINOR: h3: reject invalid :status in response Add checks to ensure that :status pseudo-header received in HTTP/3 response is valid. If either the header is not provided, or it isn't a 3 digit numbers, the response is considered as invalid and the streams is rejected. Also, glitch counter is now incremented in any of these cases. This should fix coverity report from github issue #3009. --- src/h3.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/h3.c b/src/h3.c index 4f25f1f70..9881424b7 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1189,6 +1189,14 @@ static ssize_t h3_resp_headers_to_htx(struct qcs *qcs, const struct buffer *buf, * invalid token will be rejected in the else clause. */ if (isteq(list[hdr_idx].n, ist(":status"))) { + if (isttest(status)) { + TRACE_ERROR("duplicated status 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; + } + status = list[hdr_idx].v; } else { @@ -1205,6 +1213,25 @@ static ssize_t h3_resp_headers_to_htx(struct qcs *qcs, const struct buffer *buf, flags |= HTX_SL_F_VER_11; flags |= HTX_SL_F_XFER_LEN; + if (istlen(status) != 3) { + TRACE_ERROR("invalid status code", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); + h3s->err = H3_ERR_MESSAGE_ERROR; + qcc_report_glitch(qcs->qcc, 1); + len = -1; + goto out; + } + + h = status.ptr[0] - '0'; + t = status.ptr[1] - '0'; + u = status.ptr[2] - '0'; + if (h > 9 || t > 9 || u > 9) { + TRACE_ERROR("invalid status code", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); + h3s->err = H3_ERR_MESSAGE_ERROR; + qcc_report_glitch(qcs->qcc, 1); + len = -1; + goto out; + } + sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/3.0"), status, ist("")); if (!sl) { TRACE_ERROR("cannot allocate HTX start-line", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); @@ -1216,15 +1243,6 @@ static ssize_t h3_resp_headers_to_htx(struct qcs *qcs, const struct buffer *buf, if (fin) sl->flags |= HTX_SL_F_BODYLESS; - h = status.ptr[0] - '0'; - t = status.ptr[1] - '0'; - u = status.ptr[2] - '0'; - if (h > 9 || t > 9 || u > 9) { - TRACE_ERROR("invalid status code", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); - h3s->err = H3_ERR_MESSAGE_ERROR; - len = -1; - goto out; - } sl->info.res.status = h * 100 + t * 10 + u; /* now treat standard headers */