Include v1 services key and v2 services signature in Brave Search requests (#36806)

Add the `BraveServiceKey` header (v1 key) and `Authorization` header (v2 key signature) to Brave Search requests. This will be used to reduce captcha occurrences for browser users.
This commit is contained in:
Darnell Andries
2026-05-29 10:56:37 -07:00
committed by GitHub
parent ed40ee21a6
commit 801aeaffbb
6 changed files with 88 additions and 1 deletions
+1
View File
@@ -50,6 +50,7 @@ source_set("browser_tests") {
"//components/content_settings/core/browser:cookie_settings",
"//components/prefs",
"//services/network/public/cpp",
"//testing/gmock",
]
if (!is_android) {
deps += [ "//chrome/test:test_support_ui" ]
@@ -6,10 +6,14 @@
#include "brave/browser/net/brave_service_key_network_delegate_helper.h"
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/fixed_flat_set.h"
#include "base/no_destructor.h"
#include "brave/components/brave_rewards/core/buildflags/buildflags.h"
#include "brave/components/brave_search/common/buildflags/buildflags.h"
#include "brave/components/brave_service_keys/brave_service_key_utils.h"
#include "brave/components/constants/brave_services_key.h"
#include "brave/components/constants/network_constants.h"
#include "brave/components/update_client/buildflags.h"
@@ -23,6 +27,13 @@
namespace brave {
namespace {
constexpr auto kSearchDomains = base::MakeFixedFlatSet<std::string_view>(
{"search.brave.com", "search.brave.software"});
} // namespace
template <template <typename> class T>
int OnBeforeStartTransaction_BraveServiceKey(
net::HttpRequestHeaders* headers,
@@ -43,12 +54,20 @@ int OnBeforeStartTransaction_BraveServiceKey(
const GURL& url = ctx->request_url();
if (url.SchemeIs(url::kHttpsScheme)) {
if (std::any_of(
const bool is_search_domain = kSearchDomains.contains(url.host());
if (is_search_domain ||
std::any_of(
allowed_domains->begin(), allowed_domains->end(),
[&url](const auto& domain) { return url.DomainIs(domain); })) {
headers->SetHeader(kBraveServicesKeyHeader,
BUILDFLAG(BRAVE_SERVICES_KEY));
}
if (is_search_domain) {
const auto authorization = brave_service_keys::GetAuthorizationHeader(
BUILDFLAG(SERVICE_KEY_SEARCH), /*headers=*/{}, url, ctx->method(),
{"(request-target)"});
headers->SetHeader(authorization.first, authorization.second);
}
}
return net::OK;
}
@@ -3,6 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include <string>
#include "base/containers/map_util.h"
#include "brave/components/constants/network_constants.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
@@ -13,6 +16,7 @@
#include "content/public/test/test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/http_request.h"
#include "testing/gmock/include/gmock/gmock.h"
class BraveServiceKeyNetworkDelegateBrowserTest : public InProcessBrowserTest {
public:
@@ -35,6 +39,9 @@ class BraveServiceKeyNetworkDelegateBrowserTest : public InProcessBrowserTest {
base::AutoLock auto_lock(header_result_lock_);
header_result_ = request.headers.contains("BraveServiceKey");
const std::string* auth =
base::FindOrNull(request.headers, "Authorization");
authorization_header_ = auth ? *auth : std::string();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -59,11 +66,17 @@ class BraveServiceKeyNetworkDelegateBrowserTest : public InProcessBrowserTest {
return header_result_;
}
std::string authorization_header() {
base::AutoLock auto_lock(header_result_lock_);
return authorization_header_;
}
private:
content::ContentMockCertVerifier mock_cert_verifier_;
net::test_server::EmbeddedTestServer https_server_;
mutable base::Lock header_result_lock_;
bool header_result_ = false;
std::string authorization_header_;
};
IN_PROC_BROWSER_TEST_F(BraveServiceKeyNetworkDelegateBrowserTest,
@@ -98,4 +111,37 @@ IN_PROC_BROWSER_TEST_F(BraveServiceKeyNetworkDelegateBrowserTest,
GURL target = https_server().GetURL(kExtensionUpdaterDomain, "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_TRUE(header_result());
target = https_server().GetURL("search.brave.com", "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_TRUE(header_result());
target = https_server().GetURL("search.brave.software", "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_TRUE(header_result());
}
IN_PROC_BROWSER_TEST_F(BraveServiceKeyNetworkDelegateBrowserTest,
IncludesAuthorizationHeaderForSearchDomains) {
GURL target = https_server().GetURL("search.brave.com", "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_THAT(authorization_header(),
::testing::StartsWith("Signature keyId="));
EXPECT_THAT(authorization_header(),
::testing::HasSubstr("headers=\"(request-target)\""));
target = https_server().GetURL("search.brave.software", "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_THAT(authorization_header(),
::testing::StartsWith("Signature keyId="));
EXPECT_THAT(authorization_header(),
::testing::HasSubstr("headers=\"(request-target)\""));
target = https_server().GetURL(kExtensionUpdaterDomain, "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_TRUE(authorization_header().empty());
target = https_server().GetURL("brave.com", "/index.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), target));
EXPECT_TRUE(authorization_header().empty());
}
+1
View File
@@ -68,6 +68,7 @@ brave_browser_net_deps = [
"//brave/components/brave_rewards/core",
"//brave/components/brave_rewards/core/buildflags",
"//brave/components/brave_search/common",
"//brave/components/brave_search/common/buildflags",
"//brave/components/brave_service_keys",
"//brave/components/brave_shields/content/browser",
"//brave/components/brave_shields/core/browser",
+1
View File
@@ -37,6 +37,7 @@ const FORWARD_ENV_CONFIG_VARS_TO_GN_ARGS = [
'rewards_grant_staging_endpoint',
'safebrowsing_api_endpoint',
'service_key_aichat',
'service_key_search',
'service_key_stt',
'sparkle_dsa_private_key_file',
'sparkle_eddsa_private_key',
@@ -0,0 +1,19 @@
# Copyright (c) 2026 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.
import("//build/buildflag_header.gni")
declare_args() {
service_key_search = ""
}
if (is_official_build) {
assert(service_key_search != "")
}
buildflag_header("buildflags") {
header = "buildflags.h"
flags = [ "SERVICE_KEY_SEARCH=\"$service_key_search\"" ]
}