]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: h3: reject invalid :status in response
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 17 Jun 2025 09:33:53 +0000 (11:33 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 17 Jun 2025 09:39:35 +0000 (11:39 +0200)
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

index 4f25f1f7065a507fd9c06f42aaa0765c171b6efb..9881424b75c347f40976d68c3877b8259f905864 100644 (file)
--- 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,26 +1213,36 @@ 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;
 
-       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);
+       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;
        }
 
-       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;
+               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);
+               h3s->err = H3_ERR_MESSAGE_ERROR;
+               len = -1;
+               goto out;
+       }
+
+       if (fin)
+               sl->flags |= HTX_SL_F_BODYLESS;
+
        sl->info.res.status = h * 100 + t * 10 + u;
 
        /* now treat standard headers */