Add profile-awareness to realtime URL lookups The BrowserURLLoaderThrottle now checks the current BrowserContext to determine whether real-time checks are enabled at all, then passes that information to the SafeBrowsingUrlCheckerImpl. Bug: 991394, 963165, 1001566 Change-Id: I5dbff848a4ea5a6ae3ac5c76e5d5624596ee3616 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1825482 Reviewed-by: Maksim Ivanov <emaxx@chromium.org> Reviewed-by: Varun Khaneja <vakh@chromium.org> Reviewed-by: Mihai Sardarescu <msarda@chromium.org> Reviewed-by: Dominic Battré <battre@chromium.org> Commit-Queue: Daniel Rubery <drubery@chromium.org> Cr-Commit-Position: refs/heads/master@{#702956}
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 8d173c4..f531072 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -5709,17 +5709,21 @@ IN_PROC_BROWSER_TEST_F(PolicyTest, CheckURLsInRealTime) { base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - safe_browsing::kRealTimeUrlLookupFetchAllowlist); + scoped_feature_list.InitWithFeatures( + {safe_browsing::kRealTimeUrlLookupEnabled, + safe_browsing::kRealTimeUrlLookupFetchAllowlist}, + {}); - EXPECT_FALSE(safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup()); + EXPECT_FALSE(safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup( + browser()->profile())); PolicyMap policies; SetPolicy(&policies, key::kSafeBrowsingRealTimeLookupEnabled, std::make_unique<base::Value>(true)); UpdateProviderPolicy(policies); - EXPECT_TRUE(safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup()); + EXPECT_TRUE(safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup( + browser()->profile())); } class HSTSPolicyTest : public PolicyTest {
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 97f8b33..5ee096c9 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -409,7 +409,6 @@ // Check if any profile requires the service to be active. enabled_by_prefs_ = false; estimated_extended_reporting_by_prefs_ = SBER_LEVEL_OFF; - bool is_real_time_lookup_enabled = false; for (const auto& pref : prefs_map_) { if (pref.first->GetBoolean(prefs::kSafeBrowsingEnabled)) { enabled_by_prefs_ = true; @@ -419,17 +418,9 @@ if (erl != SBER_LEVEL_OFF) { estimated_extended_reporting_by_prefs_ = erl; } - - if (pref.first->GetBoolean(prefs::kSafeBrowsingRealTimeLookupEnabled)) { - is_real_time_lookup_enabled = true; - } } } - // TODO(crbug.com/991394): This enables real-time URL lookup if it is enabled - // for any of the active profiles. This should be fixed. - RealTimePolicyEngine::SetEnabled(is_real_time_lookup_enabled); - if (enabled_by_prefs_) Start(); else
diff --git a/components/safe_browsing/DEPS b/components/safe_browsing/DEPS index 74f5a3b..b4a0ba6 100644 --- a/components/safe_browsing/DEPS +++ b/components/safe_browsing/DEPS
@@ -2,11 +2,13 @@ "+components/content_settings/core/browser", "+components/history/core/browser", "+components/password_manager/core/browser/password_manager_metrics_util.h", + "+components/prefs", "+components/security_interstitials/content", "+components/security_interstitials/core", "+components/sync/protocol", "+components/sync_preferences/testing_pref_service_syncable.h", - "+components/prefs", + "+components/unified_consent", + "+components/user_prefs/user_prefs.h", "+content/public/browser", "+content/public/common", "+content/public/test",
diff --git a/components/safe_browsing/browser/browser_url_loader_throttle.cc b/components/safe_browsing/browser/browser_url_loader_throttle.cc index a8ff5a4..25ebf3c2 100644 --- a/components/safe_browsing/browser/browser_url_loader_throttle.cc +++ b/components/safe_browsing/browser/browser_url_loader_throttle.cc
@@ -11,7 +11,9 @@ #include "components/safe_browsing/browser/url_checker_delegate.h" #include "components/safe_browsing/common/safebrowsing_constants.h" #include "components/safe_browsing/common/utils.h" +#include "components/safe_browsing/realtime/policy_engine.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/web_contents.h" #include "net/log/net_log_event_type.h" #include "net/url_request/redirect_info.h" #include "services/network/public/cpp/resource_request.h" @@ -29,12 +31,14 @@ content::ResourceContext* resource_context, int frame_tree_node_id, base::RepeatingCallback<content::WebContents*()> web_contents_getter, - base::WeakPtr<BrowserURLLoaderThrottle> throttle) + base::WeakPtr<BrowserURLLoaderThrottle> throttle, + bool real_time_lookup_enabled) : delegate_getter_(std::move(delegate_getter)), resource_context_(resource_context), frame_tree_node_id_(frame_tree_node_id), web_contents_getter_(web_contents_getter), - throttle_(std::move(throttle)) {} + throttle_(std::move(throttle)), + real_time_lookup_enabled_(real_time_lookup_enabled) {} // Starts the initial safe browsing check. This check and future checks may be // skipped after checking with the UrlCheckerDelegate. @@ -63,7 +67,7 @@ url_checker_ = std::make_unique<SafeBrowsingUrlCheckerImpl>( headers, load_flags, resource_type, has_user_gesture, - url_checker_delegate, web_contents_getter_); + url_checker_delegate, web_contents_getter_, real_time_lookup_enabled_); CheckUrl(url, method); } @@ -130,6 +134,7 @@ base::RepeatingCallback<content::WebContents*()> web_contents_getter_; bool skip_checks_ = false; base::WeakPtr<BrowserURLLoaderThrottle> throttle_; + bool real_time_lookup_enabled_ = false; }; // static @@ -150,9 +155,18 @@ int frame_tree_node_id, content::ResourceContext* resource_context) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // Decide whether to do real time URL lookups or not. + content::WebContents* web_contents = web_contents_getter.Run(); + bool real_time_lookup_enabled = + web_contents ? RealTimePolicyEngine::CanPerformFullURLLookup( + web_contents->GetBrowserContext()) + : false; + io_checker_ = std::make_unique<CheckerOnIO>( std::move(delegate_getter), resource_context, frame_tree_node_id, - web_contents_getter, weak_factory_.GetWeakPtr()); + web_contents_getter, weak_factory_.GetWeakPtr(), + real_time_lookup_enabled); } BrowserURLLoaderThrottle::~BrowserURLLoaderThrottle() {
diff --git a/components/safe_browsing/browser/mojo_safe_browsing_impl.cc b/components/safe_browsing/browser/mojo_safe_browsing_impl.cc index b28aca9..a72fe9cae 100644 --- a/components/safe_browsing/browser/mojo_safe_browsing_impl.cc +++ b/components/safe_browsing/browser/mojo_safe_browsing_impl.cc
@@ -147,11 +147,16 @@ return; } + // This is not called for frame resources, and real time URL checks currently + // only support frame resources. If we extend real time URL checks to support + // non-main frames, we will need to provide the user preferences regarding + // real time lookup here. auto checker_impl = std::make_unique<SafeBrowsingUrlCheckerImpl>( headers, static_cast<int>(load_flags), resource_type, has_user_gesture, delegate_, base::Bind(&GetWebContentsFromID, render_process_id_, - static_cast<int>(render_frame_id))); + static_cast<int>(render_frame_id)), + /*real_time_lookup_enabled=*/false); checker_impl->CheckUrl( url, method,
diff --git a/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc index d48f8c2..da22ca6b 100644 --- a/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc
@@ -99,14 +99,16 @@ content::ResourceType resource_type, bool has_user_gesture, scoped_refptr<UrlCheckerDelegate> url_checker_delegate, - const base::Callback<content::WebContents*()>& web_contents_getter) + const base::Callback<content::WebContents*()>& web_contents_getter, + bool real_time_lookup_enabled) : headers_(headers), load_flags_(load_flags), resource_type_(resource_type), has_user_gesture_(has_user_gesture), web_contents_getter_(web_contents_getter), url_checker_delegate_(std::move(url_checker_delegate)), - database_manager_(url_checker_delegate_->GetDatabaseManager()) {} + database_manager_(url_checker_delegate_->GetDatabaseManager()), + real_time_lookup_enabled_(real_time_lookup_enabled) {} SafeBrowsingUrlCheckerImpl::~SafeBrowsingUrlCheckerImpl() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -293,7 +295,8 @@ bool safe_synchronously; auto* rt_lookup_service = database_manager_->GetRealTimeUrlLookupService(); - if (RealTimePolicyEngine::CanPerformFullURLLookupForResourceType( + if (real_time_lookup_enabled_ && + RealTimePolicyEngine::CanPerformFullURLLookupForResourceType( resource_type_) && rt_lookup_service && rt_lookup_service->CanCheckUrl(url) && !rt_lookup_service->IsInBackoffMode()) {
diff --git a/components/safe_browsing/browser/safe_browsing_url_checker_impl.h b/components/safe_browsing/browser/safe_browsing_url_checker_impl.h index 6a3e8e9..24299da 100644 --- a/components/safe_browsing/browser/safe_browsing_url_checker_impl.h +++ b/components/safe_browsing/browser/safe_browsing_url_checker_impl.h
@@ -58,13 +58,18 @@ bool /* proceed */, bool /* showed_interstitial */)>; + // Constructor for SafeBrowsingUrlCheckerImpl. |real_time_lookup_enabled| + // indicates whether or not the profile has enabled real time URL lookups, as + // computed by the RealTimePolicyEngine. This must be computed in advance, + // since this class only exists on the IO thread. SafeBrowsingUrlCheckerImpl( const net::HttpRequestHeaders& headers, int load_flags, content::ResourceType resource_type, bool has_user_gesture, scoped_refptr<UrlCheckerDelegate> url_checker_delegate, - const base::Callback<content::WebContents*()>& web_contents_getter); + const base::Callback<content::WebContents*()>& web_contents_getter, + bool real_time_lookup_enabled); ~SafeBrowsingUrlCheckerImpl() override; @@ -181,6 +186,9 @@ // Timer to abort the SafeBrowsing check if it takes too long. base::OneShotTimer timer_; + // Whether real time lookup is enabled for this request. + bool real_time_lookup_enabled_; + base::WeakPtrFactory<SafeBrowsingUrlCheckerImpl> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(SafeBrowsingUrlCheckerImpl);
diff --git a/components/safe_browsing/realtime/BUILD.gn b/components/safe_browsing/realtime/BUILD.gn index 2d90ba3..6d2426681d 100644 --- a/components/safe_browsing/realtime/BUILD.gn +++ b/components/safe_browsing/realtime/BUILD.gn
@@ -14,6 +14,9 @@ "//components/safe_browsing:features", "//components/safe_browsing:realtimeapi_proto", "//components/safe_browsing/common:safe_browsing_prefs", + "//components/unified_consent", + "//components/user_prefs", + "//content/public/browser", "//content/public/common:resource_type_header", ] } @@ -45,6 +48,10 @@ ":url_lookup_service", "//base/test:test_support", "//components/safe_browsing:features", + "//components/safe_browsing/common:safe_browsing_prefs", + "//components/sync_preferences:test_support", + "//components/unified_consent", + "//components/user_prefs", "//content/test:test_support", "//services/network:test_support", "//services/network/public/cpp:cpp",
diff --git a/components/safe_browsing/realtime/policy_engine.cc b/components/safe_browsing/realtime/policy_engine.cc index be10a363..fdf23e9 100644 --- a/components/safe_browsing/realtime/policy_engine.cc +++ b/components/safe_browsing/realtime/policy_engine.cc
@@ -9,11 +9,12 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/features.h" +#include "components/unified_consent/pref_names.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/browser_context.h" namespace safe_browsing { -bool RealTimePolicyEngine::is_enabled_by_pref_ = false; - // static bool RealTimePolicyEngine::IsFetchAllowlistEnabled() { return base::FeatureList::IsEnabled(kRealTimeUrlLookupFetchAllowlist); @@ -25,39 +26,38 @@ } // static -bool RealTimePolicyEngine::IsUserOptedIn() { - // TODO(crbug.com/991394): Implement this soon. For now, disabled. - return false; +bool RealTimePolicyEngine::IsUserOptedIn( + content::BrowserContext* browser_context) { + PrefService* pref_service = user_prefs::UserPrefs::Get(browser_context); + return pref_service->GetBoolean( + unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled); } // static -bool RealTimePolicyEngine::CanPerformFullURLLookup() { - // TODO(crbug.com/991394): This should take into account whether the user is - // eligible for this service (see "Target Users" in the design doc). +bool RealTimePolicyEngine::IsEnabledByPolicy( + content::BrowserContext* browser_context) { + PrefService* pref_service = user_prefs::UserPrefs::Get(browser_context); + return pref_service->GetBoolean(prefs::kSafeBrowsingRealTimeLookupEnabled); +} +// static +bool RealTimePolicyEngine::CanPerformFullURLLookup( + content::BrowserContext* browser_context) { if (!IsFetchAllowlistEnabled()) return false; - if (is_enabled_by_pref()) + if (IsEnabledByPolicy(browser_context)) return true; - return IsUrlLookupEnabled() && IsUserOptedIn(); + return IsUrlLookupEnabled() && IsUserOptedIn(browser_context); } // static bool RealTimePolicyEngine::CanPerformFullURLLookupForResourceType( content::ResourceType resource_type) { - if (!CanPerformFullURLLookup()) - return false; - UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.RT.ResourceTypes.Requested", resource_type); return resource_type == content::ResourceType::kMainFrame; } -// static -void RealTimePolicyEngine::SetEnabled(bool is_enabled) { - is_enabled_by_pref_ = is_enabled; -} - } // namespace safe_browsing
diff --git a/components/safe_browsing/realtime/policy_engine.h b/components/safe_browsing/realtime/policy_engine.h index 4316412..eabfa31 100644 --- a/components/safe_browsing/realtime/policy_engine.h +++ b/components/safe_browsing/realtime/policy_engine.h
@@ -7,6 +7,10 @@ #include "content/public/common/resource_type.h" +namespace content { +class BrowserContext; +} + namespace safe_browsing { // This class implements the logic to decide whether the real time lookup @@ -19,16 +23,15 @@ // Is the feature to sync high confidence allowlist enabled? static bool IsFetchAllowlistEnabled(); - // Return true if the feature to enable full URL lookups is enabled and the - // allowlist fetch is enabled, |resource_type| is kMainFrame. + // Return true if full URL lookups are enabled for |resource_type|. static bool CanPerformFullURLLookupForResourceType( content::ResourceType resource_type); // Return true if the feature to enable full URL lookups is enabled and the - // allowlist fetch is enabled. - static bool CanPerformFullURLLookup(); + // allowlist fetch is enabled for the profile represented by + // |browser_context|. + static bool CanPerformFullURLLookup(content::BrowserContext* browser_context); - static bool is_enabled_by_pref() { return is_enabled_by_pref_; } friend class SafeBrowsingService; private: @@ -36,13 +39,10 @@ static bool IsUrlLookupEnabled(); // Is user opted-in to the feature? - static bool IsUserOptedIn(); + static bool IsUserOptedIn(content::BrowserContext* browser_context); - // TODO(crbug.com/991394): This is a temporary way of checking whether the - // real-time lookup is enabled for any active profile. This must be fixed - // before full launch. - static bool is_enabled_by_pref_; - static void SetEnabled(bool is_enabled); + // Is the feature enabled due to enterprise policy? + static bool IsEnabledByPolicy(content::BrowserContext* browser_context); friend class RealTimePolicyEngineTest; }; // class RealTimePolicyEngine
diff --git a/components/safe_browsing/realtime/policy_engine_unittest.cc b/components/safe_browsing/realtime/policy_engine_unittest.cc index 55a0329ac..d5325a6 100644 --- a/components/safe_browsing/realtime/policy_engine_unittest.cc +++ b/components/safe_browsing/realtime/policy_engine_unittest.cc
@@ -5,54 +5,78 @@ #include "components/safe_browsing/realtime/policy_engine.h" #include "base/test/scoped_feature_list.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/features.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/unified_consent/pref_names.h" +#include "components/unified_consent/unified_consent_service.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_browser_context.h" #include "testing/platform_test.h" namespace safe_browsing { class RealTimePolicyEngineTest : public PlatformTest { public: - void ForceSetRealTimeLookupPolicy(bool is_enabled) { - RealTimePolicyEngine::SetEnabled(is_enabled); + void SetUp() override { + user_prefs::UserPrefs::Set(&test_context_, &pref_service_); + RegisterProfilePrefs(pref_service_.registry()); + unified_consent::UnifiedConsentService::RegisterPrefs( + pref_service_.registry()); } - bool IsUserOptedIn() { return RealTimePolicyEngine::IsUserOptedIn(); } + bool IsUserOptedIn() { + return RealTimePolicyEngine::IsUserOptedIn(&test_context_); + } + + bool CanPerformFullURLLookup() { + return RealTimePolicyEngine::CanPerformFullURLLookup(&test_context_); + } + + content::BrowserTaskEnvironment task_environment_; + content::TestBrowserContext test_context_; + sync_preferences::TestingPrefServiceSyncable pref_service_; }; TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_DisabledFetchAllowlist) { base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature(kRealTimeUrlLookupFetchAllowlist); - EXPECT_FALSE(RealTimePolicyEngine::CanPerformFullURLLookup()); + EXPECT_FALSE(CanPerformFullURLLookup()); } TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_EnabledByPolicy) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(kRealTimeUrlLookupFetchAllowlist); - ForceSetRealTimeLookupPolicy(/* is_enabled= */ true); - ASSERT_TRUE(RealTimePolicyEngine::is_enabled_by_pref()); - EXPECT_TRUE(RealTimePolicyEngine::CanPerformFullURLLookup()); + pref_service_.SetUserPref(prefs::kSafeBrowsingRealTimeLookupEnabled, + std::make_unique<base::Value>(true)); + EXPECT_TRUE(CanPerformFullURLLookup()); } TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_DisabledUrlLookup) { base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature(kRealTimeUrlLookupEnabled); - EXPECT_FALSE(RealTimePolicyEngine::CanPerformFullURLLookup()); + EXPECT_FALSE(CanPerformFullURLLookup()); } TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_DisabledUserOptin) { - // This is hardcoded as false for now so ensure that. ASSERT_FALSE(IsUserOptedIn()); } +TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_EnabledUserOptin) { + pref_service_.SetUserPref( + unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, + std::make_unique<base::Value>(true)); + ASSERT_TRUE(IsUserOptedIn()); +} + TEST_F(RealTimePolicyEngineTest, TestCanPerformFullURLLookup_EnabledMainFrameOnly) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(kRealTimeUrlLookupFetchAllowlist); - ForceSetRealTimeLookupPolicy(/* is_enabled= */ true); - ASSERT_TRUE(RealTimePolicyEngine::is_enabled_by_pref()); for (int i = 0; i <= static_cast<int>(content::ResourceType::kMaxValue); i++) {