]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: http-act: reject a negative capture id in the capture actions
authorWilly Tarreau <w@1wt.eu>
Mon, 27 Jul 2026 09:45:17 +0000 (11:45 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Jul 2026 13:31:56 +0000 (15:31 +0200)
"http-request capture <expr> id <idx>" and "http-response capture <expr> id
<idx>" parse their identifier with strtol() and only reject trailing garbage:

id = strtol(args[cur_arg], &error, 10);
if (*error != '\0') {
memprintf(err, "cannot parse id '%s'", args[cur_arg]);

A negative identifier is therefore accepted at boot. The check functions only
verify the upper bound ("idx >= px->nb_req_cap"), and even that only for a proxy
with the frontend capability, so nothing complains. At run time,
http_action_req_capture_by_id() looks the slot up by walking the capture list
backwards:

for (h = fe->req_cap, i = fe->nb_req_cap - 1;
     h != NULL && i != rule->arg.capid.idx ;
     i--, h = h->next);
if (!h)
return ACT_RET_CONT;

<i> never matches a negative <idx> so the walk ends on a NULL <h> and the action
silently does nothing. There is no out-of-bounds access here, unlike in the
"capture.req.hdr" sample fetch, but a configuration that can only ever be a
no-op must be rejected rather than silently ignored.

Let's reject negative ids where they are parsed, which also covers the proxies
that have no frontend capability and are thus not checked at all.

This should be backported to all supported versions.

src/http_act.c

index 02d8f4496304396fb4a4786180fce1e80bf97804..02e1bdbe12d68e1720e63877b541bc611bbfb0bb 100644 (file)
@@ -994,7 +994,7 @@ static enum act_parse_ret parse_http_req_capture(const char **args, int *orig_ar
                }
 
                id = strtol(args[cur_arg], &error, 10);
-               if (*error != '\0') {
+               if (*error != '\0' || id < 0) {
                        memprintf(err, "cannot parse id '%s'", args[cur_arg]);
                        release_sample_expr(expr);
                        return ACT_RET_PRS_ERR;
@@ -1141,7 +1141,7 @@ static enum act_parse_ret parse_http_res_capture(const char **args, int *orig_ar
        }
 
        id = strtol(args[cur_arg], &error, 10);
-       if (*error != '\0') {
+       if (*error != '\0' || id < 0) {
                memprintf(err, "cannot parse id '%s'", args[cur_arg]);
                release_sample_expr(expr);
                return ACT_RET_PRS_ERR;