From: Greg Kroah-Hartman Date: Thu, 9 Apr 2026 11:06:45 +0000 (+0200) Subject: BUG/MINOR: http-act: validate decoded lengths in *-headers-bin X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0cde3cd4dfbc36b4a79e43d97f839ce851deaaff;p=thirdparty%2Fhaproxy.git BUG/MINOR: http-act: validate decoded lengths in *-headers-bin http_action_set_headers_bin() decodes varint name and value lengths from a binary sample but never validates that the decoded length fits in the remaining sample data before constructing the ist. If the value's varint decodes to a large number with only a few bytes following, v.len exceeds the buffer and http_add_header() memcpys past the sample, copying adjacent heap data into a header sent to the backend (or client, with http-response). The intended source for this action is the hdrs_bin sample fetch which produces well-formed output, but nothing prevents an admin from feeding it req.body or another untrusted source. With: http-request set-var(txn.h) req.body http-request add-headers-bin var(txn.h) a POST body of [05]"X-Foo"[c8]"AB" produces v = {ptr="AB", len=200} and 198 bytes of adjacent heap data go into X-Foo. http_action_del_headers_bin() was fixed too. Compare spoe_decode_buffer() which has the equivalent check. Validate both name and value lengths against remaining data. No backport needed. --- diff --git a/src/http_act.c b/src/http_act.c index 57e390b3f..f982ce068 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -1511,11 +1511,15 @@ static enum act_return http_action_set_headers_bin(struct act_rule *rule, struct goto leave; } + if (sz > (uint64_t)(end - p)) + goto fail_rewrite; n = ist2(p, sz); p += sz; if (decode_varint(&p, end, &sz) == -1) goto fail_rewrite; + if (sz > (uint64_t)(end - p)) + goto fail_rewrite; v = ist2(p, sz); p += sz; @@ -1935,6 +1939,8 @@ static enum act_return http_action_del_headers_bin(struct act_rule *rule, struct goto fail_rewrite; if (!sz) goto leave; + if (sz > (uint64_t)(end - p)) + goto fail_rewrite; n = ist2(p, sz); p += sz;