Explorar el Código

validate bearer scheme in get_bearer_token_auth (#2544)

metsw24-max hace 1 semana
padre
commit
2a068def54
Se han modificado 2 ficheros con 38 adiciones y 2 borrados
  1. 10 2
      httplib.h
  2. 28 0
      test/test.cc

+ 10 - 2
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 "";
 }

+ 28 - 0
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