]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: http-act: validate decoded lengths in *-headers-bin
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Apr 2026 11:06:45 +0000 (13:06 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 9 Apr 2026 15:10:56 +0000 (17:10 +0200)
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.

src/http_act.c

index 57e390b3fb8e5570df8ea5e4f7b193c731904e5e..f982ce068869f04c30caab6974f586f1daca33de 100644 (file)
@@ -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;