From f6dddf29d83c4e40cb3c53670aebb551783f0e23 Mon Sep 17 00:00:00 2001 From: Mark Pilgrim <43750833+pilgrim-brave@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:41:44 -0400 Subject: [PATCH] Implement "reduce language fingerprinting" (#12234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement navigator.languages farbling * add support for HTTP headers * add support for farbling HTTP header * add reduce language preference toggle in settings * Implement font whitelist * add sublabel to reduce-lang preference toggle * rebase patches * use anonymous namespace * also add our AllowFontFamily method to TestFontSelector to avoid compile errors * farble all non-whitelisted fonts without enumeration * rename to MakePseudoRandomGeneratorForURL * move session token management to singleton service * move font whitelist to .cc file * move prefs constants and code around * pref names browsertest fix * reduce patches (really) * add web worker and service worker tests * get URL differently, move DCHECK * propogate reduce-language pref to renderers * consolidate feature detection, add some comments * lint * gn_check * gn_check * refactor default locale lookup * lint * default session key to 12345 if command line switch is missing https://github.com/brave/brave-browser/issues/22021 * change 12345 -> 23456 so it doesn’t match the test default Co-authored-by: bridiver --- app/brave_generated_resources.grd | 10 +- browser/about_flags.cc | 9 + browser/brave_browser_process.h | 2 + browser/brave_browser_process_impl.cc | 9 + browser/brave_browser_process_impl.h | 4 + browser/brave_content_browser_client.cc | 22 +- browser/brave_content_browser_client.h | 3 - browser/brave_prefs_browsertest.cc | 2 + browser/brave_profile_prefs.cc | 3 + .../brave_shields_web_contents_observer.cc | 18 + .../reduce_language_navigation_throttle.cc | 115 +++ .../reduce_language_navigation_throttle.h | 60 ++ browser/brave_shields/sources.gni | 2 + .../api/settings_private/brave_prefs_util.cc | 2 + browser/farbling/BUILD.gn | 1 + ...avigator_languages_farbling_browsertest.cc | 265 ++++++ .../default_brave_shields_page.html | 6 + .../settings_localized_strings_provider.cc | 3 + .../platform/web_content_settings_client.h | 1 + .../blink/renderer/core/core_initializer.cc | 13 + .../execution_context/execution_context.cc | 68 +- .../execution_context/execution_context.h | 10 +- .../renderer/core/frame/navigator_language.cc | 41 + .../renderer/core/frame/navigator_language.h | 33 + .../platform/fonts/font_fallback_list.cc | 40 + .../platform/fonts/font_fallback_list.h | 29 + components/brave_shields/browser/BUILD.gn | 3 + .../browser/brave_farbling_service.cc | 64 ++ .../browser/brave_farbling_service.h | 40 + .../browser/brave_shields_util.cc | 33 + .../browser/brave_shields_util.h | 6 + .../brave_shields/common/brave_shields.mojom | 4 + components/brave_shields/common/features.cc | 3 + components/brave_shields/common/features.h | 1 + components/brave_shields/common/pref_names.cc | 1 + components/brave_shields/common/pref_names.h | 1 + .../brave_content_settings_agent_impl.cc | 8 + .../brave_content_settings_agent_impl.h | 6 + ...platform-fonts-font_fallback_list.cc.patch | 12 + test/base/testing_brave_browser_process.cc | 6 + test/base/testing_brave_browser_process.h | 1 + .../navigator/service-workers-languages.html | 25 + .../navigator/service-workers-languages.js | 11 + test/data/navigator/workers-languages.html | 28 + third_party/blink/renderer/BUILD.gn | 6 +- third_party/blink/renderer/DEPS | 3 + .../blink/renderer/brave_font_whitelist.cc | 752 ++++++++++++++++++ .../blink/renderer/brave_font_whitelist.h | 26 + 48 files changed, 1789 insertions(+), 22 deletions(-) create mode 100644 browser/brave_shields/reduce_language_navigation_throttle.cc create mode 100644 browser/brave_shields/reduce_language_navigation_throttle.h create mode 100644 browser/farbling/brave_navigator_languages_farbling_browsertest.cc create mode 100644 chromium_src/third_party/blink/renderer/core/core_initializer.cc create mode 100644 chromium_src/third_party/blink/renderer/core/frame/navigator_language.cc create mode 100644 chromium_src/third_party/blink/renderer/core/frame/navigator_language.h create mode 100644 chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.cc create mode 100644 chromium_src/third_party/blink/renderer/platform/fonts/font_fallback_list.h create mode 100644 components/brave_shields/browser/brave_farbling_service.cc create mode 100644 components/brave_shields/browser/brave_farbling_service.h create mode 100644 patches/third_party-blink-renderer-platform-fonts-font_fallback_list.cc.patch create mode 100644 test/data/navigator/service-workers-languages.html create mode 100644 test/data/navigator/service-workers-languages.js create mode 100644 test/data/navigator/workers-languages.html create mode 100644 third_party/blink/renderer/DEPS create mode 100644 third_party/blink/renderer/brave_font_whitelist.cc create mode 100644 third_party/blink/renderer/brave_font_whitelist.h 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_