In continuation with
9a05c1f574 ("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/haproxy@formilux.org/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.
h1_parse_upgrade_header(h1m, v);
}
else if (!(h1m->flags & H1_MF_RESP) && isteqi(n, ist("host"))) {
- if (host_idx == -1)
+ if (host_idx == -1) {
host_idx = hdr_count;
+ if (http_authority_has_forbidden_char(v)) {
+ state = H1_MSG_HDR_L2_LWS;
+ ptr = v.ptr; /* Set ptr on the error */
+ goto http_msg_invalid;
+ }
+ }
else {
if (!isteqi(v, hdr[host_idx].v)) {
state = H1_MSG_HDR_L2_LWS;
}
if (isteq(list[idx].n, ist("host"))) {
+ /* skip duplicates */
if (fields & H2_PHDR_FND_HOST)
continue;
fields |= H2_PHDR_FND_HOST;
+ if (http_authority_has_forbidden_char(list[idx].v))
+ goto fail;
}
if (isteq(list[idx].n, ist("content-length"))) {
if (isteq(list[hdr_idx].n, ist("host"))) {
struct ist prev_auth = authority;
- if (h3_set_authority(qcs, &authority, list[hdr_idx].v)) {
+ if (http_authority_has_forbidden_char(list[hdr_idx].v) ||
+ h3_set_authority(qcs, &authority, list[hdr_idx].v)) {
h3s->err = H3_ERR_MESSAGE_ERROR;
qcc_report_glitch(h3c->qcc, 1);
len = -1;