]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: http-ana: don't crash on "keep-query" in a response redirect
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 6 Aug 2026 07:28:26 +0000 (09:28 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 7 Aug 2026 08:29:19 +0000 (10:29 +0200)
http_apply_redirect_rule() always takes its HTX from the request channel
(htxbuf(&s->req.buf)), and the "keep-query" option rebuilds the query string
from the request start line. This works for a request redirect, but the
option is also accepted on "http-response redirect", and by then the request
has usually been forwarded and its buffer is empty, so http_get_stline()
returns NULL and htx_sl_req_uri() dereferences it. Thus a rule such as
"http-response redirect location /moved keep-query" crashes on the first
request that matches it (reproduced with a plain "GET /foo?a=b").

There is no query-string to preserve once the request is gone, so let's skip
that part when the start line is no longer available and emit the location
as-is. Scheme- and prefix-based redirects are rejected on the response path
by the parser, so they are left untouched.

This was introduced in 3.1 by commit b2877db47 ("MINOR: http-ana: Add
option to keep query-string on a localtion-based redirect"). It must be
backported to 3.1.

Reported-by: Claude (ANT-2026-7AZMS41X)
src/http_ana.c

index 41eaf68734310048b0f73e8a009438edf757c9a1..30451da4c5c5d76926ee1872e081f5b0006af453 100644 (file)
@@ -2550,7 +2550,14 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
                                if (ptr != NULL)
                                        sep = ((ptr+1 != b_tail(chunk)) ? '&' : '\0');
 
+                               /* On the response path the request may already have
+                                * been forwarded and its start line released, in
+                                * which case there is no query-string to preserve.
+                                */
                                sl = http_get_stline(htx);
+                               if (!sl)
+                                       break;
+
                                parser = http_uri_parser_init(htx_sl_req_uri(sl));
                                path = http_parse_path(&parser);
                                ptr = istptr(path);