From: Willy Tarreau Date: Tue, 4 Apr 2023 03:25:16 +0000 (+0200) Subject: MINOR: http-act: emit a warning when a header field name contains forbidden chars X-Git-Tag: v2.8-dev7~112 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=db12c0dd1049f7ac48b3145884439d722ad8c434;p=thirdparty%2Fhaproxy.git MINOR: http-act: emit a warning when a header field name contains forbidden chars As found in issue #2089, it's easy to mistakenly paste a colon in a header name, or other chars (e.g. spaces) when quotes are in use, and this causes all sort of trouble in field because such chars are rejected by the peer. Better try to detect these upfront. That's what we're doing here during the parsing of the add-header/set-header/early-hint actions, where a warning is emitted if a non-token character is found in a header name. A special case is made for the colon at the beginning so that it remains possible to place any future pseudo-headers that may appear. E.g: [WARNING] (14388) : config : parsing [badchar.cfg:23] : header name 'X-Content-Type-Options:' contains forbidden character ':'. This should be backported to 2.7, and ideally it should be turned to an error in future versions. --- diff --git a/src/http_act.c b/src/http_act.c index 737d6d8bad..425b3ab119 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -1484,6 +1484,7 @@ static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg struct act_rule *rule, char **err) { int cap = 0, cur_arg; + const char *p; if (args[*orig_arg-1][0] == 'e') { rule->action = ACT_CUSTOM; @@ -1533,6 +1534,23 @@ static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg px->conf.lfs_file = strdup(px->conf.args.file); px->conf.lfs_line = px->conf.args.line; + /* some characters are totally forbidden in header names and + * may happen by accident when writing configs, causing strange + * failures in field. Better catch these ones early, nobody will + * miss them. In particular, a colon at the end (or anywhere + * after the first char) or a space/cr anywhere due to misplaced + * quotes are hard to spot. + */ + for (p = istptr(rule->arg.http.str); p < istend(rule->arg.http.str); p++) { + if (HTTP_IS_TOKEN(*p)) + continue; + if (p == istptr(rule->arg.http.str) && *p == ':') + continue; + /* we only report this as-is but it will not cause an error */ + memprintf(err, "header name '%s' contains forbidden character '%c'", istptr(rule->arg.http.str), *p); + break; + } + *orig_arg = cur_arg + 1; return ACT_RET_PRS_OK; }