Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Farble Accept-Language header on subresources #14338

Merged
merged 11 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions browser/brave_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "brave/browser/brave_browser_main_extra_parts.h"
#include "brave/browser/brave_browser_process.h"
#include "brave/browser/brave_shields/brave_shields_web_contents_observer.h"
#include "brave/browser/brave_shields/reduce_language_navigation_throttle.h"
#include "brave/browser/brave_wallet/brave_wallet_context_utils.h"
#include "brave/browser/brave_wallet/brave_wallet_provider_delegate_impl.h"
#include "brave/browser/brave_wallet/brave_wallet_service_factory.h"
Expand Down Expand Up @@ -1003,13 +1002,6 @@ BraveContentBrowserClient::CreateThrottlesForNavigation(
g_browser_process->GetApplicationLocale()))
throttles.push_back(std::move(domain_block_navigation_throttle));

if (std::unique_ptr<content::NavigationThrottle>
reduce_language_navigation_throttle = brave_shields::
ReduceLanguageNavigationThrottle::MaybeCreateThrottleFor(
handle, HostContentSettingsMapFactory::GetForProfile(
Profile::FromBrowserContext(context))))
throttles.push_back(std::move(reduce_language_navigation_throttle));

// Debounce
if (auto debounce_throttle =
debounce::DebounceNavigationThrottle::MaybeCreateThrottleFor(
Expand Down
116 changes: 0 additions & 116 deletions browser/brave_shields/reduce_language_navigation_throttle.cc

This file was deleted.

60 changes: 0 additions & 60 deletions browser/brave_shields/reduce_language_navigation_throttle.h

This file was deleted.

2 changes: 0 additions & 2 deletions browser/brave_shields/sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ brave_browser_brave_shields_sources = [
"//brave/browser/brave_shields/brave_shields_web_contents_observer.h",
"//brave/browser/brave_shields/https_everywhere_component_installer.cc",
"//brave/browser/brave_shields/https_everywhere_component_installer.h",
"//brave/browser/brave_shields/reduce_language_navigation_throttle.cc",
"//brave/browser/brave_shields/reduce_language_navigation_throttle.h",
]

brave_browser_brave_shields_deps = [
Expand Down
38 changes: 34 additions & 4 deletions browser/farbling/brave_navigator_languages_farbling_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class BraveNavigatorLanguagesFarblingBrowserTest : public InProcessBrowserTest {
}

void MonitorHTTPRequest(const net::test_server::HttpRequest& request) {
if (request.relative_url != "/simple.html")
if (request.relative_url.find("/reduce-language/") == std::string::npos)
return;
if (expected_http_accept_language_.empty())
return;
Expand Down Expand Up @@ -232,13 +232,15 @@ IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
EXPECT_EQ(expected_title, watcher2.WaitAndGetTitle());
}

// Tests results of farbling user agent
// Tests results of farbling HTTP Accept-Language header
IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
FarbleHTTPAcceptLanguage) {
std::string domain_b = "b.test";
std::string domain_d = "d.test";
GURL url_b = https_server_.GetURL(domain_b, "/simple.html");
GURL url_d = https_server_.GetURL(domain_d, "/simple.html");
GURL url_b = https_server_.GetURL(
domain_b, "/reduce-language/page-with-subresources.html");
GURL url_d = https_server_.GetURL(
domain_d, "/reduce-language/page-with-subresources.html");
SetAcceptLanguages("la,es,en");

// Farbling level: off
Expand All @@ -265,4 +267,32 @@ IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
NavigateToURLUntilLoadStop(url_b);
BlockFingerprinting(domain_d);
NavigateToURLUntilLoadStop(url_d);

// Test with subdivided language code as the primary language.
SetAcceptLanguages("zh-HK,zh,la");

// Farbling level: off
// HTTP Accept-Language header should not be farbled.
AllowFingerprinting(domain_b);
SetExpectedHTTPAcceptLanguage("zh-HK,zh;q=0.9,la;q=0.8");
NavigateToURLUntilLoadStop(url_b);
AllowFingerprinting(domain_d);
NavigateToURLUntilLoadStop(url_d);

// Farbling level: default
// HTTP Accept-Language header should be farbled by domain.
SetFingerprintingDefault(domain_b);
SetExpectedHTTPAcceptLanguage("zh-HK,zh;q=0.7");
NavigateToURLUntilLoadStop(url_b);
SetExpectedHTTPAcceptLanguage("zh-HK,zh;q=0.8");
SetFingerprintingDefault(domain_d);
NavigateToURLUntilLoadStop(url_d);

// Farbling level: maximum
// HTTP Accept-Language header should be farbled but the same across domains.
BlockFingerprinting(domain_b);
SetExpectedHTTPAcceptLanguage("en-US,en;q=0.9");
NavigateToURLUntilLoadStop(url_b);
BlockFingerprinting(domain_d);
NavigateToURLUntilLoadStop(url_d);
}
2 changes: 2 additions & 0 deletions browser/net/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ source_set("net") {
"brave_proxying_url_loader_factory.h",
"brave_proxying_web_socket.cc",
"brave_proxying_web_socket.h",
"brave_reduce_language_network_delegate_helper.cc",
"brave_reduce_language_network_delegate_helper.h",
"brave_request_handler.cc",
"brave_request_handler.h",
"brave_service_key_network_delegate_helper.cc",
Expand Down
102 changes: 102 additions & 0 deletions browser/net/brave_reduce_language_network_delegate_helper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/. */

#include "brave/browser/net/brave_reduce_language_network_delegate_helper.h"
pilgrim-brave marked this conversation as resolved.
Show resolved Hide resolved

#include <array>
#include <string>
#include <vector>

#include "base/strings/string_split.h"
#include "brave/browser/brave_browser_process.h"
#include "brave/components/brave_shields/browser/brave_farbling_service.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/language/core/browser/language_prefs.h"
#include "components/language/core/browser/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_context.h"
#include "net/base/net_errors.h"

using brave_shields::ControlType;

namespace brave {

namespace {
constexpr char kAcceptLanguageMax[] = "en-US,en;q=0.9";
const std::array<std::string, 5> kFakeQValues = {";q=0.5", ";q=0.6", ";q=0.7",
";q=0.8", ";q=0.9"};
} // namespace

std::string FarbleAcceptLanguageHeader(
const GURL& tab_origin,
Profile* profile,
HostContentSettingsMap* content_settings) {
std::string languages =
profile->GetPrefs()->Get(language::prefs::kAcceptLanguages)->GetString();
std::string accept_language_string = language::GetFirstLanguage(languages);
// If the first language is a multi-part code like "en-US" or "zh-HK",
// extract and append the base language code to |accept_language_string|.
const std::vector<std::string> tokens = base::SplitString(
accept_language_string, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
if (!tokens.empty() && tokens[0] != accept_language_string) {
accept_language_string += "," + tokens[0];
}
// Add a fake q value after the language code.
brave::FarblingPRNG prng;
if (g_brave_browser_process->brave_farbling_service()
->MakePseudoRandomGeneratorForURL(
tab_origin, profile && profile->IsOffTheRecord(), &prng)) {
pilgrim-brave marked this conversation as resolved.
Show resolved Hide resolved
accept_language_string += kFakeQValues[prng() % kFakeQValues.size()];
}
return accept_language_string;
}

int OnBeforeStartTransaction_ReduceLanguageWork(
net::HttpRequestHeaders* headers,
const ResponseCallback& next_callback,
std::shared_ptr<BraveRequestInfo> ctx) {
Profile* profile = Profile::FromBrowserContext(ctx->browser_context);
DCHECK(profile);
HostContentSettingsMap* content_settings =
HostContentSettingsMapFactory::GetForProfile(profile);
DCHECK(content_settings);
if (!brave_shields::ShouldDoReduceLanguage(content_settings, ctx->tab_origin,
profile->GetPrefs())) {
return net::OK;
}

std::string accept_language_string;
switch (brave_shields::GetFingerprintingControlType(content_settings,
ctx->tab_origin)) {
case ControlType::BLOCK: {
// If fingerprint blocking is maximum, set Accept-Language header to
// static value regardless of other preferences.
accept_language_string = kAcceptLanguageMax;
break;
}
case ControlType::DEFAULT: {
// If fingerprint blocking is default, compute Accept-Language header
// based on user preferences and some randomization.
accept_language_string = FarbleAcceptLanguageHeader(
ctx->tab_origin, profile, content_settings);
break;
}
default:
// Other cases are handled within ShouldDoReduceLanguage, so we should
// never reach here.
NOTREACHED();
}

headers->SetHeader(net::HttpRequestHeaders::kAcceptLanguage,
accept_language_string);
ctx->set_headers.insert(net::HttpRequestHeaders::kAcceptLanguage);

return net::OK;
}

} // namespace brave
Loading