diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd
index 3ff99bbca98c..4232cea1bf92 100644
--- a/app/brave_generated_resources.grd
+++ b/app/brave_generated_resources.grd
@@ -245,7 +245,7 @@
- Widevine is sometimes needed to play media on a webpage. It's a Google extension loaded from Google servers, which Brave cannot inspect. By installing, you'll agree to Google's terms of use.
+ Widevine is sometimes needed to play media on a webpage. It's a Google extension loaded from Google servers, which Brave cannot inspect. By installing, you'll agree to Google's terms of use.
$1Learn more about Widevine.
@@ -337,7 +337,7 @@ Or change later at $2brave://settings/ext
Auto-redirect AMP pages
- Always visit original (non-AMP) page URLs, instead of Google's Accelerated Mobile Page versions
+ Always visit original (non-AMP) page URLs, instead of Google's Accelerated Mobile Page versions
Show autocomplete in address bar
@@ -653,6 +653,12 @@ Or change later at $2brave://settings/ext
Block fingerprinting
+
+ Prevent sites from fingerprinting me based on my language preferences
+
+
+ Enabling this setting reduces how much web sites can learn about your language preferences.
+
Upgrade connections to HTTPS
diff --git a/browser/about_flags.cc b/browser/about_flags.cc
index 6ba7ac7beb15..3e5a087fc876 100644
--- a/browser/about_flags.cc
+++ b/browser/about_flags.cc
@@ -60,6 +60,7 @@ using brave_shields::features::kBraveDarkModeBlock;
using brave_shields::features::kBraveDomainBlock;
using brave_shields::features::kBraveDomainBlock1PES;
using brave_shields::features::kBraveExtensionNetworkBlocking;
+using brave_shields::features::kBraveReduceLanguage;
using brave_shields::features::kCosmeticFilteringSyncLoad;
using de_amp::features::kBraveDeAMP;
@@ -146,6 +147,10 @@ constexpr char kBraveExtensionNetworkBlockingName[] =
constexpr char kBraveExtensionNetworkBlockingDescription[] =
"Enable blocking for network requests initiated by extensions";
+constexpr char kBraveReduceLanguageName[] = "Reduce language identifiability";
+constexpr char kBraveReduceLanguageDescription[] =
+ "Reduce the identifiability of my language preferences";
+
constexpr char kCosmeticFilteringSyncLoadName[] =
"Enable sync loading of cosmetic filter rules";
constexpr char kCosmeticFilteringSyncLoadDescription[] =
@@ -499,6 +504,10 @@ const flags_ui::FeatureEntry::Choice kBraveSkusEnvChoices[] = {
flag_descriptions::kBraveExtensionNetworkBlockingName, \
flag_descriptions::kBraveExtensionNetworkBlockingDescription, kOsAll, \
FEATURE_VALUE_TYPE(kBraveExtensionNetworkBlocking)}, \
+ {"brave-reduce-language", \
+ flag_descriptions::kBraveReduceLanguageName, \
+ flag_descriptions::kBraveReduceLanguageDescription, kOsAll, \
+ FEATURE_VALUE_TYPE(kBraveReduceLanguage)}, \
{"brave-cosmetic-filtering-sync-load", \
flag_descriptions::kCosmeticFilteringSyncLoadName, \
flag_descriptions::kCosmeticFilteringSyncLoadDescription, kOsAll, \
diff --git a/browser/brave_browser_process.h b/browser/brave_browser_process.h
index 206c83be3a40..ddd1ad55713f 100644
--- a/browser/brave_browser_process.h
+++ b/browser/brave_browser_process.h
@@ -21,6 +21,7 @@
namespace brave {
class BraveReferralsService;
class BraveP3AService;
+class BraveFarblingService;
} // namespace brave
namespace brave_component_updater {
@@ -104,6 +105,7 @@ class BraveBrowserProcess {
speedreader_rewriter_service() = 0;
#endif
virtual brave_ads::ResourceComponent* resource_component() = 0;
+ virtual brave::BraveFarblingService* brave_farbling_service() = 0;
};
extern BraveBrowserProcess* g_brave_browser_process;
diff --git a/browser/brave_browser_process_impl.cc b/browser/brave_browser_process_impl.cc
index 7f8fb22c5d5e..988c16313459 100644
--- a/browser/brave_browser_process_impl.cc
+++ b/browser/brave_browser_process_impl.cc
@@ -5,6 +5,7 @@
#include "brave/browser/brave_browser_process_impl.h"
+#include
#include
#include "base/bind.h"
@@ -27,6 +28,7 @@
#include "brave/components/brave_shields/browser/ad_block_regional_service_manager.h"
#include "brave/components/brave_shields/browser/ad_block_service.h"
#include "brave/components/brave_shields/browser/ad_block_subscription_service_manager.h"
+#include "brave/components/brave_shields/browser/brave_farbling_service.h"
#include "brave/components/brave_shields/browser/https_everywhere_service.h"
#include "brave/components/brave_sync/network_time_helper.h"
#include "brave/components/debounce/browser/debounce_component_installer.h"
@@ -47,6 +49,7 @@
#include "content/public/browser/child_process_security_policy.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "url/gurl.h"
#if BUILDFLAG(ENABLE_BRAVE_REFERRALS)
#include "brave/components/brave_referrals/browser/brave_referrals_service.h"
@@ -381,3 +384,9 @@ ipfs::BraveIpfsClientUpdater* BraveBrowserProcessImpl::ipfs_client_updater() {
return ipfs_client_updater_.get();
}
#endif // BUILDFLAG(ENABLE_IPFS)
+
+brave::BraveFarblingService* BraveBrowserProcessImpl::brave_farbling_service() {
+ if (!brave_farbling_service_)
+ brave_farbling_service_ = std::make_unique();
+ return brave_farbling_service_.get();
+}
diff --git a/browser/brave_browser_process_impl.h b/browser/brave_browser_process_impl.h
index 65fdeacaaec9..b35d968234a2 100644
--- a/browser/brave_browser_process_impl.h
+++ b/browser/brave_browser_process_impl.h
@@ -23,6 +23,7 @@ namespace brave {
class BraveReferralsService;
class BraveP3AService;
class HistogramsBraveizer;
+class BraveFarblingService;
} // namespace brave
namespace brave_component_updater {
@@ -115,6 +116,7 @@ class BraveBrowserProcessImpl : public BraveBrowserProcess,
speedreader::SpeedreaderRewriterService* speedreader_rewriter_service()
override;
#endif
+ brave::BraveFarblingService* brave_farbling_service() override;
private:
// BrowserProcessImpl overrides:
@@ -173,6 +175,8 @@ class BraveBrowserProcessImpl : public BraveBrowserProcess,
speedreader_rewriter_service_;
#endif
+ std::unique_ptr brave_farbling_service_;
+
SEQUENCE_CHECKER(sequence_checker_);
};
diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc
index cd285c42237b..fa80c1396d63 100644
--- a/browser/brave_content_browser_client.cc
+++ b/browser/brave_content_browser_client.cc
@@ -12,12 +12,12 @@
#include "base/bind.h"
#include "base/json/json_reader.h"
-#include "base/rand_util.h"
#include "base/system/sys_info.h"
#include "base/task/post_task.h"
#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"
@@ -45,6 +45,7 @@
#include "brave/components/brave_search/common/brave_search_fallback.mojom.h"
#include "brave/components/brave_search/common/brave_search_utils.h"
#include "brave/components/brave_shields/browser/ad_block_service.h"
+#include "brave/components/brave_shields/browser/brave_farbling_service.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "brave/components/brave_shields/browser/domain_block_navigation_throttle.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
@@ -352,9 +353,7 @@ void MaybeBindSkusSdkImpl(
} // namespace
-BraveContentBrowserClient::BraveContentBrowserClient()
- : session_token_(base::RandUint64()),
- incognito_session_token_(base::RandUint64()) {}
+BraveContentBrowserClient::BraveContentBrowserClient() {}
BraveContentBrowserClient::~BraveContentBrowserClient() {}
@@ -616,11 +615,9 @@ void BraveContentBrowserClient::AppendExtraCommandLineSwitches(
Profile* profile =
process ? Profile::FromBrowserContext(process->GetBrowserContext())
: nullptr;
- if (profile && !profile->IsOffTheRecord()) {
- session_token = session_token_;
- } else {
- session_token = incognito_session_token_;
- }
+ session_token =
+ g_brave_browser_process->brave_farbling_service()->session_token(
+ profile && !profile->IsOffTheRecord());
}
command_line->AppendSwitchASCII("brave_session_token",
base::NumberToString(session_token));
@@ -912,6 +909,13 @@ BraveContentBrowserClient::CreateThrottlesForNavigation(
g_browser_process->GetApplicationLocale()))
throttles.push_back(std::move(domain_block_navigation_throttle));
+ if (std::unique_ptr
+ reduce_language_navigation_throttle = brave_shields::
+ ReduceLanguageNavigationThrottle::MaybeCreateThrottleFor(
+ handle, HostContentSettingsMapFactory::GetForProfile(
+ Profile::FromBrowserContext(context))))
+ throttles.push_back(std::move(reduce_language_navigation_throttle));
+
return throttles;
}
diff --git a/browser/brave_content_browser_client.h b/browser/brave_content_browser_client.h
index 22a56e7e9314..65ea20b3d926 100644
--- a/browser/brave_content_browser_client.h
+++ b/browser/brave_content_browser_client.h
@@ -143,9 +143,6 @@ class BraveContentBrowserClient : public ChromeContentBrowserClient {
blink::web_pref::WebPreferences* prefs) override;
private:
- uint64_t session_token_;
- uint64_t incognito_session_token_;
-
void OnAllowGoogleAuthChanged();
std::unique_ptr
diff --git a/browser/brave_prefs_browsertest.cc b/browser/brave_prefs_browsertest.cc
index 257f6ea18302..e58c17597ef2 100644
--- a/browser/brave_prefs_browsertest.cc
+++ b/browser/brave_prefs_browsertest.cc
@@ -80,6 +80,8 @@ IN_PROC_BROWSER_TEST_F(BraveProfilePrefsBrowserTest, MiscBravePrefs) {
brave_shields::prefs::kTwitterEmbedControlType));
EXPECT_FALSE(chrome_test_utils::GetProfile(this)->GetPrefs()->GetBoolean(
brave_shields::prefs::kLinkedInEmbedControlType));
+ EXPECT_TRUE(chrome_test_utils::GetProfile(this)->GetPrefs()->GetBoolean(
+ brave_shields::prefs::kReduceLanguageEnabled));
#if BUILDFLAG(ENABLE_BRAVE_WAYBACK_MACHINE)
EXPECT_TRUE(chrome_test_utils::GetProfile(this)->GetPrefs()->GetBoolean(
kWebTorrentEnabled));
diff --git a/browser/brave_profile_prefs.cc b/browser/brave_profile_prefs.cc
index dc745a4aadbc..e686178e1b11 100644
--- a/browser/brave_profile_prefs.cc
+++ b/browser/brave_profile_prefs.cc
@@ -23,6 +23,7 @@
#include "brave/components/brave_rewards/common/pref_names.h"
#include "brave/components/brave_search/browser/brave_search_default_host.h"
#include "brave/components/brave_search/common/brave_search_utils.h"
+#include "brave/components/brave_shields/browser/brave_farbling_service.h"
#include "brave/components/brave_shields/common/pref_names.h"
#include "brave/components/brave_sync/brave_sync_prefs.h"
#include "brave/components/brave_today/browser/brave_news_controller.h"
@@ -437,6 +438,8 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->SetDefaultPrefValue(policy::policy_prefs::kEnableDirectSockets,
base::Value(false));
+ BraveFarblingService::RegisterProfilePrefs(registry);
+
RegisterProfilePrefsForMigration(registry);
}
diff --git a/browser/brave_shields/brave_shields_web_contents_observer.cc b/browser/brave_shields/brave_shields_web_contents_observer.cc
index 7dca4239fb16..de401a172d59 100644
--- a/browser/brave_shields/brave_shields_web_contents_observer.cc
+++ b/browser/brave_shields/brave_shields_web_contents_observer.cc
@@ -16,6 +16,7 @@
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "brave/components/brave_shields/common/features.h"
+#include "brave/components/brave_shields/common/pref_names.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/renderer_configuration.mojom.h"
@@ -23,6 +24,7 @@
#include "components/content_settings/core/common/content_settings_utils.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
+#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
@@ -105,6 +107,14 @@ void BraveShieldsWebContentsObserver::RenderFrameCreated(RenderFrameHost* rfh) {
GetBraveShieldsRemote(rfh)->SetAllowScriptsFromOriginsOnce(
allowed_script_origins_);
}
+ if (rfh) {
+ if (content::BrowserContext* context = rfh->GetBrowserContext()) {
+ if (PrefService* pref_service = user_prefs::UserPrefs::Get(context)) {
+ GetBraveShieldsRemote(rfh)->SetReduceLanguageEnabled(
+ brave_shields::IsReduceLanguageEnabledForProfile(pref_service));
+ }
+ }
+ }
WebContents* web_contents = WebContents::FromRenderFrameHost(rfh);
if (web_contents) {
@@ -279,6 +289,14 @@ void BraveShieldsWebContentsObserver::ReadyToCommitNavigation(
observer->GetBraveShieldsRemote(rfh)
->SetAllowScriptsFromOriginsOnce(
observer->allowed_script_origins_);
+ if (content::BrowserContext* context = rfh->GetBrowserContext()) {
+ if (PrefService* pref_service =
+ user_prefs::UserPrefs::Get(context)) {
+ observer->GetBraveShieldsRemote(rfh)->SetReduceLanguageEnabled(
+ brave_shields::IsReduceLanguageEnabledForProfile(
+ pref_service));
+ }
+ }
},
base::Unretained(this)));
}
diff --git a/browser/brave_shields/reduce_language_navigation_throttle.cc b/browser/brave_shields/reduce_language_navigation_throttle.cc
new file mode 100644
index 000000000000..d2203a02d82d
--- /dev/null
+++ b/browser/brave_shields/reduce_language_navigation_throttle.cc
@@ -0,0 +1,115 @@
+/* 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/brave_shields/reduce_language_navigation_throttle.h"
+
+#include
+#include
+
+#include "base/feature_list.h"
+#include "base/threading/thread_task_runner_handle.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 "brave/components/brave_shields/common/features.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 "components/user_prefs/user_prefs.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
+#include "net/http/http_util.h"
+
+namespace brave_shields {
+
+// static
+std::unique_ptr
+ReduceLanguageNavigationThrottle::MaybeCreateThrottleFor(
+ content::NavigationHandle* navigation_handle,
+ HostContentSettingsMap* content_settings) {
+ content::BrowserContext* context =
+ navigation_handle->GetWebContents()->GetBrowserContext();
+ PrefService* pref_service = user_prefs::UserPrefs::Get(context);
+ if (!IsReduceLanguageEnabledForProfile(pref_service))
+ return nullptr;
+ return std::make_unique(navigation_handle,
+ content_settings);
+}
+
+ReduceLanguageNavigationThrottle::ReduceLanguageNavigationThrottle(
+ content::NavigationHandle* navigation_handle,
+ HostContentSettingsMap* content_settings)
+ : content::NavigationThrottle(navigation_handle),
+ content_settings_(content_settings) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+}
+
+ReduceLanguageNavigationThrottle::~ReduceLanguageNavigationThrottle() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+}
+
+content::NavigationThrottle::ThrottleCheckResult
+ReduceLanguageNavigationThrottle::WillStartRequest() {
+ UpdateHeaders();
+ return content::NavigationThrottle::PROCEED;
+}
+
+content::NavigationThrottle::ThrottleCheckResult
+ReduceLanguageNavigationThrottle::WillRedirectRequest() {
+ UpdateHeaders();
+ return content::NavigationThrottle::PROCEED;
+}
+
+void ReduceLanguageNavigationThrottle::UpdateHeaders() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ content::NavigationHandle* handle = navigation_handle();
+ GURL url = handle->GetURL();
+ content::BrowserContext* context =
+ handle->GetWebContents()->GetBrowserContext();
+ PrefService* pref_service = user_prefs::UserPrefs::Get(context);
+
+ if (!brave_shields::ShouldDoReduceLanguage(content_settings_, url,
+ pref_service))
+ return;
+
+ ControlType fingerprinting_control_type =
+ brave_shields::GetFingerprintingControlType(content_settings_, url);
+
+ // If fingerprint blocking is maximum, set Accept-Language header to
+ // static value regardless of other preferences.
+ if (fingerprinting_control_type == ControlType::BLOCK) {
+ handle->SetRequestHeader(net::HttpRequestHeaders::kAcceptLanguage,
+ "en-US,en");
+ return;
+ }
+
+ // If fingerprint blocking is default, compute Accept-Language header
+ // based on user preferences.
+ std::string languages =
+ pref_service->Get(language::prefs::kAcceptLanguages)->GetString();
+ std::string first_language = language::GetFirstLanguage(languages);
+ // Potentially add a fake q value after the language code.
+ std::vector q_values = {";q=0.5", ";q=0.6", ";q=0.7",
+ ";q=0.8", ";q=0.9", ""};
+ std::mt19937_64 prng;
+ auto* profile = Profile::FromBrowserContext(context);
+ if (g_brave_browser_process->brave_farbling_service()
+ ->MakePseudoRandomGeneratorForURL(
+ url, profile && !profile->IsOffTheRecord(), &prng)) {
+ first_language += q_values[prng() % q_values.size()];
+ }
+ handle->SetRequestHeader(net::HttpRequestHeaders::kAcceptLanguage,
+ first_language);
+}
+
+const char* ReduceLanguageNavigationThrottle::GetNameForLogging() {
+ return "ReduceLanguageNavigationThrottle";
+}
+
+} // namespace brave_shields
diff --git a/browser/brave_shields/reduce_language_navigation_throttle.h b/browser/brave_shields/reduce_language_navigation_throttle.h
new file mode 100644
index 000000000000..29ad25737271
--- /dev/null
+++ b/browser/brave_shields/reduce_language_navigation_throttle.h
@@ -0,0 +1,60 @@
+/* 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/. */
+
+#ifndef BRAVE_BROWSER_BRAVE_SHIELDS_REDUCE_LANGUAGE_NAVIGATION_THROTTLE_H_
+#define BRAVE_BROWSER_BRAVE_SHIELDS_REDUCE_LANGUAGE_NAVIGATION_THROTTLE_H_
+
+#include
+#include
+#include
+
+#include "base/memory/weak_ptr.h"
+#include "brave/components/brave_shields/browser/brave_shields_util.h"
+#include "content/public/browser/navigation_throttle.h"
+#include "url/gurl.h"
+
+class HostContentSettingsMap;
+
+namespace content {
+class NavigationHandle;
+class WebContents;
+} // namespace content
+
+namespace brave_shields {
+
+class ReduceLanguageNavigationThrottle : public content::NavigationThrottle {
+ public:
+ explicit ReduceLanguageNavigationThrottle(
+ content::NavigationHandle* navigation_handle,
+ HostContentSettingsMap* content_settings);
+ ~ReduceLanguageNavigationThrottle() override;
+
+ ReduceLanguageNavigationThrottle(const ReduceLanguageNavigationThrottle&) =
+ delete;
+ ReduceLanguageNavigationThrottle& operator=(
+ const ReduceLanguageNavigationThrottle&) = delete;
+
+ static std::unique_ptr
+ MaybeCreateThrottleFor(content::NavigationHandle* navigation_handle,
+ HostContentSettingsMap* content_settings);
+
+ // content::NavigationThrottle implementation:
+ content::NavigationThrottle::ThrottleCheckResult WillStartRequest() override;
+ content::NavigationThrottle::ThrottleCheckResult WillRedirectRequest()
+ override;
+ const char* GetNameForLogging() override;
+
+ private:
+ HostContentSettingsMap* content_settings_ = nullptr;
+
+ void UpdateHeaders();
+
+ base::WeakPtrFactory weak_ptr_factory_{
+ this};
+};
+
+} // namespace brave_shields
+
+#endif // BRAVE_BROWSER_BRAVE_SHIELDS_REDUCE_LANGUAGE_NAVIGATION_THROTTLE_H_
diff --git a/browser/brave_shields/sources.gni b/browser/brave_shields/sources.gni
index 67d0def2f896..df1e09ffb3f3 100644
--- a/browser/brave_shields/sources.gni
+++ b/browser/brave_shields/sources.gni
@@ -16,6 +16,8 @@ brave_browser_brave_shields_sources = [
"//brave/browser/brave_shields/cookie_pref_service_factory.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 = [
diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc
index cdc17eec33e4..7d44434058a4 100644
--- a/browser/extensions/api/settings_private/brave_prefs_util.cc
+++ b/browser/extensions/api/settings_private/brave_prefs_util.cc
@@ -114,6 +114,8 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() {
settings_api::PrefType::PREF_TYPE_BOOLEAN;
(*s_brave_allowlist)[brave_shields::prefs::kLinkedInEmbedControlType] =
settings_api::PrefType::PREF_TYPE_BOOLEAN;
+ (*s_brave_allowlist)[brave_shields::prefs::kReduceLanguageEnabled] =
+ settings_api::PrefType::PREF_TYPE_BOOLEAN;
// Rewards/Ads prefs
(*s_brave_allowlist)[ads::prefs::kEnabled] =
diff --git a/browser/farbling/BUILD.gn b/browser/farbling/BUILD.gn
index 6ac1b8144bb8..93b239594c15 100644
--- a/browser/farbling/BUILD.gn
+++ b/browser/farbling/BUILD.gn
@@ -15,6 +15,7 @@ if (!is_android) {
"brave_navigator_devicememory_farbling_browsertest.cc",
"brave_navigator_hardwareconcurrency_farbling_browsertest.cc",
"brave_navigator_keyboard_api_browsertest.cc",
+ "brave_navigator_languages_farbling_browsertest.cc",
"brave_navigator_plugins_farbling_browsertest.cc",
"brave_navigator_useragent_farbling_browsertest.cc",
"brave_offscreencanvas_farbling_browsertest.cc",
diff --git a/browser/farbling/brave_navigator_languages_farbling_browsertest.cc b/browser/farbling/brave_navigator_languages_farbling_browsertest.cc
new file mode 100644
index 000000000000..a631ff953dca
--- /dev/null
+++ b/browser/farbling/brave_navigator_languages_farbling_browsertest.cc
@@ -0,0 +1,265 @@
+/* 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 "base/path_service.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "base/test/thread_test_helper.h"
+#include "brave/browser/brave_browser_process.h"
+#include "brave/browser/brave_content_browser_client.h"
+#include "brave/browser/extensions/brave_base_local_data_files_browsertest.h"
+#include "brave/common/brave_paths.h"
+#include "brave/common/pref_names.h"
+#include "brave/components/brave_component_updater/browser/local_data_files_service.h"
+#include "brave/components/brave_shields/browser/brave_farbling_service.h"
+#include "brave/components/brave_shields/browser/brave_shields_util.h"
+#include "brave/components/brave_shields/common/features.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/chrome_content_client.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/language/core/browser/pref_names.h"
+#include "components/network_session_configurator/common/network_switches.h"
+#include "components/permissions/permission_request.h"
+#include "components/prefs/pref_service.h"
+#include "components/user_prefs/user_prefs.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "net/dns/mock_host_resolver.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/navigator.h"
+#include "third_party/blink/renderer/core/frame/navigator_language.h"
+
+using brave_shields::ControlType;
+using content::TitleWatcher;
+
+namespace {
+const char kNavigatorLanguagesScript[] = "navigator.languages.toString()";
+}
+
+class BraveNavigatorLanguagesFarblingBrowserTest : public InProcessBrowserTest {
+ public:
+ BraveNavigatorLanguagesFarblingBrowserTest()
+ : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
+ brave::RegisterPathProvider();
+ base::FilePath test_data_dir;
+ base::PathService::Get(brave::DIR_TEST_DATA, &test_data_dir);
+ https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+ https_server_.ServeFilesFromDirectory(test_data_dir);
+ https_server_.RegisterRequestMonitor(base::BindRepeating(
+ &BraveNavigatorLanguagesFarblingBrowserTest::MonitorHTTPRequest,
+ base::Unretained(this)));
+ EXPECT_TRUE(https_server_.Start());
+ }
+
+ BraveNavigatorLanguagesFarblingBrowserTest(
+ const BraveNavigatorLanguagesFarblingBrowserTest&) = delete;
+ BraveNavigatorLanguagesFarblingBrowserTest& operator=(
+ const BraveNavigatorLanguagesFarblingBrowserTest&) = delete;
+
+ ~BraveNavigatorLanguagesFarblingBrowserTest() override {}
+
+ void SetUpOnMainThread() override {
+ InProcessBrowserTest::SetUpOnMainThread();
+
+ content_client_.reset(new ChromeContentClient);
+ content::SetContentClient(content_client_.get());
+ browser_content_client_.reset(new BraveContentBrowserClient());
+ content::SetBrowserClientForTesting(browser_content_client_.get());
+ g_brave_browser_process->brave_farbling_service()
+ ->set_session_tokens_for_testing();
+
+ host_resolver()->AddRule("*", "127.0.0.1");
+ }
+
+ void TearDown() override {
+ browser_content_client_.reset();
+ content_client_.reset();
+ }
+
+ protected:
+ base::test::ScopedFeatureList feature_list_;
+ net::EmbeddedTestServer https_server_;
+
+ HostContentSettingsMap* content_settings() {
+ return HostContentSettingsMapFactory::GetForProfile(browser()->profile());
+ }
+
+ void AllowFingerprinting(std::string domain) {
+ brave_shields::SetFingerprintingControlType(
+ content_settings(), ControlType::ALLOW,
+ https_server_.GetURL(domain, "/"));
+ }
+
+ void BlockFingerprinting(std::string domain) {
+ brave_shields::SetFingerprintingControlType(
+ content_settings(), ControlType::BLOCK,
+ https_server_.GetURL(domain, "/"));
+ }
+
+ void SetFingerprintingDefault(std::string domain) {
+ brave_shields::SetFingerprintingControlType(
+ content_settings(), ControlType::DEFAULT,
+ https_server_.GetURL(domain, "/"));
+ }
+
+ content::WebContents* web_contents() {
+ return browser()->tab_strip_model()->GetActiveWebContents();
+ }
+
+ bool NavigateToURLUntilLoadStop(const GURL& url) {
+ EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+ return WaitForLoadStop(web_contents());
+ }
+
+ void SetAcceptLanguages(const std::string& accept_languages) {
+ content::BrowserContext* context =
+ static_cast(browser()->profile());
+ PrefService* prefs = user_prefs::UserPrefs::Get(context);
+ prefs->Set(language::prefs::kSelectedLanguages,
+ base::Value(accept_languages));
+ }
+
+ void MonitorHTTPRequest(const net::test_server::HttpRequest& request) {
+ if (request.relative_url != "/simple.html")
+ return;
+ if (expected_http_accept_language_.empty())
+ return;
+ EXPECT_EQ(request.headers.at("accept-language"),
+ expected_http_accept_language_);
+ }
+
+ void SetExpectedHTTPAcceptLanguage(
+ const std::string& expected_http_accept_language) {
+ expected_http_accept_language_ = expected_http_accept_language;
+ }
+
+ private:
+ std::unique_ptr content_client_;
+ std::unique_ptr browser_content_client_;
+ std::string expected_http_accept_language_;
+};
+
+// Tests results of farbling known values
+IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
+ FarbleLanguages) {
+ std::string domain1 = "b.test";
+ std::string domain2 = "d.test";
+ GURL url1 = https_server_.GetURL(domain1, "/simple.html");
+ GURL url2 = https_server_.GetURL(domain2, "/simple.html");
+ // Farbling level: off
+ AllowFingerprinting(domain1);
+ NavigateToURLUntilLoadStop(url1);
+ std::string testing_languages = "en-US,en,es,la";
+ SetAcceptLanguages(testing_languages);
+ EXPECT_EQ(testing_languages,
+ EvalJs(web_contents(), kNavigatorLanguagesScript));
+ AllowFingerprinting(domain2);
+ NavigateToURLUntilLoadStop(url2);
+ EXPECT_EQ(testing_languages,
+ EvalJs(web_contents(), kNavigatorLanguagesScript));
+
+ // Farbling level: default
+ SetFingerprintingDefault(domain1);
+ NavigateToURLUntilLoadStop(url1);
+ std::string standard_languages = "en-US";
+ EXPECT_EQ(standard_languages,
+ EvalJs(web_contents(), kNavigatorLanguagesScript));
+ SetFingerprintingDefault(domain2);
+ NavigateToURLUntilLoadStop(url2);
+ EXPECT_EQ(standard_languages,
+ EvalJs(web_contents(), kNavigatorLanguagesScript));
+
+ // Farbling level: maximum
+ BlockFingerprinting(domain1);
+ NavigateToURLUntilLoadStop(url1);
+ std::string strict_languages = "en-US,en";
+ EXPECT_EQ(strict_languages,
+ EvalJs(web_contents(), kNavigatorLanguagesScript));
+ BlockFingerprinting(domain2);
+ NavigateToURLUntilLoadStop(url2);
+ EXPECT_EQ(strict_languages,
+ EvalJs(web_contents(), kNavigatorLanguagesScript));
+}
+
+// Tests that web workers inherit the farbled navigator.languages
+IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
+ FarbleLanguagesWebWorker) {
+ std::u16string expected_title(u"pass");
+ std::string domain = "b.test";
+ GURL url = https_server_.GetURL(domain, "/navigator/workers-languages.html");
+
+ // Farbling level: off
+ AllowFingerprinting(domain);
+ NavigateToURLUntilLoadStop(url);
+ TitleWatcher watcher1(web_contents(), expected_title);
+ EXPECT_EQ(expected_title, watcher1.WaitAndGetTitle());
+
+ // Farbling level: default
+ SetFingerprintingDefault(domain);
+ NavigateToURLUntilLoadStop(url);
+ TitleWatcher watcher2(web_contents(), expected_title);
+ EXPECT_EQ(expected_title, watcher2.WaitAndGetTitle());
+
+ // Farbling level: maximum
+ BlockFingerprinting(domain);
+ NavigateToURLUntilLoadStop(url);
+ TitleWatcher watcher3(web_contents(), expected_title);
+ EXPECT_EQ(expected_title, watcher3.WaitAndGetTitle());
+}
+
+// Tests that service workers inherit the farbled navigator.languages
+IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
+ FarbleLanguagesServiceWorker) {
+ std::u16string expected_title(u"pass");
+ std::string domain = "b.test";
+ GURL url =
+ https_server_.GetURL(domain, "/navigator/service-workers-languages.html");
+ // Farbling level: default
+ SetFingerprintingDefault(domain);
+ NavigateToURLUntilLoadStop(url);
+ TitleWatcher watcher2(web_contents(), expected_title);
+ EXPECT_EQ(expected_title, watcher2.WaitAndGetTitle());
+}
+
+// Tests results of farbling user agent
+IN_PROC_BROWSER_TEST_F(BraveNavigatorLanguagesFarblingBrowserTest,
+ FarbleHTTPAcceptLanguage) {
+ std::string domain_b = "b.test";
+ std::string domain_c = "c.test";
+ GURL url_b = https_server_.GetURL(domain_b, "/simple.html");
+ GURL url_c = https_server_.GetURL(domain_c, "/simple.html");
+ SetAcceptLanguages("la,es,en");
+
+ // Farbling level: off
+ // HTTP Accept-Language header should not be farbled.
+ AllowFingerprinting(domain_b);
+ SetExpectedHTTPAcceptLanguage("la,es;q=0.9,en;q=0.8");
+ NavigateToURLUntilLoadStop(url_b);
+ AllowFingerprinting(domain_c);
+ NavigateToURLUntilLoadStop(url_c);
+
+ // Farbling level: default
+ // HTTP Accept-Language header should be farbled by domain.
+ SetFingerprintingDefault(domain_b);
+ SetExpectedHTTPAcceptLanguage("la;q=0.8");
+ NavigateToURLUntilLoadStop(url_b);
+ SetExpectedHTTPAcceptLanguage("la;q=0.9");
+ SetFingerprintingDefault(domain_c);
+ NavigateToURLUntilLoadStop(url_c);
+
+ // Farbling level: maximum
+ // HTTP Accept-Language header should be farbled but the same across domains.
+ BlockFingerprinting(domain_b);
+ SetExpectedHTTPAcceptLanguage("en-US,en");
+ NavigateToURLUntilLoadStop(url_b);
+ BlockFingerprinting(domain_c);
+ NavigateToURLUntilLoadStop(url_c);
+}
diff --git a/browser/resources/settings/default_brave_shields_page/default_brave_shields_page.html b/browser/resources/settings/default_brave_shields_page/default_brave_shields_page.html
index 81edbd02cb04..aa4c715ca612 100644
--- a/browser/resources/settings/default_brave_shields_page/default_brave_shields_page.html
+++ b/browser/resources/settings/default_brave_shields_page/default_brave_shields_page.html
@@ -104,6 +104,12 @@
+
diff --git a/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index f8c407061706..0d20102d5ae2 100644
--- a/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chromium_src/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -149,6 +149,9 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source,
{"cookieControlLabel", IDS_SETTINGS_BRAVE_SHIELDS_COOKIE_CONTROL_LABEL},
{"fingerprintingControlLabel",
IDS_SETTINGS_BRAVE_SHIELDS_FINGERPRINTING_CONTROL_LABEL},
+ {"reduceLanguageControlLabel",
+ IDS_SETTINGS_BRAVE_SHIELDS_REDUCE_LANGUAGE_CONTROL_LABEL},
+ {"reduceLanguageDesc", IDS_SETTINGS_BRAVE_SHIELDS_REDUCE_LANGUAGE_SUBITEM},
{"httpsEverywhereControlLabel",
IDS_SETTINGS_BRAVE_SHIELDS_HTTPS_EVERYWHERE_CONTROL_LABEL},
{"noScriptControlLabel",
diff --git a/chromium_src/third_party/blink/public/platform/web_content_settings_client.h b/chromium_src/third_party/blink/public/platform/web_content_settings_client.h
index 1d624c103d1d..f36ed0eec5ae 100644
--- a/chromium_src/third_party/blink/public/platform/web_content_settings_client.h
+++ b/chromium_src/third_party/blink/public/platform/web_content_settings_client.h
@@ -23,6 +23,7 @@ class GURL;
virtual BraveFarblingLevel GetBraveFarblingLevel() { \
return BraveFarblingLevel::OFF; \
} \
+ virtual bool IsReduceLanguageEnabled() { return true; } \
virtual blink::WebSecurityOrigin GetEphemeralStorageOriginSync() { \
return blink::WebSecurityOrigin(); \
} \
diff --git a/chromium_src/third_party/blink/renderer/core/core_initializer.cc b/chromium_src/third_party/blink/renderer/core/core_initializer.cc
new file mode 100644
index 000000000000..8a2118a0f274
--- /dev/null
+++ b/chromium_src/third_party/blink/renderer/core/core_initializer.cc
@@ -0,0 +1,13 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+#include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+
+#define BindingSecurity \
+ brave::BraveSessionCache::Init(); \
+ BindingSecurity
+
+#include "src/third_party/blink/renderer/core/core_initializer.cc"
diff --git a/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc b/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc
index 6910f273804e..465642bc1fc2 100644
--- a/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc
+++ b/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -6,7 +6,10 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "base/command_line.h"
+#include "base/sequence_checker.h"
#include "base/strings/string_number_conversions.h"
+#include "brave/third_party/blink/renderer/brave_farbling_constants.h"
+#include "brave/third_party/blink/renderer/brave_font_whitelist.h"
#include "crypto/hmac.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -14,10 +17,12 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/fonts/font_fallback_list.h"
#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -103,6 +108,22 @@ bool AllowFingerprinting(ExecutionContext* context) {
return true;
}
+bool AllowFontFamily(ExecutionContext* context,
+ const AtomicString& family_name) {
+ if (!context)
+ return true;
+
+ auto* settings = brave::GetContentSettingsClientFor(context);
+ if (!settings)
+ return true;
+
+ if (!brave::BraveSessionCache::From(*context).AllowFontFamily(settings,
+ family_name))
+ return false;
+
+ return true;
+}
+
BraveSessionCache::BraveSessionCache(ExecutionContext& context)
: Supplement(context) {
farbling_enabled_ = false;
@@ -127,10 +148,17 @@ BraveSessionCache::BraveSessionCache(ExecutionContext& context)
.Utf8();
if (domain.empty())
return;
+
base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
- DCHECK(cmd_line->HasSwitch(kBraveSessionToken));
- base::StringToUint64(cmd_line->GetSwitchValueASCII(kBraveSessionToken),
- &session_key_);
+ base::StringToUint64(
+ cmd_line->HasSwitch(kBraveSessionToken)
+ ? cmd_line->GetSwitchValueASCII(kBraveSessionToken)
+ // https://github.com/brave/brave-browser/issues/22021
+ : "23456", // this is intentionally different from the test default
+ // of 12345 so we can still detect any switch issues in
+ // our farbling tests
+ &session_key_);
+
crypto::HMAC h(crypto::HMAC::SHA256);
CHECK(h.Init(reinterpret_cast(&session_key_),
sizeof session_key_));
@@ -148,6 +176,11 @@ BraveSessionCache& BraveSessionCache::From(ExecutionContext& context) {
return *cache;
}
+// static
+void BraveSessionCache::Init() {
+ RegisterAllowFontFamilyCallback(base::BindRepeating(&brave::AllowFontFamily));
+}
+
AudioFarblingCallback BraveSessionCache::GetAudioFarblingCallback(
blink::WebContentSettingsClient* settings) {
if (farbling_enabled_ && settings) {
@@ -263,6 +296,35 @@ WTF::String BraveSessionCache::FarbledUserAgent(WTF::String real_user_agent) {
return result.ToString();
}
+bool BraveSessionCache::AllowFontFamily(
+ blink::WebContentSettingsClient* settings,
+ const AtomicString& family_name) {
+ if (!CanRestrictFontFamiliesOnThisPlatform() || !farbling_enabled_ ||
+ !settings || !settings->IsReduceLanguageEnabled())
+ return true;
+ switch (settings->GetBraveFarblingLevel()) {
+ case BraveFarblingLevel::OFF:
+ break;
+ case BraveFarblingLevel::BALANCED:
+ case BraveFarblingLevel::MAXIMUM: {
+ if (GetAllowedFontFamilies().contains(family_name.Utf8()))
+ return true;
+#if BUILDFLAG(IS_WIN)
+ WTF::String locale = blink::DefaultLanguage().GetString().Left(2);
+ if (GetAdditionalAllowedFontFamiliesByLocale(locale).contains(
+ family_name.Utf8()))
+ return true;
+#endif
+ std::mt19937_64 prng = MakePseudoRandomGenerator();
+ prng.discard(family_name.Impl()->GetHash() % 16);
+ return ((prng() % 2) == 0);
+ }
+ default:
+ NOTREACHED();
+ }
+ return true;
+}
+
std::mt19937_64 BraveSessionCache::MakePseudoRandomGenerator() {
uint64_t seed = *reinterpret_cast(domain_key_);
return std::mt19937_64(seed);
diff --git a/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.h b/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.h
index efd7ec40587e..03c758b59b49 100644
--- a/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.h
+++ b/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -6,12 +6,13 @@
#ifndef BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_H_
#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_H_
-#include "src/third_party/blink/renderer/core/execution_context/execution_context.h"
-
#include
#include "base/callback.h"
#include "brave/third_party/blink/renderer/brave_farbling_constants.h"
+#include "src/third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
class WebContentSettingsClient;
@@ -32,6 +33,8 @@ CORE_EXPORT BraveFarblingLevel
GetBraveFarblingLevelFor(ExecutionContext* context,
BraveFarblingLevel default_value);
CORE_EXPORT bool AllowFingerprinting(ExecutionContext* context);
+CORE_EXPORT bool AllowFontFamily(ExecutionContext* context,
+ const AtomicString& family_name);
class CORE_EXPORT BraveSessionCache final
: public GarbageCollected,
@@ -43,6 +46,7 @@ class CORE_EXPORT BraveSessionCache final
virtual ~BraveSessionCache() = default;
static BraveSessionCache& From(ExecutionContext&);
+ static void Init();
AudioFarblingCallback GetAudioFarblingCallback(
blink::WebContentSettingsClient* settings);
@@ -51,6 +55,8 @@ class CORE_EXPORT BraveSessionCache final
size_t size);
WTF::String GenerateRandomString(std::string seed, wtf_size_t length);
WTF::String FarbledUserAgent(WTF::String real_user_agent);
+ bool AllowFontFamily(blink::WebContentSettingsClient* settings,
+ const AtomicString& family_name);
std::mt19937_64 MakePseudoRandomGenerator();
private:
diff --git a/chromium_src/third_party/blink/renderer/core/frame/navigator_language.cc b/chromium_src/third_party/blink/renderer/core/frame/navigator_language.cc
new file mode 100644
index 000000000000..8e417c9bcd80
--- /dev/null
+++ b/chromium_src/third_party/blink/renderer/core/frame/navigator_language.cc
@@ -0,0 +1,41 @@
+/* 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 "third_party/blink/renderer/core/frame/navigator_language.h"
+
+#include "third_party/blink/public/platform/web_content_settings_client.h"
+
+#define NavigatorLanguage NavigatorLanguage_ChromiumImpl
+#include "src/third_party/blink/renderer/core/frame/navigator_language.cc"
+#undef NavigatorLanguage
+
+namespace blink {
+
+NavigatorLanguage::NavigatorLanguage(ExecutionContext* execution_context)
+ : NavigatorLanguage_ChromiumImpl(execution_context) {}
+
+void NavigatorLanguage::EnsureUpdatedLanguage() {
+ NavigatorLanguage_ChromiumImpl::EnsureUpdatedLanguage();
+ blink::WebContentSettingsClient* settings =
+ brave::GetContentSettingsClientFor(execution_context_);
+ // If Brave Shields are down or anti-fingerprinting is off for this site,
+ // do nothing.
+ if (!settings || settings->GetBraveFarblingLevel() == BraveFarblingLevel::OFF)
+ return;
+ if (settings->GetBraveFarblingLevel() == BraveFarblingLevel::MAXIMUM) {
+ // If anti-fingerprinting is at maximum, override the entire language list
+ // regardless of locale or other settings.
+ languages_.clear();
+ languages_.push_back("en-US");
+ languages_.push_back("en");
+ } else {
+ // If anti-fingerprinting is on at its default level, remove all but the
+ // first language. (Note: this method requires a non-empty list, which the
+ // upstream code guarantees.)
+ languages_.Shrink(1);
+ }
+}
+
+} // namespace blink
diff --git a/chromium_src/third_party/blink/renderer/core/frame/navigator_language.h b/chromium_src/third_party/blink/renderer/core/frame/navigator_language.h
new file mode 100644
index 000000000000..966869518ad6
--- /dev/null
+++ b/chromium_src/third_party/blink/renderer/core/frame/navigator_language.h
@@ -0,0 +1,33 @@
+/* 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/. */
+
+#ifndef BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_LANGUAGE_H_
+#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_LANGUAGE_H_
+
+#define NavigatorLanguage NavigatorLanguage_ChromiumImpl
+#define EnsureUpdatedLanguage \
+ UnusedMethod() {} \
+ \
+ protected: \
+ virtual void EnsureUpdatedLanguage
+
+#include "src/third_party/blink/renderer/core/frame/navigator_language.h"
+
+#undef EnsureUpdatedLanguage
+#undef NavigatorLanguage
+
+namespace blink {
+
+class CORE_EXPORT NavigatorLanguage : public NavigatorLanguage_ChromiumImpl {
+ public:
+ explicit NavigatorLanguage(ExecutionContext*);
+
+ protected:
+ void EnsureUpdatedLanguage() override;
+};
+
+} // namespace blink
+
+#endif // BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_LANGUAGE_H_
diff --git a/chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
new file mode 100644
index 000000000000..73578d3ccb7d
--- /dev/null
+++ b/chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -0,0 +1,40 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+#include "third_party/blink/renderer/platform/fonts/font_fallback_list.h"
+
+#include "base/no_destructor.h"
+#include "third_party/blink/renderer/platform/fonts/font_selector.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+
+namespace brave {
+
+namespace {
+
+AllowFontFamilyCallback* GetAllowFontFamilyCallback() {
+ static base::NoDestructor callback;
+ return callback.get();
+}
+
+} // namespace
+
+void RegisterAllowFontFamilyCallback(AllowFontFamilyCallback callback) {
+ DCHECK(GetAllowFontFamilyCallback()->is_null());
+ *GetAllowFontFamilyCallback() = std::move(callback);
+}
+
+} // namespace brave
+
+// This only runs if the relevant font selector (CSS or offscreen)
+// does NOT find a matching font, because we want to allow web fonts
+// unconditionally.
+#define BRAVE_GET_FONT_DATA \
+ if (brave::GetAllowFontFamilyCallback() && \
+ !brave::GetAllowFontFamilyCallback()->Run( \
+ GetFontSelector()->GetExecutionContext(), \
+ curr_family->FamilyName())) \
+ result = nullptr;
+
+#include "src/third_party/blink/renderer/platform/fonts/font_fallback_list.cc"
diff --git a/chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.h b/chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.h
new file mode 100644
index 000000000000..01af5f276bf5
--- /dev/null
+++ b/chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.h
@@ -0,0 +1,29 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_LIST_H_
+#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_LIST_H_
+
+#include "base/callback.h"
+#include "src/third_party/blink/renderer/platform/fonts/font_fallback_list.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+
+namespace blink {
+class ExecutionContext;
+}
+
+namespace brave {
+
+typedef base::RepeatingCallback
+ AllowFontFamilyCallback;
+
+PLATFORM_EXPORT void RegisterAllowFontFamilyCallback(
+ AllowFontFamilyCallback callback);
+
+} // namespace brave
+
+#endif // BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_LIST_H_
diff --git a/components/brave_shields/browser/BUILD.gn b/components/brave_shields/browser/BUILD.gn
index 3ce8bbdf90bd..9948b68442dc 100644
--- a/components/brave_shields/browser/BUILD.gn
+++ b/components/brave_shields/browser/BUILD.gn
@@ -39,6 +39,8 @@ static_library("browser") {
"base_brave_shields_service.h",
"blocked_domain_1pes_lifetime.cc",
"blocked_domain_1pes_lifetime.h",
+ "brave_farbling_service.cc",
+ "brave_farbling_service.h",
"brave_shields_p3a.cc",
"brave_shields_p3a.h",
"brave_shields_util.cc",
@@ -74,6 +76,7 @@ static_library("browser") {
"//components/component_updater:component_updater",
"//components/content_settings/core/browser",
"//components/content_settings/core/common",
+ "//components/pref_registry:pref_registry",
"//components/prefs",
"//components/security_interstitials/content:security_interstitial_page",
"//components/security_interstitials/core",
diff --git a/components/brave_shields/browser/brave_farbling_service.cc b/components/brave_shields/browser/brave_farbling_service.cc
new file mode 100644
index 000000000000..4a3b6857d276
--- /dev/null
+++ b/components/brave_shields/browser/brave_farbling_service.cc
@@ -0,0 +1,64 @@
+/* Copyright 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/components/brave_shields/browser/brave_farbling_service.h"
+
+#include
+
+#include "base/rand_util.h"
+#include "brave/components/brave_shields/common/pref_names.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "crypto/hmac.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "url/gurl.h"
+
+namespace brave {
+
+BraveFarblingService::BraveFarblingService() {
+ // initialize random seeds for farbling
+ session_token_ = base::RandUint64();
+ incognito_session_token_ = base::RandUint64();
+}
+
+BraveFarblingService::~BraveFarblingService() {}
+
+uint64_t BraveFarblingService::session_token(bool is_off_the_record) {
+ if (is_off_the_record)
+ return incognito_session_token_;
+ return session_token_;
+}
+
+void BraveFarblingService::set_session_tokens_for_testing() {
+ session_token_ = incognito_session_token_ = 12345;
+}
+
+bool BraveFarblingService::MakePseudoRandomGeneratorForURL(
+ const GURL& url,
+ bool is_off_the_record,
+ std::mt19937_64* prng) {
+ const std::string domain =
+ net::registry_controlled_domains::GetDomainAndRegistry(
+ url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+ if (domain.empty())
+ return false;
+ uint8_t domain_key[32];
+ uint64_t session_key = session_token(is_off_the_record);
+ crypto::HMAC h(crypto::HMAC::SHA256);
+ CHECK(h.Init(reinterpret_cast(&session_key),
+ sizeof session_key));
+ CHECK(h.Sign(domain, domain_key, sizeof domain_key));
+ uint64_t seed = *reinterpret_cast(domain_key);
+ *prng = std::mt19937_64(seed);
+ return true;
+}
+
+// static
+void BraveFarblingService::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterBooleanPref(brave_shields::prefs::kReduceLanguageEnabled,
+ true);
+}
+
+} // namespace brave
diff --git a/components/brave_shields/browser/brave_farbling_service.h b/components/brave_shields/browser/brave_farbling_service.h
new file mode 100644
index 000000000000..5f37b693ae50
--- /dev/null
+++ b/components/brave_shields/browser/brave_farbling_service.h
@@ -0,0 +1,40 @@
+/* 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/. */
+
+#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_BRAVE_FARBLING_SERVICE_H_
+#define BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_BRAVE_FARBLING_SERVICE_H_
+
+// https://github.com/brave/brave-browser/issues/21931
+#include
+
+class GURL;
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+namespace brave {
+
+class BraveFarblingService {
+ public:
+ BraveFarblingService();
+ ~BraveFarblingService();
+
+ uint64_t session_token(bool is_off_the_record);
+ void set_session_tokens_for_testing();
+ bool MakePseudoRandomGeneratorForURL(const GURL& url,
+ bool is_off_the_record,
+ std::mt19937_64* prng);
+
+ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+ private:
+ uint64_t session_token_;
+ uint64_t incognito_session_token_;
+};
+
+} // namespace brave
+
+#endif // BRAVE_COMPONENTS_BRAVE_SHIELDS_BROWSER_BRAVE_FARBLING_SERVICE_H_
diff --git a/components/brave_shields/browser/brave_shields_util.cc b/components/brave_shields/browser/brave_shields_util.cc
index 7c6a753a87a0..b055ec37acc2 100644
--- a/components/brave_shields/browser/brave_shields_util.cc
+++ b/components/brave_shields/browser/brave_shields_util.cc
@@ -13,11 +13,13 @@
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "brave/components/brave_shields/common/brave_shield_utils.h"
#include "brave/components/brave_shields/common/features.h"
+#include "brave/components/brave_shields/common/pref_names.h"
#include "brave/components/content_settings/core/common/content_settings_util.h"
#include "brave/components/debounce/common/features.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/pref_names.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/referrer.h"
#include "net/base/features.h"
@@ -248,6 +250,37 @@ bool ShouldDoDebouncing(HostContentSettingsMap* map, const GURL& url) {
return true;
}
+bool IsReduceLanguageEnabledForProfile(PrefService* pref_service) {
+ // Don't reduce language if feature is disabled
+ if (!base::FeatureList::IsEnabled(features::kBraveReduceLanguage))
+ return false;
+
+ // Don't reduce language if user preference is unchecked
+ if (!pref_service->GetBoolean(brave_shields::prefs::kReduceLanguageEnabled))
+ return false;
+
+ return true;
+}
+
+bool ShouldDoReduceLanguage(HostContentSettingsMap* map,
+ const GURL& url,
+ PrefService* pref_service) {
+ if (!IsReduceLanguageEnabledForProfile(pref_service))
+ return false;
+
+ // Don't reduce language if Brave Shields is down (this also handles cases
+ // where the URL is not HTTP(S))
+ if (!brave_shields::GetBraveShieldsEnabled(map, url))
+ return false;
+
+ // Don't reduce language if fingerprinting is off
+ if (brave_shields::GetFingerprintingControlType(map, url) ==
+ ControlType::ALLOW)
+ return false;
+
+ return true;
+}
+
DomainBlockingType GetDomainBlockingType(HostContentSettingsMap* map,
const GURL& url) {
// Don't block if feature is disabled
diff --git a/components/brave_shields/browser/brave_shields_util.h b/components/brave_shields/browser/brave_shields_util.h
index d17b28ba3362..99e86cb12fdb 100644
--- a/components/brave_shields/browser/brave_shields_util.h
+++ b/components/brave_shields/browser/brave_shields_util.h
@@ -72,6 +72,12 @@ bool IsFirstPartyCosmeticFilteringEnabled(HostContentSettingsMap* map,
bool ShouldDoDebouncing(HostContentSettingsMap* map, const GURL& url);
+bool IsReduceLanguageEnabledForProfile(PrefService* pref_service);
+
+bool ShouldDoReduceLanguage(HostContentSettingsMap* map,
+ const GURL& url,
+ PrefService* pref_service);
+
DomainBlockingType GetDomainBlockingType(HostContentSettingsMap* map,
const GURL& url);
diff --git a/components/brave_shields/common/brave_shields.mojom b/components/brave_shields/common/brave_shields.mojom
index 634a2167d7fb..de477cff7760 100644
--- a/components/brave_shields/common/brave_shields.mojom
+++ b/components/brave_shields/common/brave_shields.mojom
@@ -16,4 +16,8 @@ interface BraveShields {
// Tell the associated RenderFrame(s) to temporary allow scripts from a list
// of origins once.
SetAllowScriptsFromOriginsOnce(array origins);
+
+ // Tell the associated RenderFrame(s) whether "reduce language
+ // identifiability" is enabled.
+ SetReduceLanguageEnabled(bool enabled);
};
diff --git a/components/brave_shields/common/features.cc b/components/brave_shields/common/features.cc
index 9bc6309ace3d..c1d4f92723c9 100644
--- a/components/brave_shields/common/features.cc
+++ b/components/brave_shields/common/features.cc
@@ -51,6 +51,9 @@ const base::Feature kBraveDomainBlock1PES{"BraveDomainBlock1PES",
// potentially blocked by Brave Shields.
const base::Feature kBraveExtensionNetworkBlocking{
"BraveExtensionNetworkBlocking", base::FEATURE_DISABLED_BY_DEFAULT};
+// When enabled, language headers and APIs may be altered by Brave Shields.
+const base::Feature kBraveReduceLanguage{"BraveReduceLanguage",
+ base::FEATURE_ENABLED_BY_DEFAULT};
// When enabled, Brave will always report Light in Fingerprinting: Strict mode
const base::Feature kBraveDarkModeBlock{"BraveDarkModeBlock",
base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/brave_shields/common/features.h b/components/brave_shields/common/features.h
index 694a12c6bd2e..8b6d65f79657 100644
--- a/components/brave_shields/common/features.h
+++ b/components/brave_shields/common/features.h
@@ -21,6 +21,7 @@ extern const base::Feature kBraveAdblockCspRules;
extern const base::Feature kBraveDomainBlock;
extern const base::Feature kBraveDomainBlock1PES;
extern const base::Feature kBraveExtensionNetworkBlocking;
+extern const base::Feature kBraveReduceLanguage;
extern const base::Feature kBraveDarkModeBlock;
extern const base::Feature kCosmeticFilteringSyncLoad;
extern const base::Feature kBraveShieldsPanelV1;
diff --git a/components/brave_shields/common/pref_names.cc b/components/brave_shields/common/pref_names.cc
index fa5d9a7c0c55..8492b74a804b 100644
--- a/components/brave_shields/common/pref_names.cc
+++ b/components/brave_shields/common/pref_names.cc
@@ -18,6 +18,7 @@ const char kAdBlockListSubscriptions[] = "brave.ad_block.list_subscriptions";
const char kFBEmbedControlType[] = "brave.fb_embed_default";
const char kTwitterEmbedControlType[] = "brave.twitter_embed_default";
const char kLinkedInEmbedControlType[] = "brave.linkedin_embed_default";
+const char kReduceLanguageEnabled[] = "brave.reduce_language";
} // namespace prefs
} // namespace brave_shields
diff --git a/components/brave_shields/common/pref_names.h b/components/brave_shields/common/pref_names.h
index b58d16a2d50c..f6bacde55a93 100644
--- a/components/brave_shields/common/pref_names.h
+++ b/components/brave_shields/common/pref_names.h
@@ -17,6 +17,7 @@ extern const char kAdBlockListSubscriptions[];
extern const char kFBEmbedControlType[];
extern const char kTwitterEmbedControlType[];
extern const char kLinkedInEmbedControlType[];
+extern const char kReduceLanguageEnabled[];
} // namespace prefs
} // namespace brave_shields
diff --git a/components/content_settings/renderer/brave_content_settings_agent_impl.cc b/components/content_settings/renderer/brave_content_settings_agent_impl.cc
index 161020295be4..3da18932b5cc 100644
--- a/components/content_settings/renderer/brave_content_settings_agent_impl.cc
+++ b/components/content_settings/renderer/brave_content_settings_agent_impl.cc
@@ -108,6 +108,10 @@ bool BraveContentSettingsAgentImpl::IsScriptTemporilyAllowed(
return allow;
}
+bool BraveContentSettingsAgentImpl::IsReduceLanguageEnabled() {
+ return reduce_language_enabled_;
+}
+
void BraveContentSettingsAgentImpl::BraveSpecificDidBlockJavaScript(
const std::u16string& details) {
mojo::AssociatedRemote remote;
@@ -353,6 +357,10 @@ void BraveContentSettingsAgentImpl::SetAllowScriptsFromOriginsOnce(
temporarily_allowed_scripts_ = origins;
}
+void BraveContentSettingsAgentImpl::SetReduceLanguageEnabled(bool enabled) {
+ reduce_language_enabled_ = enabled;
+}
+
void BraveContentSettingsAgentImpl::BindBraveShieldsReceiver(
mojo::PendingAssociatedReceiver
pending_receiver) {
diff --git a/components/content_settings/renderer/brave_content_settings_agent_impl.h b/components/content_settings/renderer/brave_content_settings_agent_impl.h
index 75d76c18ab51..9e65274b1c51 100644
--- a/components/content_settings/renderer/brave_content_settings_agent_impl.h
+++ b/components/content_settings/renderer/brave_content_settings_agent_impl.h
@@ -64,6 +64,8 @@ class BraveContentSettingsAgentImpl
BraveFarblingLevel GetBraveFarblingLevel() override;
+ bool IsReduceLanguageEnabled() override;
+
private:
FRIEND_TEST_ALL_PREFIXES(BraveContentSettingsAgentImplAutoplayBrowserTest,
AutoplayBlockedByDefault);
@@ -78,6 +80,7 @@ class BraveContentSettingsAgentImpl
// brave_shields::mojom::BraveShields.
void SetAllowScriptsFromOriginsOnce(
const std::vector& origins) override;
+ void SetReduceLanguageEnabled(bool enabled) override;
void BindBraveShieldsReceiver(
mojo::PendingAssociatedReceiver
@@ -95,6 +98,9 @@ class BraveContentSettingsAgentImpl
// cache blocked script url which will later be used in `DidNotAllowScript()`
GURL blocked_script_url_;
+ // Status of "reduce language identifiability" feature.
+ bool reduce_language_enabled_;
+
base::flat_map
cached_ephemeral_storage_origins_;
diff --git a/patches/third_party-blink-renderer-platform-fonts-font_fallback_list.cc.patch b/patches/third_party-blink-renderer-platform-fonts-font_fallback_list.cc.patch
new file mode 100644
index 000000000000..cc9b55b862b5
--- /dev/null
+++ b/patches/third_party-blink-renderer-platform-fonts-font_fallback_list.cc.patch
@@ -0,0 +1,12 @@
+diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+index 62d4121f7078b90cc08ba72bb53b5c96f73c0a31..c47dd22f421ee71473304484ab0ef26b808745a6 100644
+--- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
++++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+@@ -173,6 +173,7 @@ scoped_refptr FontFallbackList::GetFontData(
+ GetFontSelector()->ReportFontLookupByUniqueOrFamilyName(
+ curr_family->FamilyName(), font_description,
+ DynamicTo(result.get()));
++ BRAVE_GET_FONT_DATA
+ }
+ }
+ if (result) {
diff --git a/test/base/testing_brave_browser_process.cc b/test/base/testing_brave_browser_process.cc
index 0dda32d06a4a..24353ee34e30 100644
--- a/test/base/testing_brave_browser_process.cc
+++ b/test/base/testing_brave_browser_process.cc
@@ -132,6 +132,12 @@ brave_ads::ResourceComponent* TestingBraveBrowserProcess::resource_component() {
return nullptr;
}
+brave::BraveFarblingService*
+TestingBraveBrowserProcess::brave_farbling_service() {
+ NOTREACHED();
+ return nullptr;
+}
+
void TestingBraveBrowserProcess::SetAdBlockService(
std::unique_ptr service) {
ad_block_service_ = std::move(service);
diff --git a/test/base/testing_brave_browser_process.h b/test/base/testing_brave_browser_process.h
index 5e034a09e627..1f409d7e1c83 100644
--- a/test/base/testing_brave_browser_process.h
+++ b/test/base/testing_brave_browser_process.h
@@ -69,6 +69,7 @@ class TestingBraveBrowserProcess : public BraveBrowserProcess {
override;
#endif
brave_ads::ResourceComponent* resource_component() override;
+ brave::BraveFarblingService* brave_farbling_service() override;
// Populate the mock process with services. Consumer is responsible for
// cleaning these up after completion of a test.
diff --git a/test/data/navigator/service-workers-languages.html b/test/data/navigator/service-workers-languages.html
new file mode 100644
index 000000000000..200d7e7c1159
--- /dev/null
+++ b/test/data/navigator/service-workers-languages.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/data/navigator/service-workers-languages.js b/test/data/navigator/service-workers-languages.js
new file mode 100644
index 000000000000..83e42ca12ea6
--- /dev/null
+++ b/test/data/navigator/service-workers-languages.js
@@ -0,0 +1,11 @@
+self.addEventListener('install', function(event) {
+ event.waitUntil(self.skipWaiting()); // Activate worker immediately
+});
+
+self.addEventListener('activate', function(event) {
+ event.waitUntil(self.clients.claim()); // Become available to all pages
+});
+self.addEventListener('message', async event => {
+ const client = await clients.get(event.source.id)
+ client.postMessage(navigator.languages.toString());
+});
diff --git a/test/data/navigator/workers-languages.html b/test/data/navigator/workers-languages.html
new file mode 100644
index 000000000000..effd72c2e901
--- /dev/null
+++ b/test/data/navigator/workers-languages.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/third_party/blink/renderer/BUILD.gn b/third_party/blink/renderer/BUILD.gn
index 41aac3e98580..2e5be029e175 100644
--- a/third_party/blink/renderer/BUILD.gn
+++ b/third_party/blink/renderer/BUILD.gn
@@ -6,9 +6,9 @@
source_set("renderer") {
sources = [
"brave_farbling_constants.h",
+ "brave_font_whitelist.cc",
+ "brave_font_whitelist.h",
]
- deps = [
- "//brave/components/brave_drm:brave_drm_blink",
- ]
+ deps = [ "//brave/components/brave_drm:brave_drm_blink" ]
}
diff --git a/third_party/blink/renderer/DEPS b/third_party/blink/renderer/DEPS
new file mode 100644
index 000000000000..c79f0a833681
--- /dev/null
+++ b/third_party/blink/renderer/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+third_party/blink/renderer/platform/wtf/text",
+]
diff --git a/third_party/blink/renderer/brave_font_whitelist.cc b/third_party/blink/renderer/brave_font_whitelist.cc
new file mode 100644
index 000000000000..cfa37b27fc69
--- /dev/null
+++ b/third_party/blink/renderer/brave_font_whitelist.cc
@@ -0,0 +1,752 @@
+/* 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/third_party/blink/renderer/brave_font_whitelist.h"
+
+#include
+
+namespace brave {
+
+namespace {
+
+base::flat_set kEmptyFontSet =
+ base::MakeFlatSet(std::vector{});
+
+#if BUILDFLAG(IS_MAC)
+// This list covers the fonts installed by default on Mac OS as of Mac OS 12.3.
+base::flat_set kAllowedFontFamilies =
+ base::MakeFlatSet(std::vector{
+ "Al Bayan",
+ "Al Nile",
+ "Al Tarikh",
+ "American Typewriter",
+ "Andale Mono",
+ "Apple Braille Outline 6 Dot",
+ "Apple Braille Outline 8 Dot",
+ "Apple Braille Pinpoint 6 Dot",
+ "Apple Braille Pinpoint 8 Dot",
+ "Apple Braille",
+ "Apple Color Emoji",
+ "Apple SD Gothic Neo",
+ "Apple Symbols",
+ "AppleGothic",
+ "AppleMyungjo",
+ "AquaKana",
+ "Arial Black",
+ "Arial Hebrew Scholar",
+ "Arial Hebrew",
+ "Arial Narrow",
+ "Arial Rounded MT Bold",
+ "Arial Unicode MS",
+ "Arial",
+ "Athelas",
+ "Avenir Black Oblique",
+ "Avenir Black",
+ "Avenir Book",
+ "Avenir Heavy",
+ "Avenir Light",
+ "Avenir Medium",
+ "Avenir Next Condensed Demi Bold",
+ "Avenir Next Condensed Heavy",
+ "Avenir Next Condensed Medium",
+ "Avenir Next Condensed Ultra Light",
+ "Avenir Next Condensed",
+ "Avenir Next Demi Bold",
+ "Avenir Next Heavy",
+ "Avenir Next Medium",
+ "Avenir Next Ultra Light",
+ "Avenir Next",
+ "Avenir",
+ "Ayuthaya",
+ "Baghdad",
+ "Bangla MN",
+ "Bangla Sangam MN",
+ "Baskerville",
+ "Beirut",
+ "Big Caslon",
+ "Bodoni Ornaments",
+ "Bradley Hand",
+ "Brush Script MT",
+ "Chalkboard SE",
+ "Chalkboard",
+ "Chalkduster",
+ "Charter Black",
+ "Charter",
+ "Cochin",
+ "Comic Sans MS",
+ "Copperplate",
+ "Corsiva Hebrew",
+ "Courier New",
+ "DIN Alternate",
+ "DIN Condensed",
+ "Damascus",
+ "DecoType Naskh",
+ "Devanagari MT",
+ "Devanagari Sangam MN",
+ "Didot",
+ "Diwan Kufi",
+ "Diwan Thuluth",
+ "Euphemia UCAS",
+ "Farah",
+ "Farisi",
+ "Futura",
+ "GB18030 Bitmap",
+ "Galvji",
+ "Geeza Pro",
+ "Geneva",
+ "Georgia",
+ "Gill Sans",
+ "Gujarati MT",
+ "Gujarati Sangam MN",
+ "Gurmukhi MN",
+ "Gurmukhi MT",
+ "Gurmukhi Sangam MN",
+ "Heiti SC",
+ "Heiti TC",
+ "Helvetica Neue",
+ "Herculanum",
+ "Hiragino Kaku Gothic Pro W3",
+ "Hiragino Kaku Gothic Pro W6",
+ "Hiragino Kaku Gothic Pro",
+ "Hiragino Kaku Gothic ProN W3",
+ "Hiragino Kaku Gothic ProN W6",
+ "Hiragino Kaku Gothic ProN",
+ "Hiragino Kaku Gothic Std W8",
+ "Hiragino Kaku Gothic Std",
+ "Hiragino Kaku Gothic StdN W8",
+ "Hiragino Kaku Gothic StdN",
+ "Hiragino Maru Gothic Pro W4",
+ "Hiragino Maru Gothic Pro",
+ "Hiragino Maru Gothic ProN W4",
+ "Hiragino Maru Gothic ProN",
+ "Hiragino Mincho Pro W3",
+ "Hiragino Mincho Pro W6",
+ "Hiragino Mincho Pro",
+ "Hiragino Mincho ProN W3",
+ "Hiragino Mincho ProN W6",
+ "Hiragino Mincho ProN",
+ "Hiragino Sans GB W3",
+ "Hiragino Sans GB W6",
+ "Hiragino Sans GB",
+ "Hiragino Sans W0",
+ "Hiragino Sans W1",
+ "Hiragino Sans W2",
+ "Hiragino Sans W3",
+ "Hiragino Sans W4",
+ "Hiragino Sans W5",
+ "Hiragino Sans W6",
+ "Hiragino Sans W7",
+ "Hiragino Sans W8",
+ "Hiragino Sans W9",
+ "Hiragino Sans",
+ "Hoefler Text Ornaments",
+ "Hoefler Text",
+ "ITF Devanagari Marathi",
+ "ITF Devanagari",
+ "Impact",
+ "InaiMathi",
+ "Iowan Old Style Black",
+ "Iowan Old Style",
+ "Kailasa",
+ "Kannada MN",
+ "Kannada Sangam MN",
+ "Kefa",
+ "Khmer MN",
+ "Khmer Sangam MN",
+ "Kohinoor Bangla",
+ "Kohinoor Devanagari",
+ "Kohinoor Gujarati",
+ "Kohinoor Telugu",
+ "Kokonor",
+ "Krungthep",
+ "KufiStandardGK",
+ "Lao MN",
+ "Lao Sangam MN",
+ "LastResort",
+ "Lucida Grande",
+ "Luminari",
+ "Malayalam MN",
+ "Malayalam Sangam MN",
+ "Marion",
+ "Marker Felt",
+ "Menlo",
+ "Microsoft Sans Serif",
+ "Mishafi Gold",
+ "Mishafi",
+ "Monaco",
+ "Mshtakan",
+ "Muna",
+ "Myanmar MN",
+ "Myanmar Sangam MN",
+ "Nadeem",
+ "New Peninim MT",
+ "Noteworthy",
+ "Noto Nastaliq Urdu",
+ "Noto Sans Gothic",
+ "Noto Sans Linear A",
+ "Noto Sans Linear B",
+ "Noto Sans Old Italic",
+ "Noto Serif Ahom",
+ "Noto Serif Balinese",
+ "Noto Serif Myanmar",
+ "Optima",
+ "Oriya MN",
+ "Oriya Sangam MN",
+ "PT Mono",
+ "PT Sans Caption",
+ "PT Sans Narrow",
+ "PT Sans",
+ "PT Serif Caption",
+ "PT Serif",
+ "Palatino",
+ "Phosphate",
+ "PingFang HK",
+ "PingFang SC",
+ "PingFang TC",
+ "Plantagenet Cherokee",
+ "Raanana",
+ "Rockwell",
+ "STIXGeneral",
+ "STIXGeneral-Bold",
+ "STIXGeneral-BoldItalic",
+ "STIXGeneral-Italic",
+ "STIXGeneral-Regular",
+ "STIXIntegralsD",
+ "STIXIntegralsD-Bold",
+ "STIXIntegralsD-Regular",
+ "STIXIntegralsSm",
+ "STIXIntegralsSm-Bold",
+ "STIXIntegralsSm-Regular",
+ "STIXIntegralsUp",
+ "STIXIntegralsUp-Bold",
+ "STIXIntegralsUp-Regular",
+ "STIXIntegralsUpD",
+ "STIXIntegralsUpD-Bold",
+ "STIXIntegralsUpD-Regular",
+ "STIXIntegralsUpSm",
+ "STIXIntegralsUpSm-Bold",
+ "STIXIntegralsUpSm-Regular",
+ "STIXNonUnicode",
+ "STIXNonUnicode-Bold",
+ "STIXNonUnicode-BoldItalic",
+ "STIXNonUnicode-Italic",
+ "STIXNonUnicode-Regular",
+ "STIXSizeFiveSym",
+ "STIXSizeFiveSym-Regular",
+ "STIXSizeFourSym",
+ "STIXSizeFourSym-Bold",
+ "STIXSizeFourSym-Regular",
+ "STIXSizeOneSym",
+ "STIXSizeOneSym-Bold",
+ "STIXSizeOneSym-Regular",
+ "STIXSizeThreeSym",
+ "STIXSizeThreeSym-Bold",
+ "STIXSizeThreeSym-Regular",
+ "STIXSizeTwoSym",
+ "STIXSizeTwoSym-Bold",
+ "STIXSizeTwoSym-Regular",
+ "STIXVariants",
+ "STIXVariants-Bold",
+ "STIXVariants-Regular",
+ "STSong",
+ "Sana",
+ "Sathu",
+ "Savoye LET Plain CC.:1.0",
+ "Savoye LET Plain:1.0",
+ "Savoye LET",
+ "Seravek ExtraLight",
+ "Seravek Light",
+ "Seravek Medium",
+ "Seravek",
+ "SignPainter",
+ "SignPainter-HouseScript",
+ "Silom",
+ "Sinhala MN",
+ "Sinhala Sangam MN",
+ "Skia",
+ "Snell Roundhand",
+ "Songti SC",
+ "Songti TC",
+ "Sukhumvit Set",
+ "Superclarendon",
+ "Symbol",
+ "Tahoma",
+ "Tamil MN",
+ "Tamil Sangam MN",
+ "Telugu MN",
+ "Telugu Sangam MN",
+ "Thonburi",
+ "Times New Roman",
+ "Trattatello",
+ "Trebuchet MS",
+ "Verdana",
+ "Waseem",
+ "Webdings",
+ "Wingdings 2",
+ "Wingdings 3",
+ "Wingdings",
+ "Zapf Dingbats",
+ "Zapfino",
+ });
+#elif BUILDFLAG(IS_WIN)
+// This list covers the fonts installed by default on Windows 11.
+// See
+base::flat_set kAllowedFontFamilies =
+ base::MakeFlatSet(std::vector{
+ "Arial",
+ "Arial Black",
+ "Arial Bold",
+ "Arial Bold Italic",
+ "Arial Italic",
+ "Arial Nova",
+ "Arial Nova Bold",
+ "Arial Nova Bold Italic",
+ "Arial Nova Cond",
+ "Arial Nova Cond Bold",
+ "Arial Nova Cond Bold Italic",
+ "Arial Nova Cond Italic",
+ "Arial Nova Cond Light",
+ "Arial Nova Cond Light Italic",
+ "Arial Nova Italic",
+ "Arial Nova Light",
+ "Arial Nova Light Italic",
+ "Bahnschrift",
+ "Calibri",
+ "Calibri Bold",
+ "Calibri Bold Italic",
+ "Calibri Italic",
+ "Calibri Light",
+ "Calibri Light Italic",
+ "Cambria",
+ "Cambria Bold",
+ "Cambria Bold Italic",
+ "Cambria Italic",
+ "Cambria Math",
+ "Candara",
+ "Candara Bold",
+ "Candara Bold Italic",
+ "Candara Italic",
+ "Candara Light",
+ "Candara Light Italic",
+ "Comic Sans MS",
+ "Comic Sans MS Bold",
+ "Comic Sans MS Bold Italic",
+ "Comic Sans MS Italic",
+ "Consolas",
+ "Consolas Bold",
+ "Consolas Bold Italic",
+ "Consolas Italic",
+ "Constantia",
+ "Constantia Bold",
+ "Constantia Bold Italic",
+ "Constantia Italic",
+ "Corbel",
+ "Corbel Bold",
+ "Corbel Bold Italic",
+ "Corbel Italic",
+ "Corbel Light",
+ "Corbel Light Italic",
+ "Courier New",
+ "Courier New Bold",
+ "Courier New Bold Italic",
+ "Courier New Italic",
+ "Ebrima",
+ "Ebrima Bold",
+ "Franklin Gothic Medium",
+ "Franklin Gothic Medium Italic",
+ "Gabriola",
+ "Gadugi",
+ "Gadugi Bold",
+ "Georgia",
+ "Georgia Bold",
+ "Georgia Bold Italic",
+ "Georgia Italic",
+ "Georgia Pro",
+ "Georgia Pro",
+ "Georgia Pro Black",
+ "Georgia Pro Black Italic",
+ "Georgia Pro Bold",
+ "Georgia Pro Bold Italic",
+ "Georgia Pro Cond",
+ "Georgia Pro Cond Black",
+ "Georgia Pro Cond Black Italic",
+ "Georgia Pro Cond Bold",
+ "Georgia Pro Cond Bold Italic",
+ "Georgia Pro Cond Italic",
+ "Georgia Pro Cond Light",
+ "Georgia Pro Cond Light Italic",
+ "Georgia Pro Cond Semibold",
+ "Georgia Pro Cond Semibold Italic",
+ "Georgia Pro Italic",
+ "Georgia Pro Light",
+ "Georgia Pro Light Italic",
+ "Georgia Pro Semibold",
+ "Georgia Pro Semibold Italic",
+ "Gill Sans Nova",
+ "Gill Sans Nova",
+ "Gill Sans Nova Bold",
+ "Gill Sans Nova Bold Italic",
+ "Gill Sans Nova Cond",
+ "Gill Sans Nova Cond Bold",
+ "Gill Sans Nova Cond Bold Italic",
+ "Gill Sans Nova Cond Italic",
+ "Gill Sans Nova Cond Lt",
+ "Gill Sans Nova Cond Lt Italic",
+ "Gill Sans Nova Cond Ultra Bold",
+ "Gill Sans Nova Cond XBd",
+ "Gill Sans Nova Cond XBd Italic",
+ "Gill Sans Nova Italic",
+ "Gill Sans Nova Light",
+ "Gill Sans Nova Light Italic",
+ "Gill Sans Nova Ultra Bold",
+ "HoloLens MDL2 Assets",
+ "Impact",
+ "Ink Free",
+ "Javanese Text",
+ "Leelawadee UI",
+ "Leelawadee UI Bold",
+ "Leelawadee UI Semilight",
+ "Lucida Console",
+ "Lucida Sans Unicode",
+ "MS Gothic",
+ "MS PGothic",
+ "MS UI Gothic",
+ "MV Boli",
+ "Malgun Gothic",
+ "Malgun Gothic Bold",
+ "Malgun Gothic Semilight",
+ "Marlett",
+ "Microsoft Himalaya",
+ "Microsoft JhengHei",
+ "Microsoft JhengHei Bold",
+ "Microsoft JhengHei Light",
+ "Microsoft JhengHei UI",
+ "Microsoft JhengHei UI Bold",
+ "Microsoft JhengHei UI Light",
+ "Microsoft New Tai Lue",
+ "Microsoft New Tai Lue Bold",
+ "Microsoft PhagsPa",
+ "Microsoft PhagsPa Bold",
+ "Microsoft Sans Serif",
+ "Microsoft Tai Le",
+ "Microsoft Tai Le Bold",
+ "Microsoft YaHei",
+ "Microsoft YaHei Bold",
+ "Microsoft YaHei Light",
+ "Microsoft YaHei UI",
+ "Microsoft YaHei UI Bold",
+ "Microsoft YaHei UI Light",
+ "Microsoft Yi Baiti",
+ "MingLiU-ExtB",
+ "MingLiU_HKSCS-ExtB",
+ "Mongolian Baiti",
+ "Myanmar Text",
+ "Myanmar Text Bold",
+ "NSimSun",
+ "Neue Haas Grotesk Text Pro",
+ "Neue Haas Grotesk Text Pro Black",
+ "Neue Haas Grotesk Text Pro Black Italic",
+ "Neue Haas Grotesk Text Pro Bold",
+ "Neue Haas Grotesk Text Pro Bold Italic",
+ "Neue Haas Grotesk Text Pro ExtraLight",
+ "Neue Haas Grotesk Text Pro ExtraLight Italic",
+ "Neue Haas Grotesk Text Pro Light",
+ "Neue Haas Grotesk Text Pro Light Italic",
+ "Neue Haas Grotesk Text Pro Medium",
+ "Neue Haas Grotesk Text Pro Medium Italic",
+ "Neue Haas Grotesk Text Pro Regular",
+ "Neue Haas Grotesk Text Pro Regular Italic",
+ "Neue Haas Grotesk Text Pro Thin",
+ "Neue Haas Grotesk Text Pro Thin Italic",
+ "Neue Haas Grotesk Text Pro UltraThin",
+ "Neue Haas Grotesk Text Pro UltraThin Italic",
+ "Nirmala UI",
+ "Nirmala UI Bold",
+ "Nirmala UI Semilight",
+ "PMingLiU-ExtB",
+ "Palatino Linotype",
+ "Palatino Linotype Bold",
+ "Palatino Linotype Bold Italic",
+ "Palatino Linotype Italic",
+ "Rockwell Nova",
+ "Rockwell Nova Bold",
+ "Rockwell Nova Bold Italic",
+ "Rockwell Nova Cond",
+ "Rockwell Nova Cond Bold",
+ "Rockwell Nova Cond Bold Italic",
+ "Rockwell Nova Cond Italic",
+ "Rockwell Nova Cond Light",
+ "Rockwell Nova Cond Light Italic",
+ "Rockwell Nova Extra Bold",
+ "Rockwell Nova Extra Bold Italic",
+ "Rockwell Nova Italic",
+ "Rockwell Nova Light",
+ "Rockwell Nova Light Italic",
+ "Segoe Fluent Icons",
+ "Segoe MDL2 Assets",
+ "Segoe Print",
+ "Segoe Print Bold",
+ "Segoe Script",
+ "Segoe Script Bold",
+ "Segoe UI",
+ "Segoe UI",
+ "Segoe UI Black",
+ "Segoe UI Black Italic",
+ "Segoe UI Bold",
+ "Segoe UI Bold Italic",
+ "Segoe UI Emoji",
+ "Segoe UI Historic",
+ "Segoe UI Italic",
+ "Segoe UI Light",
+ "Segoe UI Light Italic",
+ "Segoe UI Semibold",
+ "Segoe UI Semibold Italic",
+ "Segoe UI Semilight",
+ "Segoe UI Semilight Italic",
+ "Segoe UI Symbol",
+ "Segoe UI Variable",
+ "Segoe UI Variable Display Bold",
+ "Segoe UI Variable Display Light",
+ "Segoe UI Variable Display Regular",
+ "Segoe UI Variable Display Semibold",
+ "Segoe UI Variable Display Semilight",
+ "Segoe UI Variable Small Bold",
+ "Segoe UI Variable Small Light",
+ "Segoe UI Variable Small Regular",
+ "Segoe UI Variable Small Semibold",
+ "Segoe UI Variable Small Semilight",
+ "Segoe UI Variable Text Bold",
+ "Segoe UI Variable Text Light",
+ "Segoe UI Variable Text Regular",
+ "Segoe UI Variable Text Semibold",
+ "Segoe UI Variable Text Semilight",
+ "SimSun",
+ "SimSun-ExtB",
+ "Sitka",
+ "Sitka Banner",
+ "Sitka Banner Bold",
+ "Sitka Banner Bold Italic",
+ "Sitka Banner Italic",
+ "Sitka Banner Semibold",
+ "Sitka Banner Semibold Italic",
+ "Sitka Display",
+ "Sitka Display Bold",
+ "Sitka Display Bold Italic",
+ "Sitka Display Italic",
+ "Sitka Display Semibold",
+ "Sitka Display Semibold Italic",
+ "Sitka Heading",
+ "Sitka Heading Bold",
+ "Sitka Heading Bold Italic",
+ "Sitka Heading Italic",
+ "Sitka Heading Semibold",
+ "Sitka Heading Semibold Italic",
+ "Sitka Small",
+ "Sitka Small Bold",
+ "Sitka Small Bold Italic",
+ "Sitka Small Italic",
+ "Sitka Small Semibold",
+ "Sitka Small Semibold Italic",
+ "Sitka Subheading",
+ "Sitka Subheading Bold",
+ "Sitka Subheading Bold Italic",
+ "Sitka Subheading Italic",
+ "Sitka Subheading Semibold",
+ "Sitka Subheading Semibold Italic",
+ "Sitka Text",
+ "Sitka Text Bold",
+ "Sitka Text Bold Italic",
+ "Sitka Text Italic",
+ "Sitka Text Semibold",
+ "Sitka Text Semibold Italic",
+ "Sylfaen",
+ "Symbol",
+ "Tahoma",
+ "Tahoma Bold",
+ "Times New Roman",
+ "Times New Roman Bold",
+ "Times New Roman Bold Italic",
+ "Times New Roman Italic",
+ "Trebuchet MS",
+ "Trebuchet MS Bold",
+ "Trebuchet MS Bold Italic",
+ "Trebuchet MS Italic",
+ "Verdana",
+ "Verdana Bold",
+ "Verdana Bold Italic",
+ "Verdana Italic",
+ "Verdana Pro",
+ "Verdana Pro",
+ "Verdana Pro Black",
+ "Verdana Pro Black Italic",
+ "Verdana Pro Bold",
+ "Verdana Pro Bold Italic",
+ "Verdana Pro Cond",
+ "Verdana Pro Cond Black",
+ "Verdana Pro Cond Black Italic",
+ "Verdana Pro Cond Bold",
+ "Verdana Pro Cond Bold Italic",
+ "Verdana Pro Cond Italic",
+ "Verdana Pro Cond Light",
+ "Verdana Pro Cond Light Italic",
+ "Verdana Pro Cond SemiBold",
+ "Verdana Pro Cond SemiBold Italic",
+ "Verdana Pro Italic",
+ "Verdana Pro Light",
+ "Verdana Pro Light Italic",
+ "Verdana Pro SemiBold",
+ "Verdana Pro SemiBold Italic",
+ "Webdings",
+ "Wingdings",
+ "Yu Gothic",
+ "Yu Gothic Bold",
+ "Yu Gothic Light",
+ "Yu Gothic Medium",
+ "Yu Gothic Regular",
+ "Yu Gothic UI Bold",
+ "Yu Gothic UI Light",
+ "Yu Gothic UI Regular",
+ "Yu Gothic UI Semibold",
+ "Yu Gothic UI Semilight"});
+base::flat_set kAdditionalAllowedFontFamiliesAR =
+ base::MakeFlatSet(std::vector{
+ "Aldhabi", "Andalus", "Arabic Typesetting", "Microsoft Uighur",
+ "Microsoft Uighur Bold", "Sakkal Majalla", "Sakkal Majalla Bold",
+ "Simplified Arabic", "Simplified Arabic Bold",
+ "Simplified Arabic Fixed", "Traditional Arabic",
+ "Traditional Arabic Bold", "Urdu Typesetting",
+ "Urdu Typesetting Bold"});
+base::flat_set kAdditionalAllowedFontFamiliesAS =
+ base::MakeFlatSet(std::vector{
+ "Shonar Bangla", "Shonar Bangla Bold", "Vrinda", "Vrinda Bold"});
+base::flat_set kAdditionalAllowedFontFamiliesIU =
+ base::MakeFlatSet(
+ std::vector{"Euphemia"});
+base::flat_set kAdditionalAllowedFontFamiliesHI =
+ base::MakeFlatSet(std::vector{
+ "Aparajita", "Aparajita Italic", "Aparajita Bold",
+ "Aparajita Bold Italic", "Kokila", "Kokila Italic", "Kokila Bold",
+ "Kokila Bold Italic", "Mangal", "Mangal Bold", "Sanskrit Text",
+ "Utsaah", "Utsaah Italic", "Utsaah Bold", "Utsaah Bold Italic"});
+base::flat_set kAdditionalAllowedFontFamiliesAM =
+ base::MakeFlatSet(
+ std::vector{"Nyala"});
+base::flat_set kAdditionalAllowedFontFamiliesGU =
+ base::MakeFlatSet(
+ std::vector{"Shruti", "Shruti Bold"});
+base::flat_set kAdditionalAllowedFontFamiliesPA =
+ base::MakeFlatSet(
+ std::vector{"Raavi", "Raavi Bold"});
+base::flat_set kAdditionalAllowedFontFamiliesZH =
+ base::MakeFlatSet(std::vector{
+ "DengXian Light", "DengXian", "DengXian Bold", "FangSong", "KaiTi",
+ "SimHei", "DFKai-SB", "MingLiU", "MingLiU_HKSCS", "PMingLiU"});
+base::flat_set kAdditionalAllowedFontFamiliesHE =
+ base::MakeFlatSet(std::vector{
+ "Aharoni Bold", "David", "David Bold", "FrankRuehl", "Gisha",
+ "Gisha Bold", "Levenim MT", "Levenim MT Bold", "Miriam", "Miriam Fixed",
+ "Narkisim", "Rod"});
+base::flat_set kAdditionalAllowedFontFamiliesJA =
+ base::MakeFlatSet(
+ std::vector{"BIZ UDGothic",
+ "BIZ UDGothic Bold",
+ "BIZ UDPGothic",
+ "BIZ UDPGothic Bold",
+ "BIZ UDMincho Medium",
+ "BIZ UDPMincho Medium",
+ "Meiryo",
+ "Meiryo Italic",
+ "Meiryo Bold",
+ "Meiryo Bold Italic",
+ "Meiryo UI",
+ "Meiryo UI Italic",
+ "Meiryo UI Bold",
+ "Meiryo UI Bold Italic",
+ "MS Mincho",
+ "MS PMincho",
+ "UD Digi Kyokasho",
+ "UD Digi Kyokasho N-B",
+ "UD Digi Kyokasho NK-B",
+ "UD Digi Kyokasho NK-R",
+ "UD Digi Kyokasho NP-B",
+ "UD Digi Kyokasho NP-R",
+ "UD Digi Kyokasho N-R",
+ "Yu Mincho Light",
+ "Yu Mincho Regular",
+ "Yu Mincho Demibold"});
+base::flat_set kAdditionalAllowedFontFamiliesKN =
+ base::MakeFlatSet(
+ std::vector{"Tunga", "Tunga Bold"});
+base::flat_set kAdditionalAllowedFontFamiliesKM =
+ base::MakeFlatSet(std::vector{
+ "DaunPenh", "Khmer UI", "Khmer UI Bold", "MoolBoran"});
+base::flat_set kAdditionalAllowedFontFamiliesKO =
+ base::MakeFlatSet(std::vector{
+ "Batang", "BatangChe", "Dotum", "DotumChe", "Gulim", "GulimChe",
+ "Gungsuh", "GungsuhChe"});
+base::flat_set kAdditionalAllowedFontFamiliesLO =
+ base::MakeFlatSet(
+ std::vector{"DokChampa", "Lao UI", "Lao UI Bold"});
+base::flat_set kAdditionalAllowedFontFamiliesML =
+ base::MakeFlatSet(
+ std::vector{"Kartika", "Kartika Bold"});
+#endif
+} // namespace
+
+bool CanRestrictFontFamiliesOnThisPlatform() {
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+ return true;
+#else
+ return false;
+#endif
+}
+
+const base::flat_set& GetAllowedFontFamilies() {
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+ return kAllowedFontFamilies;
+#else
+ return kEmptyFontSet;
+#endif
+}
+
+const base::flat_set&
+GetAdditionalAllowedFontFamiliesByLocale(WTF::String locale_language) {
+#if BUILDFLAG(IS_WIN)
+ if (locale_language == "ar" || locale_language == "fa" ||
+ locale_language == "ur")
+ return kAdditionalAllowedFontFamiliesAR;
+ if (locale_language == "as")
+ return kAdditionalAllowedFontFamiliesAS;
+ if (locale_language == "iu")
+ return kAdditionalAllowedFontFamiliesIU;
+ if (locale_language == "hi" || locale_language == "mr")
+ return kAdditionalAllowedFontFamiliesHI;
+ if (locale_language == "am" || locale_language == "ti")
+ return kAdditionalAllowedFontFamiliesAM;
+ if (locale_language == "gu")
+ return kAdditionalAllowedFontFamiliesGU;
+ if (locale_language == "pa")
+ return kAdditionalAllowedFontFamiliesPA;
+ if (locale_language == "zh")
+ return kAdditionalAllowedFontFamiliesZH;
+ if (locale_language == "he")
+ return kAdditionalAllowedFontFamiliesHE;
+ if (locale_language == "ja")
+ return kAdditionalAllowedFontFamiliesJA;
+ if (locale_language == "kn")
+ return kAdditionalAllowedFontFamiliesKN;
+ if (locale_language == "km")
+ return kAdditionalAllowedFontFamiliesKM;
+ if (locale_language == "ko")
+ return kAdditionalAllowedFontFamiliesKO;
+ if (locale_language == "lo")
+ return kAdditionalAllowedFontFamiliesLO;
+ if (locale_language == "ml")
+ return kAdditionalAllowedFontFamiliesML;
+#endif
+ return kEmptyFontSet;
+}
+
+} // namespace brave
diff --git a/third_party/blink/renderer/brave_font_whitelist.h b/third_party/blink/renderer/brave_font_whitelist.h
new file mode 100644
index 000000000000..db9097851204
--- /dev/null
+++ b/third_party/blink/renderer/brave_font_whitelist.h
@@ -0,0 +1,26 @@
+/* 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/. */
+
+#ifndef BRAVE_THIRD_PARTY_BLINK_RENDERER_BRAVE_FONT_WHITELIST_H_
+#define BRAVE_THIRD_PARTY_BLINK_RENDERER_BRAVE_FONT_WHITELIST_H_
+
+#include
+
+#include "base/containers/flat_set.h"
+#include "base/strings/string_piece.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace brave {
+
+bool CanRestrictFontFamiliesOnThisPlatform();
+const base::flat_set& GetAllowedFontFamilies();
+
+// This takes a 2-character language code.
+const base::flat_set&
+GetAdditionalAllowedFontFamiliesByLocale(WTF::String locale_language);
+
+} // namespace brave
+
+#endif // BRAVE_THIRD_PARTY_BLINK_RENDERER_BRAVE_FONT_WHITELIST_H_