Skip to content

Commit 47d13c6

Browse files
a-denoyellecapflam
authored andcommitted
BUG/MEDIUM: h3: ensure the ":method" pseudo header is totally valid
Ensure pseudo-header method is only constitued of valid characters according to RFC 9110. If an invalid value is found, the request is rejected and stream is resetted. Previously only characters forbidden in headers were rejected (NUL/CR/LF), but this is insufficient for :method, where some other forbidden chars might be used to trick a non-compliant backend server into seeing a different path from the one seen by haproxy. Note that header injection is not possible though. This must be backported up to 2.6. Many thanks to Yuki Mogi of FFRI Security Inc for the detailed report that allowed to quicky spot, confirm and fix the problem. (cherry picked from commit 789d4ab) Signed-off-by: Christopher Faulet <[email protected]>
1 parent a8740d1 commit 47d13c6

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

include/haproxy/http.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,21 @@ static inline int http_header_has_forbidden_char(const struct ist ist, const cha
197197
return 0;
198198
}
199199

200+
/* Check that method only contains token as required.
201+
* See RFC 9110 9. Methods
202+
*/
203+
static inline int http_method_has_forbidden_char(const struct ist ist)
204+
{
205+
const char *start = istptr(ist);
206+
207+
do {
208+
if (!HTTP_IS_TOKEN(*start))
209+
return 1;
210+
start++;
211+
} while (start < istend(ist));
212+
return 0;
213+
}
214+
200215
/* Looks into <ist> for forbidden characters for :path values (0x00..0x1F,
201216
* 0x20, 0x23), starting at pointer <start> which must be within <ist>.
202217
* Returns non-zero if such a character is found, 0 otherwise. When run on

src/h3.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,15 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
630630
len = -1;
631631
goto out;
632632
}
633+
634+
if (!istlen(list[hdr_idx].v) || http_method_has_forbidden_char(list[hdr_idx].v)) {
635+
TRACE_ERROR("invalid method pseudo-header", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
636+
h3s->err = H3_ERR_MESSAGE_ERROR;
637+
qcc_report_glitch(h3c->qcc, 1);
638+
len = -1;
639+
goto out;
640+
}
641+
633642
meth = list[hdr_idx].v;
634643
}
635644
else if (isteq(list[hdr_idx].n, ist(":path"))) {

0 commit comments

Comments
 (0)