From: Christopher Faulet Date: Wed, 23 Sep 2026 04:38:06 +0000 (+0000) Subject: BUG/MINOR: http-fetch: fix the space check of http_auth_bearer() X-Git-Tag: v3.5-dev8~124 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=1afc7ca3ad95638080de70538ed75c3bf55f98e6;p=haproxy.git BUG/MINOR: http-fetch: fix the space check of http_auth_bearer() When http_auth_bearer() was called with a custom header name, a test was performed to know if the value contained a space after the scheme, by comparing the length of the scheme with the length of the header value. But istsplit() had already advanced past the scheme and the space at this point, so the comparison was made with the length of the token instead: - a token of exactly 6 characters, the length of "Bearer", was reported as a mismatch, e.g. "Bearer abcdef"; - a lone "Bearer" without any space was accepted and returned an empty token. Let's compare with the length of the value before it is split. The reg-test is extended with these two cases. This should be backported to all supported versions. --- diff --git a/reg-tests/sample_fetches/http_auth_bearer.vtc b/reg-tests/sample_fetches/http_auth_bearer.vtc index 037c8ee5e..4f76a508f 100644 --- a/reg-tests/sample_fetches/http_auth_bearer.vtc +++ b/reg-tests/sample_fetches/http_auth_bearer.vtc @@ -3,8 +3,11 @@ 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. +# space and the token, whatever the token length. In particular a token +# of 6 characters, as long as the word "Bearer" itself, must be found, and +# a lone "Bearer" without any token is not a Bearer authorization. When the +# custom header is absent, nothing is found, so that the Authorization +# header is checked by the next rule. feature ignore_unknown_macro @@ -29,6 +32,11 @@ client c1 -connect ${h1_fe_sock} { expect resp.status == 200 expect resp.http.tok == "a" + txreq -hdr "x-tok: Bearer abcdef" + rxresp + expect resp.status == 200 + expect resp.http.tok == "abcdef" + txreq -hdr "x-tok: Bearer abcdefg" rxresp expect resp.status == 200 @@ -40,7 +48,11 @@ client c1 -connect ${h1_fe_sock} { expect resp.status == 200 expect resp.http.tok == "xyz123" - # another scheme + # no token, or another scheme + txreq -hdr "x-tok: Bearer" + rxresp + expect resp.status == 404 + txreq -hdr "x-tok: Basic abcdef" rxresp expect resp.status == 404 diff --git a/src/http_fetch.c b/src/http_fetch.c index f944925c9..c7c967cb3 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -1473,10 +1473,11 @@ static int smp_fetch_http_auth_bearer(const struct arg *args, struct sample *smp ctx.blk = NULL; if (http_find_header(htx, hdr_name, &ctx, 0)) { + struct ist value = ctx.value; struct ist type = istsplit(&ctx.value, ' '); /* no space was found or the space is the first character or no "Bearer" method */ - if (!istlen(type) || istlen(type) == istlen(ctx.value) || !isteqi(type, ist("Bearer"))) + if (!istlen(type) || istlen(type) == istlen(value) || !isteqi(type, ist("Bearer"))) return 0; /* There must be "at least" one space character between