Commit 425f8559 authored by David Dorwin's avatar David Dorwin Committed by Commit Bot

Extract Safe Sites from blocklist policy

Although PolicyBlocklistNavigationThrottle uses Safe Sites, blocklists
and Safe Sites are conceptually different. Also, Safe Sites does not
require Prefs, which makes it easier to use outside //chrome.

Also extract SafeSearchService from PolicyBlocklistService.

Bug: 1147231
Change-Id: I4e2714478177bebcf26a07ed0e6230aa67e0792f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2530145
Auto-Submit: David Dorwin <ddorwin@chromium.org>
Reviewed-by: default avatarOwen Min <zmin@chromium.org>
Reviewed-by: default avatarNicolas Ouellet-Payeur <nicolaso@chromium.org>
Commit-Queue: David Dorwin <ddorwin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826798}
parent 1589e87b
......@@ -6,6 +6,25 @@ import("//build/config/features.gni")
assert(!is_ios, "Policy Throttle should not be referenced on iOS")
source_set("safe_sites_navigation_throttle") {
sources = [
"safe_search_service.cc",
"safe_search_service.h",
"safe_sites_navigation_throttle.cc",
"safe_sites_navigation_throttle.h",
]
deps = [
"//base",
"//components/keyed_service/content:content",
"//components/policy/core/browser",
"//components/safe_search_api",
"//components/safe_search_api:safe_search_client",
"//content/public/browser",
"//net",
]
}
source_set("content") {
sources = [
"policy_blocklist_navigation_throttle.cc",
......@@ -15,15 +34,12 @@ source_set("content") {
]
deps = [
"//base",
":safe_sites_navigation_throttle",
"//components/keyed_service/content:content",
"//components/policy/core/browser",
"//components/prefs",
"//components/safe_search_api",
"//components/safe_search_api:safe_search_client",
"//components/user_prefs:user_prefs",
"//content/public/browser",
"//net",
]
}
......@@ -32,6 +48,7 @@ source_set("unit_tests") {
sources = [ "policy_blocklist_navigation_throttle_unittest.cc" ]
deps = [
":content",
":safe_sites_navigation_throttle",
"//base",
"//components/keyed_service/content",
"//components/policy/core/browser",
......
......@@ -6,11 +6,9 @@
#include "base/bind.h"
#include "base/check_op.h"
#include "base/strings/string_piece.h"
#include "components/policy/content/policy_blocklist_service.h"
#include "components/policy/core/browser/url_blocklist_manager.h"
#include "components/policy/core/browser/url_blocklist_policy_handler.h"
#include "components/policy/core/browser/url_util.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/user_prefs/user_prefs.h"
......@@ -21,29 +19,30 @@
using URLBlocklistState = policy::URLBlocklist::URLBlocklistState;
using SafeSitesFilterBehavior = policy::SafeSitesFilterBehavior;
// Passing an Unretained pointer for the safe_sites_navigation_throttle_
// callback is safe because this object owns safe_sites_navigation_throttle_,
// which runs the callback from within the object.
PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context)
: NavigationThrottle(navigation_handle),
: content::NavigationThrottle(navigation_handle),
safe_sites_navigation_throttle_(
navigation_handle,
context,
base::BindRepeating(
&PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult,
base::Unretained(this))),
blocklist_service_(PolicyBlocklistFactory::GetForBrowserContext(context)),
prefs_(user_prefs::UserPrefs::Get(context)) {
DCHECK(prefs_);
}
PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content)
: PolicyBlocklistNavigationThrottle(navigation_handle, context) {
safe_sites_error_page_content_ = safe_sites_error_page_content.as_string();
}
PolicyBlocklistNavigationThrottle::~PolicyBlocklistNavigationThrottle() =
default;
content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::WillStartRequest() {
GURL url = navigation_handle()->GetURL();
const GURL& url = navigation_handle()->GetURL();
// Ignore blob scheme because we may use it to deliver navigation responses
// to the renderer process.
......@@ -63,12 +62,11 @@ PolicyBlocklistNavigationThrottle::WillStartRequest() {
return CheckSafeSitesFilter(url);
}
// SafeSitesNavigationThrottle is unconditional and does not check PrefService
// because it is used outside //chrome. Therefore, the policy must be checked
// here to determine whether to use SafeSitesNavigationThrottle.
content::NavigationThrottle::ThrottleCheckResult
PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url) {
// Safe Sites filter applies to top-level HTTP[S] requests.
if (!url.SchemeIsHTTPOrHTTPS())
return PROCEED;
SafeSitesFilterBehavior filter_behavior =
static_cast<SafeSitesFilterBehavior>(
prefs_->GetInteger(policy::policy_prefs::kSafeSitesFilterBehavior));
......@@ -76,25 +74,7 @@ PolicyBlocklistNavigationThrottle::CheckSafeSitesFilter(const GURL& url) {
return PROCEED;
DCHECK_EQ(filter_behavior, SafeSitesFilterBehavior::kSafeSitesFilterEnabled);
GURL effective_url = policy::url_util::GetEmbeddedURL(url);
if (!effective_url.is_valid())
effective_url = url;
bool synchronous = blocklist_service_->CheckSafeSearchURL(
effective_url,
base::BindOnce(
&PolicyBlocklistNavigationThrottle::CheckSafeSearchCallback,
weak_ptr_factory_.GetWeakPtr()));
if (!synchronous) {
deferred_ = true;
return DEFER;
}
if (should_cancel_)
return ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR,
safe_sites_error_page_content_);
return PROCEED;
return safe_sites_navigation_throttle_.WillStartRequest();
}
content::NavigationThrottle::ThrottleCheckResult
......@@ -106,18 +86,12 @@ const char* PolicyBlocklistNavigationThrottle::GetNameForLogging() {
return "PolicyBlocklistNavigationThrottle";
}
void PolicyBlocklistNavigationThrottle::CheckSafeSearchCallback(bool is_safe) {
if (!deferred_) {
should_cancel_ = !is_safe;
return;
}
deferred_ = false;
void PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult(
bool is_safe,
ThrottleCheckResult cancel_result) {
if (is_safe) {
Resume();
} else {
CancelDeferredNavigation(
ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR,
safe_sites_error_page_content_));
CancelDeferredNavigation(cancel_result);
}
}
}
\ No newline at end of file
......@@ -5,20 +5,13 @@
#ifndef COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_
#define COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece_forward.h"
#include "components/policy/content/safe_sites_navigation_throttle.h"
#include "content/public/browser/navigation_throttle.h"
class GURL;
class PolicyBlocklistService;
class PrefService;
namespace content {
class BrowserContext;
class NavigationHandle;
} // namespace content
// PolicyBlocklistNavigationThrottle provides a simple way to block a navigation
// based on the URLBlocklistManager and Safe Search API. If the URL is on the
// blocklist or allowlist, the throttle will immediately block or allow the
......@@ -30,10 +23,10 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle {
PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context);
PolicyBlocklistNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content);
PolicyBlocklistNavigationThrottle(const PolicyBlocklistNavigationThrottle&) =
delete;
PolicyBlocklistNavigationThrottle& operator=(
const PolicyBlocklistNavigationThrottle&) = delete;
~PolicyBlocklistNavigationThrottle() override;
// NavigationThrottle overrides.
......@@ -42,30 +35,17 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle {
const char* GetNameForLogging() override;
private:
// To ensure both allow and block policies override Safe Sites,
// SafeSitesNavigationThrottle must be consulted as part of this throttle
// rather than added separately to the list of throttles.
ThrottleCheckResult CheckSafeSitesFilter(const GURL& url);
// Callback from PolicyBlocklistService.
void CheckSafeSearchCallback(bool is_safe);
void OnDeferredSafeSitesResult(bool is_safe,
ThrottleCheckResult cancel_result);
SafeSitesNavigationThrottle safe_sites_navigation_throttle_;
PolicyBlocklistService* blocklist_service_;
PrefService* prefs_;
// HTML to be displayed when navigation is canceled by the Safe Sites filter.
// If null, a default error page will be displayed.
base::Optional<std::string> safe_sites_error_page_content_;
// Whether the request was deferred in order to check the Safe Search API.
bool deferred_ = false;
// Whether the Safe Search API callback determined the in-progress navigation
// should be canceled.
bool should_cancel_ = false;
base::WeakPtrFactory<PolicyBlocklistNavigationThrottle> weak_ptr_factory_{
this};
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistNavigationThrottle);
};
#endif // COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_NAVIGATION_THROTTLE_H_
......@@ -7,35 +7,14 @@
#include <utility>
#include "base/bind.h"
#include "base/sequence_checker.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/browser/url_util.h"
#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
#include "components/safe_search_api/url_checker.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/net_errors.h"
namespace {
// Calls the PolicyBlocklistService callback with the result of the Safe Search
// API check.
void OnCheckURLDone(PolicyBlocklistService::CheckSafeSearchCallback callback,
const GURL& /* url */,
safe_search_api::Classification classification,
bool /* uncertain */) {
std::move(callback).Run(classification ==
safe_search_api::Classification::SAFE);
}
} // namespace
PolicyBlocklistService::PolicyBlocklistService(
content::BrowserContext* browser_context,
std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager)
: browser_context_(browser_context),
url_blocklist_manager_(std::move(url_blocklist_manager)) {}
: url_blocklist_manager_(std::move(url_blocklist_manager)) {}
PolicyBlocklistService::~PolicyBlocklistService() = default;
......@@ -44,53 +23,6 @@ PolicyBlocklistService::GetURLBlocklistState(const GURL& url) const {
return url_blocklist_manager_->GetURLBlocklistState(url);
}
bool PolicyBlocklistService::CheckSafeSearchURL(
const GURL& url,
CheckSafeSearchCallback callback) {
if (!safe_search_url_checker_) {
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("policy_blacklist_service", R"(
semantics {
sender: "Cloud Policy"
description:
"Checks whether a given URL (or set of URLs) is considered safe "
"by Google SafeSearch."
trigger:
"If the policy for safe sites is enabled, this is sent for every "
"top-level navigation if the result isn't already cached."
data: "URL to be checked."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This feature is off by default and cannot be controlled in "
"settings."
chrome_policy {
SafeSitesFilterBehavior {
SafeSitesFilterBehavior: 0
}
}
})");
safe_search_url_checker_ = std::make_unique<safe_search_api::URLChecker>(
std::make_unique<safe_search_api::SafeSearchURLCheckerClient>(
content::BrowserContext::GetDefaultStoragePartition(
browser_context_)
->GetURLLoaderFactoryForBrowserProcess(),
traffic_annotation));
}
return safe_search_url_checker_->CheckURL(
policy::url_util::Normalize(url),
base::BindOnce(&OnCheckURLDone, std::move(callback)));
}
void PolicyBlocklistService::SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker) {
safe_search_url_checker_ = std::move(safe_search_url_checker);
}
// static
PolicyBlocklistFactory* PolicyBlocklistFactory::GetInstance() {
return base::Singleton<PolicyBlocklistFactory>::get();
......@@ -115,7 +47,7 @@ KeyedService* PolicyBlocklistFactory::BuildServiceInstanceFor(
PrefService* pref_service = user_prefs::UserPrefs::Get(context);
auto url_blocklist_manager =
std::make_unique<policy::URLBlocklistManager>(pref_service);
return new PolicyBlocklistService(context, std::move(url_blocklist_manager));
return new PolicyBlocklistService(std::move(url_blocklist_manager));
}
content::BrowserContext* PolicyBlocklistFactory::GetBrowserContextToUse(
......
......@@ -7,52 +7,35 @@
#include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/policy/core/browser/url_blocklist_manager.h"
namespace safe_search_api {
class URLChecker;
} // namespace safe_search_api
// PolicyBlocklistService and PolicyBlocklistFactory provide a way for
// us to access URLBlocklistManager, a policy block list service based on
// the Preference Service. The URLBlocklistManager responds to permission
// changes and is per-Profile.
class PolicyBlocklistService : public KeyedService {
public:
using CheckSafeSearchCallback = base::OnceCallback<void(bool is_safe)>;
PolicyBlocklistService(
content::BrowserContext* browser_context,
explicit PolicyBlocklistService(
std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager);
PolicyBlocklistService(const PolicyBlocklistService&) = delete;
PolicyBlocklistService& operator=(const PolicyBlocklistService&) = delete;
~PolicyBlocklistService() override;
policy::URLBlocklist::URLBlocklistState GetURLBlocklistState(
const GURL& url) const;
// Starts a call to the Safe Search API for the given URL to determine whether
// the URL is "safe" (not porn). Returns whether |callback| was run
// synchronously.
bool CheckSafeSearchURL(const GURL& url, CheckSafeSearchCallback callback);
// Creates a SafeSearch URLChecker using a given URLLoaderFactory for testing.
void SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker);
private:
content::BrowserContext* const browser_context_;
std::unique_ptr<policy::URLBlocklistManager> url_blocklist_manager_;
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker_;
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistService);
};
class PolicyBlocklistFactory : public BrowserContextKeyedServiceFactory {
public:
PolicyBlocklistFactory(const PolicyBlocklistFactory&) = delete;
PolicyBlocklistFactory& operator=(const PolicyBlocklistFactory&) = delete;
static PolicyBlocklistFactory* GetInstance();
static PolicyBlocklistService* GetForBrowserContext(
content::BrowserContext* context);
......@@ -70,7 +53,6 @@ class PolicyBlocklistFactory : public BrowserContextKeyedServiceFactory {
content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override;
DISALLOW_COPY_AND_ASSIGN(PolicyBlocklistFactory);
};
#endif // COMPONENTS_POLICY_CONTENT_POLICY_BLOCKLIST_SERVICE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/content/safe_search_service.h"
#include <utility>
#include "base/bind.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/browser/url_util.h"
#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
#include "components/safe_search_api/url_checker.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/net_errors.h"
namespace {
// Calls the SafeSearchService callback with the result of the Safe Search
// API check.
void OnCheckURLDone(SafeSearchService::CheckSafeSearchCallback callback,
const GURL& /* url */,
safe_search_api::Classification classification,
bool /* uncertain */) {
std::move(callback).Run(classification ==
safe_search_api::Classification::SAFE);
}
} // namespace
SafeSearchService::SafeSearchService(content::BrowserContext* browser_context)
: browser_context_(browser_context) {}
SafeSearchService::~SafeSearchService() = default;
bool SafeSearchService::CheckSafeSearchURL(const GURL& url,
CheckSafeSearchCallback callback) {
if (!safe_search_url_checker_) {
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("safe_search_service", R"(
semantics {
sender: "Cloud Policy"
description:
"Checks whether a given URL (or set of URLs) is considered safe "
"by Google SafeSearch."
trigger:
"If the policy for safe sites is enabled, this is sent for every "
"top-level navigation if the result isn't already cached."
data: "URL to be checked."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This feature is off by default and cannot be controlled in "
"settings."
chrome_policy {
SafeSitesFilterBehavior {
SafeSitesFilterBehavior: 0
}
}
})");
safe_search_url_checker_ = std::make_unique<safe_search_api::URLChecker>(
std::make_unique<safe_search_api::SafeSearchURLCheckerClient>(
content::BrowserContext::GetDefaultStoragePartition(
browser_context_)
->GetURLLoaderFactoryForBrowserProcess(),
traffic_annotation));
}
return safe_search_url_checker_->CheckURL(
policy::url_util::Normalize(url),
base::BindOnce(&OnCheckURLDone, std::move(callback)));
}
void SafeSearchService::SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker) {
safe_search_url_checker_ = std::move(safe_search_url_checker);
}
// static
SafeSearchFactory* SafeSearchFactory::GetInstance() {
return base::Singleton<SafeSearchFactory>::get();
}
// static
SafeSearchService* SafeSearchFactory::GetForBrowserContext(
content::BrowserContext* context) {
return static_cast<SafeSearchService*>(
GetInstance()->GetServiceForBrowserContext(context, true));
}
SafeSearchFactory::SafeSearchFactory()
: BrowserContextKeyedServiceFactory(
"SafeSearch",
BrowserContextDependencyManager::GetInstance()) {}
SafeSearchFactory::~SafeSearchFactory() = default;
KeyedService* SafeSearchFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new SafeSearchService(context);
}
content::BrowserContext* SafeSearchFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
return context;
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_POLICY_CONTENT_SAFE_SEARCH_SERVICE_H_
#define COMPONENTS_POLICY_CONTENT_SAFE_SEARCH_SERVICE_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
class GURL;
namespace safe_search_api {
class URLChecker;
} // namespace safe_search_api
// SafeSearchService and SafeSearchFactory provide a way for
// us to access a Context-specific instance of safe_search_api.
class SafeSearchService : public KeyedService {
public:
using CheckSafeSearchCallback = base::OnceCallback<void(bool is_safe)>;
explicit SafeSearchService(content::BrowserContext* browser_context);
SafeSearchService(const SafeSearchService&) = delete;
SafeSearchService& operator=(const SafeSearchService&) = delete;
~SafeSearchService() override;
// Starts a call to the Safe Search API for the given URL to determine whether
// the URL is "safe" (not porn). Returns whether |callback| was run
// synchronously.
bool CheckSafeSearchURL(const GURL& url, CheckSafeSearchCallback callback);
// Creates a SafeSearch URLChecker using a given URLLoaderFactory for testing.
void SetSafeSearchURLCheckerForTest(
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker);
private:
content::BrowserContext* const browser_context_;
std::unique_ptr<safe_search_api::URLChecker> safe_search_url_checker_;
};
class SafeSearchFactory : public BrowserContextKeyedServiceFactory {
public:
SafeSearchFactory(const SafeSearchFactory&) = delete;
SafeSearchFactory& operator=(const SafeSearchFactory&) = delete;
static SafeSearchFactory* GetInstance();
static SafeSearchService* GetForBrowserContext(
content::BrowserContext* context);
private:
SafeSearchFactory();
~SafeSearchFactory() override;
friend struct base::DefaultSingletonTraits<SafeSearchFactory>;
// BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
// Finds which browser context (if any) to use.
content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override;
};
#endif // COMPONENTS_POLICY_CONTENT_SAFE_SEARCH_SERVICE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/policy/content/safe_sites_navigation_throttle.h"
#include "base/bind.h"
#include "base/strings/string_piece.h"
#include "components/policy/content/safe_search_service.h"
#include "components/policy/core/browser/url_util.h"
#include "content/public/browser/navigation_handle.h"
#include "url/gurl.h"
SafeSitesNavigationThrottle::SafeSitesNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context)
: SafeSitesNavigationThrottle(
navigation_handle,
context,
base::BindRepeating(&SafeSitesNavigationThrottle::OnDeferredResult,
base::Unretained(this))) {}
SafeSitesNavigationThrottle::SafeSitesNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
DeferredResultCallback deferred_result_callback)
: NavigationThrottle(navigation_handle),
safe_seach_service_(SafeSearchFactory::GetForBrowserContext(context)),
deferred_result_callback_(std::move(deferred_result_callback)) {}
// Use of Unretained for is safe because it is called synchronously from this
// object.
SafeSitesNavigationThrottle::SafeSitesNavigationThrottle(
content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content)
: NavigationThrottle(navigation_handle),
safe_seach_service_(SafeSearchFactory::GetForBrowserContext(context)),
deferred_result_callback_(
base::BindRepeating(&SafeSitesNavigationThrottle::OnDeferredResult,
base::Unretained(this))),
safe_sites_error_page_content_(
safe_sites_error_page_content.as_string()) {}
SafeSitesNavigationThrottle::~SafeSitesNavigationThrottle() = default;
content::NavigationThrottle::ThrottleCheckResult
SafeSitesNavigationThrottle::WillStartRequest() {
const GURL& url = navigation_handle()->GetURL();
// Ignore blob scheme because we may use it to deliver navigation responses
// to the renderer process.
if (url.SchemeIs(url::kBlobScheme))
return PROCEED;
// Safe Sites filter applies to top-level HTTP[S] requests.
if (!url.SchemeIsHTTPOrHTTPS())
return PROCEED;
GURL effective_url = policy::url_util::GetEmbeddedURL(url);
if (!effective_url.is_valid())
effective_url = url;
bool synchronous = safe_seach_service_->CheckSafeSearchURL(
effective_url,
base::BindOnce(&SafeSitesNavigationThrottle::CheckSafeSearchCallback,
weak_ptr_factory_.GetWeakPtr()));
if (!synchronous) {
deferred_ = true;
return DEFER;
}
if (should_cancel_)
return CreateCancelResult();
return PROCEED;
}
content::NavigationThrottle::ThrottleCheckResult
SafeSitesNavigationThrottle::WillRedirectRequest() {
return WillStartRequest();
}
const char* SafeSitesNavigationThrottle::GetNameForLogging() {
return "SafeSitesNavigationThrottle";
}
void SafeSitesNavigationThrottle::CheckSafeSearchCallback(bool is_safe) {
if (!deferred_) {
should_cancel_ = !is_safe;
return;
}
deferred_ = false;
deferred_result_callback_.Run(is_safe, CreateCancelResult());
}
void SafeSitesNavigationThrottle::OnDeferredResult(
bool is_safe,
ThrottleCheckResult cancel_result) {
if (is_safe) {
Resume();
} else {
CancelDeferredNavigation(cancel_result);
}
}
content::NavigationThrottle::ThrottleCheckResult
SafeSitesNavigationThrottle::CreateCancelResult() const {
return ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR,
safe_sites_error_page_content_);
}
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_POLICY_CONTENT_SAFE_SITES_NAVIGATION_THROTTLE_H_
#define COMPONENTS_POLICY_CONTENT_SAFE_SITES_NAVIGATION_THROTTLE_H_
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/strings/string_piece_forward.h"
#include "content/public/browser/navigation_throttle.h"
class SafeSearchService;
namespace content {
class BrowserContext;
class NavigationHandle;
} // namespace content
// SafeSitesNavigationThrottle provides a simple way to block a navigation
// based on the Safe Search API. The URL is checked against the Safe Search API.
// The check may be asynchronous if the result hasn't been cached yet.
// This class does not check the SafeSitesFilterBehavior policy.
class SafeSitesNavigationThrottle : public content::NavigationThrottle {
public:
// Called when the SafeSearch result is available after being deferred.
// if !|is_safe|, |cancel_result| contains the result to pass to
// CancelDeferredNavigation(). Other NavigationThrottles using this object
// must handle resolving deferred navigation themselves due to checks in
// NavigationThrottleRunner.
using DeferredResultCallback =
base::RepeatingCallback<void(bool is_safe,
ThrottleCheckResult cancel_result)>;
SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle,
content::BrowserContext* context);
SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
DeferredResultCallback deferred_result_callback);
SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle,
content::BrowserContext* context,
base::StringPiece safe_sites_error_page_content);
SafeSitesNavigationThrottle(const SafeSitesNavigationThrottle&) = delete;
SafeSitesNavigationThrottle& operator=(const SafeSitesNavigationThrottle&) =
delete;
~SafeSitesNavigationThrottle() override;
// NavigationThrottle overrides.
ThrottleCheckResult WillStartRequest() override;
ThrottleCheckResult WillRedirectRequest() override;
const char* GetNameForLogging() override;
private:
// Callback from SafeSearchService.
void CheckSafeSearchCallback(bool is_safe);
// The default implementation DeferredResultCallback.
void OnDeferredResult(bool is_safe, ThrottleCheckResult cancel_result);
// Creates the result to be returned when navigation is canceled.
ThrottleCheckResult CreateCancelResult() const;
SafeSearchService* safe_seach_service_;
const DeferredResultCallback deferred_result_callback_;
// HTML to be displayed when navigation is canceled by the Safe Sites filter.
// If null, a default error page will be displayed.
const base::Optional<std::string> safe_sites_error_page_content_;
// Whether the request was deferred in order to check the Safe Search API.
bool deferred_ = false;
// Whether the Safe Search API callback determined the in-progress navigation
// should be canceled.
bool should_cancel_ = false;
base::WeakPtrFactory<SafeSitesNavigationThrottle> weak_ptr_factory_{this};
};
#endif // COMPONENTS_POLICY_CONTENT_SAFE_SITES_NAVIGATION_THROTTLE_H_
......@@ -231,7 +231,6 @@ Refer to README.md for content description and update process.
<item id="permission_request_creator" added_in_milestone="62" hash_code="43206794" type="0" deprecated="2019-07-30" content_hash_code="73571699" file_path=""/>
<item id="persist_blob_to_indexed_db" added_in_milestone="62" hash_code="32030464" type="0" deprecated="2018-08-13" content_hash_code="35410079" file_path=""/>
<item id="plugins_resource_service" added_in_milestone="62" hash_code="49601082" type="0" content_hash_code="6877335" os_list="linux,windows" file_path="chrome/browser/plugins/plugins_resource_service.cc"/>
<item id="policy_blacklist_service" added_in_milestone="70" hash_code="49799644" type="0" content_hash_code="57843386" os_list="linux,windows" file_path="components/policy/content/policy_blocklist_service.cc"/>
<item id="popular_sites_fetch" added_in_milestone="62" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows" file_path="components/ntp_tiles/popular_sites_impl.cc"/>
<item id="port_forwarding_controller_socket" added_in_milestone="65" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/>
<item id="ppapi_download_request" added_in_milestone="62" hash_code="135967426" type="0" content_hash_code="110461402" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/>
......@@ -300,6 +299,7 @@ Refer to README.md for content description and update process.
<item id="safe_browsing_realtime_url_lookup" added_in_milestone="78" hash_code="119324658" type="0" content_hash_code="71236226" os_list="linux,windows" file_path="components/safe_browsing/core/realtime/url_lookup_service.cc"/>
<item id="safe_browsing_v4_get_hash" added_in_milestone="62" hash_code="8561691" type="0" content_hash_code="132435617" os_list="linux,windows" file_path="components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc"/>
<item id="safe_browsing_v4_update" added_in_milestone="70" hash_code="82509217" type="0" content_hash_code="5247849" os_list="linux,windows" file_path="components/safe_browsing/core/db/v4_update_protocol_manager.cc"/>
<item id="safe_search_service" added_in_milestone="70" hash_code="136386805" type="0" content_hash_code="127491095" os_list="linux,windows" file_path="components/policy/content/safe_search_service.cc"/>
<item id="safety_check_update_connectivity" added_in_milestone="84" hash_code="137724067" type="0" content_hash_code="30977369" os_list="linux,windows" file_path="components/safety_check/update_check_helper.cc"/>
<item id="sanitized_image_source" added_in_milestone="86" hash_code="36944304" type="0" content_hash_code="39770427" os_list="linux,windows" file_path="chrome/browser/ui/webui/sanitized_image_source.cc"/>
<item id="save_file_manager" added_in_milestone="62" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows" file_path="content/browser/download/save_file_manager.cc"/>
......
......@@ -242,9 +242,9 @@ hidden="true" so that these annotations don't show up in the document.
<traffic_annotation unique_id="gaia_oauth_client_get_tokens"/>
<traffic_annotation unique_id="gaia_oauth_client_get_user_info"/>
<traffic_annotation unique_id="gaia_oauth_client_refresh_token"/>
<traffic_annotation unique_id="policy_blacklist_service"/>
<traffic_annotation unique_id="oauth2_access_token_fetcher"/>
<traffic_annotation unique_id="oauth2_mint_token_flow"/>
<traffic_annotation unique_id="safe_search_service"/>
</sender>
<sender name="Payments">
<traffic_annotation unique_id="payments_sync_cards"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment