Commit 65d98ed3 authored by Ali Juma's avatar Ali Juma Committed by Commit Bot

[iOS] Make a Safe Browsing query on each navigation

This CL introduces a SafeBrowsingTabHelper, which is a WebStatePolicyDecider
that makes a Safe Browsing query on each call to ShouldAllowRequest(). For
now, the result of the Safe Browsing query is ignored; the purpose of making
the Safe Browsing query is to exercise the Safe Browsing database code and
record UMA (being added in http://crrev.com/c/2087415) for database freshness.

This new behavior is behind the kSafeBrowsingAvailableOnIOS flag.

Bug: 1049340
Change-Id: I2844637fa9e3c0845fca6355ff1547b9d19252c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2092127
Commit-Queue: Ali Juma <ajuma@chromium.org>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Reviewed-by: default avatarKurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarVarun Khaneja <vakh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#749343}
parent 97622acc
......@@ -9,20 +9,27 @@ source_set("safe_browsing") {
sources = [
"safe_browsing_service.h",
"safe_browsing_service.mm",
"safe_browsing_tab_helper.h",
"safe_browsing_tab_helper.mm",
]
deps = [
"//base",
"//build:branding_buildflags",
"//components/prefs",
"//components/safe_browsing/core:features",
"//components/safe_browsing/core/browser",
"//components/safe_browsing/core/common",
"//components/safe_browsing/core/db",
"//components/safe_browsing/core/db:database_manager",
"//components/safe_browsing/core/db:v4_local_database_manager",
"//components/safe_browsing/core/db:v4_protocol_manager_util",
"//ios/chrome/browser",
"//ios/net",
"//ios/web/public",
"//ios/web/public/init",
"//mojo/public/cpp/bindings",
"//net",
"//services/network:network_service",
"//services/network/public/cpp",
"//services/network/public/mojom",
......
// 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 IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TAB_HELPER_H_
#define IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TAB_HELPER_H_
#include "base/macros.h"
#include "components/safe_browsing/core/db/database_manager.h"
#include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
#import "ios/web/public/navigation/web_state_policy_decider.h"
#import "ios/web/public/web_state_user_data.h"
// A tab helper that uses Safe Browsing to check whether URLs that are being
// navigated to are unsafe.
class SafeBrowsingTabHelper
: public web::WebStateUserData<SafeBrowsingTabHelper> {
public:
~SafeBrowsingTabHelper() override;
SafeBrowsingTabHelper(const SafeBrowsingTabHelper&) = delete;
SafeBrowsingTabHelper& operator=(const SafeBrowsingTabHelper&) = delete;
private:
friend class web::WebStateUserData<SafeBrowsingTabHelper>;
// A simple SafeBrowsingDatabaseManager::Client that queries the database but
// doesn't do anything with the result yet. This class may be constructed on
// the UI thread but otherwise must only be used and destroyed on the IO
// thread.
// TODO(crbug.com/1028755): Use the result of Safe Browsing queries to block
// navigations that are identified as unsafe.
class DatabaseClient
: public safe_browsing::SafeBrowsingDatabaseManager::Client {
public:
explicit DatabaseClient(
safe_browsing::SafeBrowsingDatabaseManager* database_manager);
~DatabaseClient() override;
// Query the database with the given |url|.
void CheckUrl(const GURL& url);
private:
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
// The set of threat types that URLs are checked against.
safe_browsing::SBThreatTypeSet threat_types_;
};
// A WebStatePolicyDecider that queries the SafeBrowsing database on each
// request, but always allows the request.
// TODO(crbug.com/1028755): Use the result of Safe Browsing queries to block
// navigations that are identified as unsafe.
class PolicyDecider : public web::WebStatePolicyDecider {
public:
PolicyDecider(web::WebState* web_state, DatabaseClient* database_client);
// web::WebStatePolicyDecider implementation
bool ShouldAllowRequest(
NSURLRequest* request,
const web::WebStatePolicyDecider::RequestInfo& request_info) override;
private:
DatabaseClient* database_client_;
};
explicit SafeBrowsingTabHelper(web::WebState* web_state);
std::unique_ptr<DatabaseClient> database_client_;
std::unique_ptr<PolicyDecider> policy_decider_;
WEB_STATE_USER_DATA_KEY_DECL();
};
#endif // IOS_CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TAB_HELPER_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.
#import "ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h"
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/task/post_task.h"
#include "components/safe_browsing/core/features.h"
#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/safe_browsing/safe_browsing_service.h"
#include "ios/web/public/thread/web_task_traits.h"
#import "net/base/mac/url_conversions.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#pragma mark - SafeBrowsingTabHelper
SafeBrowsingTabHelper::SafeBrowsingTabHelper(web::WebState* web_state) {
DCHECK(
base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingAvailableOnIOS));
// Unit tests that use a TestingApplicationContext don't have a
// SafeBrowsingService.
// TODO(crbug.com/1060300): Create a FakeSafeBrowsingService and use it in
// TestingApplicationContext, so that a special case for tests isn't needed
// here.
if (!GetApplicationContext()->GetSafeBrowsingService())
return;
database_client_ = std::make_unique<SafeBrowsingTabHelper::DatabaseClient>(
GetApplicationContext()->GetSafeBrowsingService()->GetDatabaseManager());
policy_decider_ = std::make_unique<SafeBrowsingTabHelper::PolicyDecider>(
web_state, database_client_.get());
}
SafeBrowsingTabHelper::~SafeBrowsingTabHelper() {
if (database_client_) {
base::DeleteSoon(FROM_HERE, {web::WebThread::IO},
database_client_.release());
}
}
WEB_STATE_USER_DATA_KEY_IMPL(SafeBrowsingTabHelper)
#pragma mark - SafeBrowsingTabHelper::DatabaseClient
SafeBrowsingTabHelper::DatabaseClient::DatabaseClient(
safe_browsing::SafeBrowsingDatabaseManager* database_manager)
: database_manager_(database_manager),
threat_types_(safe_browsing::CreateSBThreatTypeSet(
{safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
safe_browsing::SB_THREAT_TYPE_URL_UNWANTED,
safe_browsing::SB_THREAT_TYPE_BILLING})) {}
SafeBrowsingTabHelper::DatabaseClient::~DatabaseClient() {
DCHECK_CURRENTLY_ON(web::WebThread::IO);
database_manager_->CancelCheck(this);
}
void SafeBrowsingTabHelper::DatabaseClient::CheckUrl(const GURL& url) {
DCHECK_CURRENTLY_ON(web::WebThread::IO);
database_manager_->CheckBrowseUrl(url, threat_types_, this);
}
#pragma mark - SafeBrowsingTabHelper::PolicyDecider
SafeBrowsingTabHelper::PolicyDecider::PolicyDecider(
web::WebState* web_state,
SafeBrowsingTabHelper::DatabaseClient* database_client)
: web::WebStatePolicyDecider(web_state),
database_client_(database_client) {}
bool SafeBrowsingTabHelper::PolicyDecider::ShouldAllowRequest(
NSURLRequest* request,
const web::WebStatePolicyDecider::RequestInfo& request_info) {
if (!database_client_)
return true;
GURL request_url = net::GURLWithNSURL(request.URL);
base::PostTask(
FROM_HERE, {web::WebThread::IO},
base::BindOnce(&SafeBrowsingTabHelper::DatabaseClient::CheckUrl,
base::Unretained(database_client_), request_url));
return true;
}
......@@ -51,6 +51,7 @@ source_set("tabs_internal") {
"//components/language/ios/browser",
"//components/navigation_metrics",
"//components/profile_metrics",
"//components/safe_browsing/core:features",
"//components/security_state/ios",
"//components/sessions",
"//components/strings",
......@@ -84,6 +85,7 @@ source_set("tabs_internal") {
"//ios/chrome/browser/passwords",
"//ios/chrome/browser/prerender",
"//ios/chrome/browser/reading_list",
"//ios/chrome/browser/safe_browsing",
"//ios/chrome/browser/search_engines",
"//ios/chrome/browser/sessions",
"//ios/chrome/browser/sessions:restoration_agent",
......
......@@ -14,6 +14,7 @@
#import "components/history/ios/browser/web_state_top_sites_observer.h"
#include "components/keyed_service/core/service_access_type.h"
#import "components/language/ios/browser/ios_language_detection_tab_helper.h"
#include "components/safe_browsing/core/features.h"
#import "components/security_state/ios/insecure_input_tab_helper.h"
#import "components/ukm/ios/ukm_url_recorder.h"
#import "ios/chrome/browser/autofill/autofill_tab_helper.h"
......@@ -41,6 +42,7 @@
#import "ios/chrome/browser/passwords/password_tab_helper.h"
#include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
#import "ios/chrome/browser/reading_list/reading_list_web_state_observer.h"
#import "ios/chrome/browser/safe_browsing/safe_browsing_tab_helper.h"
#import "ios/chrome/browser/search_engines/search_engine_tab_helper.h"
#import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
#import "ios/chrome/browser/snapshots/snapshot_tab_helper.h"
......@@ -113,6 +115,11 @@ void AttachTabHelpers(web::WebState* web_state, bool for_prerender) {
BreadcrumbManagerTabHelper::CreateForWebState(web_state);
}
if (base::FeatureList::IsEnabled(
safe_browsing::kSafeBrowsingAvailableOnIOS)) {
SafeBrowsingTabHelper::CreateForWebState(web_state);
}
ImageFetchTabHelper::CreateForWebState(web_state);
OpenInTabHelper::CreateForWebState(web_state);
......
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