]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http-act: emit a warning when a header field name contains forbidden chars
authorWilly Tarreau <w@1wt.eu>
Tue, 4 Apr 2023 03:25:16 +0000 (05:25 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 4 Apr 2023 03:38:01 +0000 (05:38 +0200)
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.

src/http_act.c

index 737d6d8bad4be205a3aa6c3947529d09b38bee95..425b3ab119d56d87c940480b2dea1012b083d204 100644 (file)
@@ -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;
 }