From: Christopher Faulet Date: Wed, 23 Sep 2026 04:37:37 +0000 (+0000) Subject: BUG/MINOR: http-fetch: http_auth_bearer() must not match a missing header X-Git-Tag: v3.5-dev8~125 X-Git-Url: https://git.kaiwu.me/$%7BISSUES%7D/static/gitweb.js?a=commitdiff_plain;h=39e4fe6e33e599cbc8fa700a6218a5fe6eb7ab47;p=haproxy.git BUG/MINOR: http-fetch: http_auth_bearer() must not match a missing header When http_auth_bearer() was called with a custom header name and this header was not found, the fetch still succeeded and returned an empty string. So a condition like "{ http_auth_bearer(x-tok) -m found }" was true for a request without any such header. Commit 909578520 ("BUG/MINOR: http-fetch: Fix http_auth_bearer() when custom header is used") intended to report a mismatch in this case, as its message says, but only did it for a header with a wrong type. Let's return 0 when the header is not found. A reg-test is added for the fetch with and without a custom header. This should be backported as far as 2.6. --- diff --git a/reg-tests/sample_fetches/http_auth_bearer.vtc b/reg-tests/sample_fetches/http_auth_bearer.vtc new file mode 100644 index 000000000..037c8ee5e --- /dev/null +++ b/reg-tests/sample_fetches/http_auth_bearer.vtc @@ -0,0 +1,57 @@ +varnishtest "http_auth_bearer() on the authorization header and on a custom one" + +# The fetch returns the token of a "Bearer" authorization, either from the +# Authorization header or from the header given as argument. For the custom +# header, the value must be the "Bearer" scheme followed by at least one +# space and the token. When the custom header is absent, nothing is found, +# so that the Authorization header is checked by the next rule. + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + http-request return status 200 hdr tok "%[http_auth_bearer(x-tok)]" if { http_auth_bearer(x-tok) -m found } + http-request return status 201 hdr tok "%[http_auth_bearer]" if { http_auth_bearer -m found } + http-request return status 404 +} -start + +client c1 -connect ${h1_fe_sock} { + # custom header, tokens of several lengths + txreq -hdr "x-tok: Bearer a" + rxresp + expect resp.status == 200 + expect resp.http.tok == "a" + + txreq -hdr "x-tok: Bearer abcdefg" + rxresp + expect resp.status == 200 + expect resp.http.tok == "abcdefg" + + # several spaces are allowed between the scheme and the token + txreq -hdr "x-tok: bearer xyz123" + rxresp + expect resp.status == 200 + expect resp.http.tok == "xyz123" + + # another scheme + txreq -hdr "x-tok: Basic abcdef" + rxresp + expect resp.status == 404 + + # the Authorization header + txreq -hdr "authorization: Bearer abcdef" + rxresp + expect resp.status == 201 + expect resp.http.tok == "abcdef" + + txreq -hdr "authorization: Basic YTpi" + rxresp + expect resp.status == 404 +} -run diff --git a/src/http_fetch.c b/src/http_fetch.c index 6133983c1..f944925c9 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -1486,6 +1486,8 @@ static int smp_fetch_http_auth_bearer(const struct arg *args, struct sample *smp ctx.value = istskip(ctx.value, ' '); chunk_initlen(&bearer_val, istptr(ctx.value), 0, istlen(ctx.value)); } + else + return 0; } else { txn = smp->strm->txn.http;