From: Willy Tarreau Date: Mon, 27 Jul 2026 09:45:17 +0000 (+0200) Subject: BUG/MINOR: http-act: reject a negative capture id in the capture actions X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=f571e23cc0e844d5be3360c937886ad46cf1f0cb;p=thirdparty%2Fhaproxy.git BUG/MINOR: http-act: reject a negative capture id in the capture actions "http-request capture id " and "http-response capture id " 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; never matches a negative so the walk ends on a NULL 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. --- diff --git a/src/http_act.c b/src/http_act.c index 02d8f4496..02e1bdbe1 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -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;