From 98ff38a6f1a8a1e214bd3905a2dcac31ae6c2f52 Mon Sep 17 00:00:00 2001 From: laanwj <126646+laanwj@users.noreply.github.com> Date: Tue, 6 May 2025 15:42:06 +0200 Subject: [PATCH] rpc: Perform HTTP user:pass split once in `RPCAuthorized` --- src/httprpc.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 0c85ba9e83a..8c7cd746255 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -99,14 +99,8 @@ static void JSONErrorReply(HTTPRequest* req, UniValue objError, const JSONRPCReq //This function checks username and password against -rpcauth //entries from config file. -static bool CheckUserAuthorized(std::string_view user_pass) +static bool CheckUserAuthorized(std::string_view user, std::string_view pass) { - if (user_pass.find(':') == std::string::npos) { - return false; - } - std::string_view user = user_pass.substr(0, user_pass.find(':')); - std::string_view pass = user_pass.substr(user_pass.find(':') + 1); - for (const auto& fields : g_rpcauth) { if (!TimingResistantEqual(std::string_view(fields[0]), user)) { continue; @@ -136,10 +130,14 @@ static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUserna if (!userpass_data) return false; strUserPass.assign(userpass_data->begin(), userpass_data->end()); - if (strUserPass.find(':') != std::string::npos) - strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(':')); - - return CheckUserAuthorized(strUserPass); + size_t colon_pos = strUserPass.find(':'); + if (colon_pos == std::string::npos) { + return false; // Invalid basic auth. + } + std::string user = strUserPass.substr(0, colon_pos); + std::string pass = strUserPass.substr(colon_pos + 1); + strAuthUsernameOut = user; + return CheckUserAuthorized(user, pass); } static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)