Commit 6d358e32 authored by Selim Gurun's avatar Selim Gurun Committed by Commit Bot

Add a whitelisting manager for Safebrowsing

Add a whitelisting manager for safebrowsing. This code will be plumbed
to an Android WebView API so that applications can whitelist 
(i.e. prevent) domains from being checked by Safebrowsing logic.
 
The main rules are:
- if host has a leading ".", it needs to be exact to be whitelisted.
- if host does not have a leading ".", subdomains are also whitelisted.

Invalid schemes are also ignored. Note that Safebrowsing only works on h
ttp/https and in future ws urls.

Bug: 726770
Change-Id: Icbffebd87472286508f1902cd6323ce58faee797
Reviewed-on: https://chromium-review.googlesource.com/563520
Commit-Queue: Selim Gurun <sgurun@chromium.org>
Reviewed-by: default avatarVarun Khaneja <vakh@chromium.org>
Reviewed-by: default avatarEric Roman <eroman@chromium.org>
Reviewed-by: default avatarNate Fischer <ntfschr@chromium.org>
Reviewed-by: default avatarBo Liu <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487567}
parent fd0c62ae
......@@ -522,6 +522,8 @@ source_set("common") {
"browser/aw_safe_browsing_resource_throttle.h",
"browser/aw_safe_browsing_ui_manager.cc",
"browser/aw_safe_browsing_ui_manager.h",
"browser/aw_safe_browsing_whitelist_manager.cc",
"browser/aw_safe_browsing_whitelist_manager.h",
"browser/aw_settings.cc",
"browser/aw_settings.h",
"browser/aw_ssl_host_state_delegate.cc",
......@@ -711,6 +713,7 @@ source_set("common") {
"//components/spellcheck:build_features",
"//components/supervised_user_error_page",
"//components/supervised_user_error_page:gin",
"//components/url_matcher",
"//components/version_info",
"//components/visitedlink/browser",
"//components/visitedlink/renderer",
......
......@@ -12,6 +12,7 @@
#include "android_webview/browser/aw_permission_manager.h"
#include "android_webview/browser/aw_quota_manager_bridge.h"
#include "android_webview/browser/aw_resource_context.h"
#include "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
#include "android_webview/browser/net/aw_url_request_context_getter.h"
#include "android_webview/common/aw_content_client.h"
#include "base/base_paths_android.h"
......@@ -107,6 +108,18 @@ policy::URLBlacklistManager* CreateURLBlackListManager(
base::Bind(OverrideBlacklistForURL));
}
std::unique_ptr<AwSafeBrowsingWhitelistManager>
CreateSafeBrowsingWhitelistManager() {
// Should not be called until the end of PreMainMessageLoopRun,
scoped_refptr<base::SequencedTaskRunner> background_task_runner =
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BACKGROUND});
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
return base::MakeUnique<AwSafeBrowsingWhitelistManager>(
background_task_runner, io_task_runner);
}
} // namespace
// Delete the legacy cache dir (in the app data dir) in 10 seconds after init.
......@@ -208,6 +221,7 @@ void AwBrowserContext::PreMainMessageLoopRun() {
safe_browsing_trigger_manager_ =
base::MakeUnique<safe_browsing::TriggerManager>(
safe_browsing_ui_manager_.get());
safe_browsing_whitelist_manager_ = CreateSafeBrowsingWhitelistManager();
}
void AwBrowserContext::OnWebRestrictionsAuthorityChanged() {
......@@ -377,7 +391,7 @@ AwBrowserContext::GetWebRestrictionProvider() {
return web_restriction_provider_.get();
}
AwSafeBrowsingUIManager* AwBrowserContext::GetSafeBrowsingUIManager() {
AwSafeBrowsingUIManager* AwBrowserContext::GetSafeBrowsingUIManager() const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return safe_browsing_ui_manager_.get();
}
......@@ -401,6 +415,12 @@ safe_browsing::TriggerManager* AwBrowserContext::GetSafeBrowsingTriggerManager()
return safe_browsing_trigger_manager_.get();
}
AwSafeBrowsingWhitelistManager*
AwBrowserContext::GetSafeBrowsingWhitelistManager() const {
// Should not be called until the end of PreMainMessageLoopRun,
return safe_browsing_whitelist_manager_.get();
}
void AwBrowserContext::RebuildTable(
const scoped_refptr<URLEnumerator>& enumerator) {
// Android WebView rebuilds from WebChromeClient.getVisitedHistory. The client
......
......@@ -50,6 +50,7 @@ namespace android_webview {
class AwFormDatabaseService;
class AwQuotaManagerBridge;
class AwSafeBrowsingWhitelistManager;
class AwURLRequestContextGetter;
namespace prefs {
......@@ -119,9 +120,10 @@ class AwBrowserContext : public content::BrowserContext,
// visitedlink::VisitedLinkDelegate implementation.
void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override;
AwSafeBrowsingUIManager* GetSafeBrowsingUIManager();
AwSafeBrowsingUIManager* GetSafeBrowsingUIManager() const;
safe_browsing::RemoteSafeBrowsingDatabaseManager* GetSafeBrowsingDBManager();
safe_browsing::TriggerManager* GetSafeBrowsingTriggerManager() const;
AwSafeBrowsingWhitelistManager* GetSafeBrowsingWhitelistManager() const;
private:
void InitUserPrefService();
......@@ -160,6 +162,9 @@ class AwBrowserContext : public content::BrowserContext,
safe_browsing_db_manager_;
bool safe_browsing_db_manager_started_ = false;
std::unique_ptr<AwSafeBrowsingWhitelistManager>
safe_browsing_whitelist_manager_;
DISALLOW_COPY_AND_ASSIGN(AwBrowserContext);
};
......
......@@ -8,8 +8,10 @@
#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_contents_io_thread_client.h"
#include "android_webview/browser/aw_safe_browsing_config_helper.h"
#include "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
#include "android_webview/browser/net/aw_url_request_context_getter.h"
#include "android_webview/common/aw_version_info_values.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
......@@ -89,6 +91,17 @@ void SetSafeBrowsingEnabled(JNIEnv* env,
AwSafeBrowsingConfigHelper::SetSafeBrowsingEnabled(enable);
}
// static
void SetSafeBrowsingWhiteList(JNIEnv* env,
const JavaParamRef<jclass>&,
const JavaParamRef<jobjectArray>& jrules) {
std::vector<std::string> rules;
base::android::AppendJavaStringArrayToStringVector(env, jrules, &rules);
AwSafeBrowsingWhitelistManager* whitelist_manager =
AwBrowserContext::GetDefault()->GetSafeBrowsingWhitelistManager();
whitelist_manager->SetWhitelistOnUIThread(std::move(rules));
}
// static
void SetServiceWorkerIoThreadClient(
JNIEnv* env,
......
......@@ -6,6 +6,7 @@
#include "android_webview/browser/aw_contents_client_bridge.h"
#include "android_webview/browser/aw_safe_browsing_ui_manager.h"
#include "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
#include "base/macros.h"
#include "components/safe_browsing/base_resource_throttle.h"
#include "components/safe_browsing_db/database_manager.h"
......@@ -28,10 +29,12 @@ AwSafeBrowsingResourceThrottle* AwSafeBrowsingResourceThrottle::MaybeCreate(
net::URLRequest* request,
content::ResourceType resource_type,
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
scoped_refptr<AwSafeBrowsingUIManager> ui_manager) {
scoped_refptr<AwSafeBrowsingUIManager> ui_manager,
AwSafeBrowsingWhitelistManager* whitelist_manager) {
if (database_manager->IsSupported()) {
return new AwSafeBrowsingResourceThrottle(request, resource_type,
database_manager, ui_manager);
database_manager, ui_manager,
whitelist_manager);
}
return nullptr;
}
......@@ -40,7 +43,8 @@ AwSafeBrowsingResourceThrottle::AwSafeBrowsingResourceThrottle(
net::URLRequest* request,
content::ResourceType resource_type,
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
scoped_refptr<AwSafeBrowsingUIManager> ui_manager)
scoped_refptr<AwSafeBrowsingUIManager> ui_manager,
AwSafeBrowsingWhitelistManager* whitelist_manager)
: safe_browsing::BaseResourceThrottle(
request,
resource_type,
......@@ -49,10 +53,18 @@ AwSafeBrowsingResourceThrottle::AwSafeBrowsingResourceThrottle(
safe_browsing::SB_THREAT_TYPE_URL_PHISHING}),
database_manager,
ui_manager),
request_(request) {}
request_(request),
whitelist_manager_(whitelist_manager) {}
AwSafeBrowsingResourceThrottle::~AwSafeBrowsingResourceThrottle() {}
bool AwSafeBrowsingResourceThrottle::CheckUrl(const GURL& gurl) {
if (whitelist_manager_->IsURLWhitelisted(gurl)) {
return true;
}
return BaseResourceThrottle::CheckUrl(gurl);
}
void AwSafeBrowsingResourceThrottle::StartDisplayingBlockingPageHelper(
security_interstitials::UnsafeResource resource) {
content::BrowserThread::PostTask(
......
......@@ -22,6 +22,8 @@ using safe_browsing::SBThreatType;
namespace android_webview {
class AwSafeBrowsingWhitelistManager;
class AwSafeBrowsingResourceThrottle
: public safe_browsing::BaseResourceThrottle {
public:
......@@ -32,6 +34,8 @@ class AwSafeBrowsingResourceThrottle
BACK_TO_SAFETY,
};
static const void* kUserDataKey;
// Will construct an AwSafeBrowsingResourceThrottle if GMS exists on device
// and supports safebrowsing.
static AwSafeBrowsingResourceThrottle* MaybeCreate(
......@@ -39,9 +43,11 @@ class AwSafeBrowsingResourceThrottle
content::ResourceType resource_type,
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager,
scoped_refptr<AwSafeBrowsingUIManager> ui_manager);
scoped_refptr<AwSafeBrowsingUIManager> ui_manager,
AwSafeBrowsingWhitelistManager* whitelist_manager);
static const void* kUserDataKey;
protected:
bool CheckUrl(const GURL& url) override;
private:
AwSafeBrowsingResourceThrottle(
......@@ -49,7 +55,8 @@ class AwSafeBrowsingResourceThrottle
content::ResourceType resource_type,
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager,
scoped_refptr<AwSafeBrowsingUIManager> ui_manager);
scoped_refptr<AwSafeBrowsingUIManager> ui_manager,
AwSafeBrowsingWhitelistManager* whitelist_manager);
~AwSafeBrowsingResourceThrottle() override;
......@@ -77,6 +84,8 @@ class AwSafeBrowsingResourceThrottle
net::URLRequest* request_;
AwSafeBrowsingWhitelistManager* whitelist_manager_;
DISALLOW_COPY_AND_ASSIGN(AwSafeBrowsingResourceThrottle);
};
......
// Copyright 2017 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 "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
#include <map>
#include "base/bind.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/url_util.h"
#include "url/url_util.h"
namespace android_webview {
// This is a simple trie structure designed for handling host/domain matches
// for Safebrowsing whitelisting. For the match rules, see the class header.
//
// It is easy to visualize the trie edges as hostname components of a url in
// reverse order. For example a whitelist of google.com will have a tree
// tree structure as below.
// root
// | com
// Node1
// google/ \ example
// Node2 Node3
//
// Normally, a search in the tree should end in a leaf node for a positive
// match. For example in the tree above com.google and com.example are matches.
// However, the whitelisting also allows matching subdomains if there is a
// leading dot, for example, see ."google.com" and a.google.com below:
// root
// | com
// Node1
// | google
// Node2
// | a
// Node3
// Here, both Node2 and Node3 are valid terminal nodes to terminate a match.
// The boolean is_terminal indicates whether a node can successfully terminate
// a search (aka. whether this rule was entered to the whitelist) and
// match_prefix indicate if this should match exactly, or just do a prefix
// match.
// The structure is optimized such that if a node already allows a prefix
// match, then there is no need for it to have children, or if it has children
// these children are removed.
struct TrieNode {
std::map<std::string, std::unique_ptr<TrieNode>> children;
bool match_prefix = false;
bool is_terminal = false;
};
namespace {
void InsertRuleToTrie(const std::vector<base::StringPiece>& components,
TrieNode* root,
bool match_prefix) {
TrieNode* node = root;
for (auto hostcomp = components.rbegin(); hostcomp != components.rend();
++hostcomp) {
DCHECK(!node->match_prefix);
std::string component = hostcomp->as_string();
auto child_node = node->children.find(component);
if (child_node == node->children.end()) {
std::unique_ptr<TrieNode> temp = base::MakeUnique<TrieNode>();
TrieNode* current = temp.get();
node->children.emplace(component, std::move(temp));
node = current;
} else {
node = child_node->second.get();
// Optimization. No need to add new nodes as this node matches prefixes.
DCHECK(node);
if (node->match_prefix)
return;
}
}
DCHECK(node != root);
// Optimization. If match_prefix is true, remove all nodes originating
// from that node.
if (match_prefix) {
node->match_prefix = true;
node->children.clear();
}
node->is_terminal = true;
}
std::vector<base::StringPiece> SplitHost(const GURL& url) {
std::vector<base::StringPiece> components;
if (url.HostIsIPAddress()) {
components.push_back(url.host_piece());
} else {
components =
base::SplitStringPiece(url.host_piece(), ".", base::KEEP_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
}
DCHECK(components.size() > 0);
return components;
}
// Rule is a UTF-8 wide string.
bool AddRuleToWhitelist(base::StringPiece rule, TrieNode* root) {
if (rule.empty()) {
return false;
}
// Leading dot means to do an exact match.
bool started_with_dot = false;
if (rule.front() == '.') {
rule.remove_prefix(1); // Strip it for the rest of the handling.
started_with_dot = true;
}
// With the dot removed |rule| should look like a hostname.
GURL test_url("http://" + rule.as_string());
if (!test_url.is_valid()) {
return false;
}
bool has_path = test_url.has_path() && test_url.path() != "/";
// Verify that it is a hostname.
if (!test_url.has_host() || has_path || test_url.has_port() ||
test_url.has_query() || test_url.has_password() ||
test_url.has_username() || test_url.has_ref()) {
return false;
}
bool match_prefix = false;
if (test_url.HostIsIPAddress()) {
// leading dots are not allowed for IP addresses. IP addresses are always
// exact match.
if (started_with_dot) {
return false;
}
match_prefix = false;
} else {
match_prefix = !started_with_dot;
}
InsertRuleToTrie(SplitHost(test_url), root, match_prefix);
return true;
}
void AddRules(const std::vector<std::string>& rules, TrieNode* root) {
for (auto rule : rules) {
if (!AddRuleToWhitelist(rule, root)) {
LOG(ERROR) << " Dropping invalid whitelist rule " << rule;
}
}
}
bool IsWhitelisted(const GURL& url, const TrieNode* node) {
std::vector<base::StringPiece> components = SplitHost(url);
for (auto component = components.rbegin(); component != components.rend();
++component) {
if (node->match_prefix) {
return true;
}
auto child_node = node->children.find(component->as_string());
if (child_node == node->children.end()) {
return false;
} else {
node = child_node->second.get();
DCHECK(node);
}
}
// DCHECK optimization. A match_prefix node should have no children.
DCHECK(!node->match_prefix || node->children.empty());
// If trie search finished in a terminal node, host is found in trie. The
// root node is not a terminal node.
return node->is_terminal;
}
} // namespace
AwSafeBrowsingWhitelistManager::AwSafeBrowsingWhitelistManager(
const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
: background_task_runner_(background_task_runner),
io_task_runner_(io_task_runner),
ui_task_runner_(base::ThreadTaskRunnerHandle::Get()),
whitelist_(base::MakeUnique<TrieNode>()) {}
AwSafeBrowsingWhitelistManager::~AwSafeBrowsingWhitelistManager() {}
void AwSafeBrowsingWhitelistManager::SetWhitelist(
std::unique_ptr<TrieNode> whitelist) {
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
whitelist_ = std::move(whitelist);
}
// A task that builds the whitelist on a background thread.
void AwSafeBrowsingWhitelistManager::BuildWhitelist(
const std::vector<std::string>& rules) {
DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
std::unique_ptr<TrieNode> whitelist(base::MakeUnique<TrieNode>());
AddRules(rules, whitelist.get());
DCHECK(!whitelist->is_terminal);
DCHECK(!whitelist->match_prefix);
// use base::Unretained as AwSafeBrowsingWhitelistManager is a singleton and
// not cleaned.
io_task_runner_->PostTask(
FROM_HERE,
base::Bind(&AwSafeBrowsingWhitelistManager::SetWhitelist,
base::Unretained(this), base::Passed(std::move(whitelist))));
}
void AwSafeBrowsingWhitelistManager::SetWhitelistOnUIThread(
std::vector<std::string>&& rules) {
DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
// use base::Unretained as AwSafeBrowsingWhitelistManager is a singleton and
// not cleaned.
background_task_runner_->PostTask(
FROM_HERE,
base::Bind(&AwSafeBrowsingWhitelistManager::BuildWhitelist,
base::Unretained(this), base::Passed(std::move(rules))));
}
bool AwSafeBrowsingWhitelistManager::IsURLWhitelisted(const GURL& url) const {
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
return IsWhitelisted(url, whitelist_.get());
}
} // namespace android_webview
// Copyright 2017 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 ANDROID_WEBVIEW_BROWSER_AW_SAFE_BROWSING_WHITELIST_MANAGER_H_
#define ANDROID_WEBVIEW_BROWSER_AW_SAFE_BROWSING_WHITELIST_MANAGER_H_
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "url/gurl.h"
namespace base {
class SequencedTaskRunner;
} // namespace base
namespace android_webview {
struct TrieNode;
// This class tracks the whitelisting policies for Safebrowsing. The class
// interacts with UI thread, where the whitelist is set, and then checks
// for the URLs in IO thread. The whitelisted entries are not checked for
// Safebrowsing.
//
// The class must be constructed on the UI thread.
//
// Update whitelist tasks from the UI thread are post to the IO thread.
//
// Encoding and the whitelisting rules:
// The whitelist is set in Java and plumbed to native through JNI, making
// them UTF-8 encoded wide strings.
//
// Each rule should take one of these:
// HOSTNAME
// .HOSTNAME
// IPV4_LITERAL
// IPV6_LITERAL_WITH_BRACKETS
//
// All other rules, including wildcards, are invalid.
//
// The hostname with a leading dot means an exact match, otherwise subdomains
// are also matched. This particular rule is similar to admiministration
// blacklist policy format:
// https://www.chromium.org/administrators/url-blacklist-filter-format
//
// The expected number of entries on the list should be 100s at most, however
// the size is not enforced here. The list size can be enforced at
// Java level if necessary.
//
class AwSafeBrowsingWhitelistManager {
public:
// Must be constructed on the UI thread.
// |background_task_runner| is used to build the filter list in a background
// thread.
// |io_task_runner| must be backed by the IO thread.
AwSafeBrowsingWhitelistManager(
const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
const scoped_refptr<base::SequencedTaskRunner>& io_task_runner);
virtual ~AwSafeBrowsingWhitelistManager();
// Returns true if |url| is whitelisted by the current whitelist. Must be
// called from the IO thread.
bool IsURLWhitelisted(const GURL& url) const;
// Replace the current host whitelist with a new one.
void SetWhitelistOnUIThread(std::vector<std::string>&& rules);
private:
// Builds whitelist on background thread.
void BuildWhitelist(const std::vector<std::string>& rules);
// Replaces the current whitelist. Must be called on the IO thread.
void SetWhitelist(std::unique_ptr<TrieNode> whitelist);
scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
std::unique_ptr<TrieNode> whitelist_;
DISALLOW_COPY_AND_ASSIGN(AwSafeBrowsingWhitelistManager);
};
} // namespace android_webview
#endif // ANDROID_WEBVIEW_BROWSER_AW_SAFE_BROWSING_WHITELIST_MANAGER_H_
......@@ -301,7 +301,8 @@ void AwResourceDispatcherHostDelegate::RequestBeginning(
AwSafeBrowsingResourceThrottle::MaybeCreate(
request, resource_type,
AwBrowserContext::GetDefault()->GetSafeBrowsingDBManager(),
AwBrowserContext::GetDefault()->GetSafeBrowsingUIManager());
AwBrowserContext::GetDefault()->GetSafeBrowsingUIManager(),
AwBrowserContext::GetDefault()->GetSafeBrowsingWhitelistManager());
if (throttle == nullptr) {
// Should not happen
DLOG(WARNING) << "Failed creating safebrowsing throttle";
......
......@@ -97,6 +97,10 @@ public class AwContentsStatics {
nativeSetSafeBrowsingEnabled(enable);
}
public static void setSafeBrowsingWhiteList(String[] urls) {
nativeSetSafeBrowsingWhiteList(urls);
}
@SuppressWarnings("unchecked")
@TargetApi(19)
public static void initSafeBrowsing(Context context, ValueCallback<Boolean> callback) {
......@@ -159,6 +163,7 @@ public class AwContentsStatics {
AwContentsIoThreadClient ioThreadClient, AwBrowserContext browserContext);
private static native boolean nativeGetSafeBrowsingEnabled();
private static native void nativeSetSafeBrowsingEnabled(boolean enable);
private static native void nativeSetSafeBrowsingWhiteList(String[] urls);
private static native void nativeSetCheckClearTextPermitted(boolean permitted);
private static native String nativeFindAddress(String addr);
}
......@@ -8,6 +8,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.support.test.filters.SmallTest;
import android.view.ViewGroup;
import android.webkit.ValueCallback;
......@@ -19,6 +20,7 @@ import org.chromium.android_webview.AwContents.InternalAccessDelegate;
import org.chromium.android_webview.AwContents.NativeDrawGLFunctorFactory;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwContentsClient.AwWebResourceRequest;
import org.chromium.android_webview.AwContentsStatics;
import org.chromium.android_webview.AwSafeBrowsingConversionHelper;
import org.chromium.android_webview.AwSafeBrowsingResponse;
import org.chromium.android_webview.AwSettings;
......@@ -262,7 +264,6 @@ public class SafeBrowsingTest extends AwTestBase {
public void setUp() throws Exception {
super.setUp();
mContentsClient = new SafeBrowsingContentsClient();
mContainerView = createAwTestContainerViewOnMainSync(
mContentsClient, false, new SafeBrowsingDependencyFactory());
mAwContents = (MockAwContents) mContainerView.getAwContents();
......@@ -434,6 +435,24 @@ public class SafeBrowsingTest extends AwTestBase {
// the target page
}
@SmallTest
@Feature({"AndroidWebView"})
@CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT)
public void testSafeBrowsingWhitelistedUnsafePagesDontShowInterstitial() throws Throwable {
loadGreenPage();
final String responseUrl = mTestServer.getURL(MALWARE_HTML_PATH);
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
String host = Uri.parse(responseUrl).getHost();
String[] s = new String[] {host};
AwContentsStatics.setSafeBrowsingWhiteList(s);
}
});
loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), responseUrl);
assertTargetPageHasLoaded(MALWARE_PAGE_BACKGROUND_COLOR);
}
@SmallTest
@Feature({"AndroidWebView"})
@CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT)
......
......@@ -258,6 +258,7 @@ test("android_webview_unittests") {
"../browser/aw_form_database_service_unittest.cc",
"../browser/aw_media_url_interceptor_unittest.cc",
"../browser/aw_permission_manager_unittest.cc",
"../browser/aw_safe_browsing_whitelist_manager_unittest.cc",
"../browser/aw_static_cookie_policy_unittest.cc",
"../browser/browser_view_renderer_unittest.cc",
"../browser/command_line_helper_unittest.cc",
......
......@@ -107,6 +107,11 @@ class BaseResourceThrottle
scoped_refptr<BaseUIManager> ui_manager,
const security_interstitials::UnsafeResource& resource);
// Starts running |url| through the safe browsing check. Returns true if the
// URL is safe to visit. Otherwise returns false and will call
// OnBrowseUrlResult() when the check has completed.
virtual bool CheckUrl(const GURL& url);
scoped_refptr<BaseUIManager> ui_manager();
private:
......@@ -136,11 +141,6 @@ class BaseResourceThrottle
scoped_refptr<BaseUIManager> ui_manager_;
// Starts running |url| through the safe browsing check. Returns true if the
// URL is safe to visit. Otherwise returns false and will call
// OnBrowseUrlResult() when the check has completed.
bool CheckUrl(const GURL& url);
// Callback for when the safe browsing check (which was initiated by
// StartCheckingUrl()) has taken longer than kCheckUrlTimeoutMs.
void OnCheckUrlTimeout();
......
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