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)
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);