Skip to content

Commit df00164

Browse files
committed
BUG/MEDIUM: h1/h2/h3: reject forbidden chars in the Host header field
In continuation with 9a05c1f ("BUG/MEDIUM: h2/h3: reject some forbidden chars in :authority before reassembly") and the discussion in issue #2941, @DemiMarie rightfully suggested that Host should also be sanitized, because it is sometimes used in concatenation, such as this: http-request set-url https://%[req.hdr(host)]%[pathq] which was proposed as a workaround for h2 upstream servers that require :authority here: https://www.mail-archive.com/[email protected]/msg43261.html The current patch then adds the same check for forbidden chars in the Host header, using the same function as for the patch above, since in both cases we validate the host:port part of the authority. This way we won't reconstruct ambiguous URIs by concatenating Host and path. Just like the patch above, this can be backported afer a period of observation.
1 parent b84762b commit df00164

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

src/h1.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,8 +986,14 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
986986
h1_parse_upgrade_header(h1m, v);
987987
}
988988
else if (!(h1m->flags & H1_MF_RESP) && isteqi(n, ist("host"))) {
989-
if (host_idx == -1)
989+
if (host_idx == -1) {
990990
host_idx = hdr_count;
991+
if (http_authority_has_forbidden_char(v)) {
992+
state = H1_MSG_HDR_L2_LWS;
993+
ptr = v.ptr; /* Set ptr on the error */
994+
goto http_msg_invalid;
995+
}
996+
}
991997
else {
992998
if (!isteqi(v, hdr[host_idx].v)) {
993999
state = H1_MSG_HDR_L2_LWS;

src/h2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,13 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
411411
}
412412

413413
if (isteq(list[idx].n, ist("host"))) {
414+
/* skip duplicates */
414415
if (fields & H2_PHDR_FND_HOST)
415416
continue;
416417

417418
fields |= H2_PHDR_FND_HOST;
419+
if (http_authority_has_forbidden_char(list[idx].v))
420+
goto fail;
418421
}
419422

420423
if (isteq(list[idx].n, ist("content-length"))) {

src/h3.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,8 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
863863
if (isteq(list[hdr_idx].n, ist("host"))) {
864864
struct ist prev_auth = authority;
865865

866-
if (h3_set_authority(qcs, &authority, list[hdr_idx].v)) {
866+
if (http_authority_has_forbidden_char(list[hdr_idx].v) ||
867+
h3_set_authority(qcs, &authority, list[hdr_idx].v)) {
867868
h3s->err = H3_ERR_MESSAGE_ERROR;
868869
qcc_report_glitch(h3c->qcc, 1);
869870
len = -1;

0 commit comments

Comments
 (0)