From 2a068def549d5c96985927c5421df1e79a41bd49 Mon Sep 17 00:00:00 2001 From: metsw24-max Date: Thu, 20 Aug 2026 04:34:46 +0530 Subject: [PATCH] validate bearer scheme in get_bearer_token_auth (#2544) --- httplib.h | 12 ++++++++++-- test/test.cc | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/httplib.h b/httplib.h index ed49c83b..4f81ad49 100644 --- a/httplib.h +++ b/httplib.h @@ -10460,8 +10460,16 @@ inline bool set_socket_opt(socket_t sock, int level, int optname, int optval) { inline std::string get_bearer_token_auth(const Request &req) { if (req.has_header("Authorization")) { constexpr auto bearer_header_prefix_len = detail::str_len("Bearer "); - return req.get_header_value("Authorization") - .substr(bearer_header_prefix_len); + auto value = req.get_header_value("Authorization"); + // Only strip the prefix when the value actually carries the "Bearer " + // scheme (case-insensitive per RFC 7235). Without this the fixed-length + // substr throws out_of_range on a value shorter than the prefix, and a + // different scheme (e.g. "Basic ...") is mistaken for a bearer token. + if (value.size() >= bearer_header_prefix_len && + detail::case_ignore::equal(value.substr(0, bearer_header_prefix_len), + "Bearer ")) { + return value.substr(bearer_header_prefix_len); + } } return ""; } diff --git a/test/test.cc b/test/test.cc index fa52c349..5a0b13af 100644 --- a/test/test.cc +++ b/test/test.cc @@ -1560,6 +1560,34 @@ TEST(GetHeaderValueTest, RegularInvalidValueInt) { EXPECT_TRUE(is_invalid_value); } +TEST(BearerTokenAuthTest, SchemeValidation) { + // A value shorter than "Bearer " must not throw from the fixed-length + // substr, and a non-Bearer scheme must not be reported as a token. + { + Request req; + req.set_header("Authorization", "x"); + EXPECT_EQ("", get_bearer_token_auth(req)); + } + { + Request req; + req.set_header("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); + EXPECT_EQ("", get_bearer_token_auth(req)); + } + + // A well-formed header still yields the token; the scheme is + // case-insensitive. + { + Request req; + req.set_header("Authorization", "Bearer abc123"); + EXPECT_EQ("abc123", get_bearer_token_auth(req)); + } + { + Request req; + req.set_header("Authorization", "bearer abc123"); + EXPECT_EQ("abc123", get_bearer_token_auth(req)); + } +} + TEST(GetHeaderValueTest, OutOfRangeValueInt) { // An all-digit value that overflows size_t must be reported as invalid, not // silently saturated/truncated: parsing at size_t width would otherwise wrap