Commit fc29229e authored by Tim Volodine's avatar Tim Volodine Committed by Commit Bot

[WebLayer] Add support for committed interstitials for safebrowsing

Currently committed safebrowsing interstitials are not supported
in weblayer. This patch adds this support and tests.

In this patch:
 - add support for committed interstitials for safebrowsing in
   weblayer (i.e. when kCommittedSBInterstitials is enabled).
 - add SafeBrowsingBlockingPage and SafeBrowsingNavigationThrottle
 - make SafeBrowsingBrowserTest work when kCommittedSBInterstitials
   feature is enabled.
 - parameterize tests to run both with committed interstitials and
   non-committed interstitials.

BUG=1042662
TBR=vakh@chromium.org

Change-Id: I5f732c1f0c2c6c09b2041ea0a7c8d41e81bce9d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2003857
Commit-Queue: Tim Volodine <timvolodine@chromium.org>
Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#734515}
parent 10be3096
......@@ -207,6 +207,7 @@ jumbo_static_library("weblayer_lib") {
"//components/embedder_support",
"//components/network_time",
"//components/prefs",
"//components/safe_browsing/core:features",
"//components/security_interstitials/content:security_interstitial_page",
"//components/security_interstitials/content/renderer:security_interstitial_page_controller",
"//components/security_interstitials/core",
......
......@@ -12,6 +12,7 @@ include_rules = [
"+components/prefs",
"+components/user_prefs",
"+components/safe_browsing/core/common",
"+components/safe_browsing/core/features.h",
"+components/security_interstitials",
"+components/sessions",
"+components/spellcheck/browser",
......
......@@ -14,6 +14,7 @@
#include "build/build_config.h"
#include "components/autofill/content/browser/content_autofill_driver_factory.h"
#include "components/embedder_support/switches.h"
#include "components/safe_browsing/core/features.h"
#include "components/security_interstitials/content/ssl_cert_reporter.h"
#include "components/security_interstitials/content/ssl_error_navigation_throttle.h"
#include "components/version_info/version_info.h"
......@@ -342,6 +343,15 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation(
throttles.push_back(std::make_unique<SSLErrorNavigationThrottle>(
handle, std::make_unique<SSLCertReporterImpl>(),
base::BindOnce(&HandleSSLError), base::BindOnce(&IsInHostedApp)));
#if defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing) &&
base::FeatureList::IsEnabled(safe_browsing::kCommittedSBInterstitials) &&
IsSafebrowsingSupported()) {
throttles.push_back(
GetSafeBrowsingService()->CreateSafeBrowsingNavigationThrottle(handle));
}
#endif
return throttles;
}
......
......@@ -8,6 +8,10 @@ assert(is_android)
source_set("safe_browsing") {
sources = [
"safe_browsing_blocking_page.cc",
"safe_browsing_blocking_page.h",
"safe_browsing_navigation_throttle.cc",
"safe_browsing_navigation_throttle.h",
"safe_browsing_service.cc",
"safe_browsing_service.h",
"safe_browsing_ui_manager.cc",
......@@ -25,6 +29,7 @@ source_set("safe_browsing") {
"//components/safe_browsing/core/browser:network_context",
"//components/safe_browsing/core/common",
"//components/safe_browsing/core/db:database_manager",
"//components/security_interstitials/core/",
"//content/public/browser",
"//skia",
"//third_party/blink/public/common",
......
// 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 "weblayer/browser/safe_browsing/safe_browsing_blocking_page.h"
#include "components/security_interstitials/content/security_interstitial_controller_client.h"
#include "content/public/browser/navigation_entry.h"
#include "weblayer/browser/safe_browsing/safe_browsing_ui_manager.h"
namespace weblayer {
SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
SafeBrowsingUIManager* ui_manager,
content::WebContents* web_contents,
const GURL& main_frame_url,
const UnsafeResourceList& unsafe_resources,
std::unique_ptr<
security_interstitials::SecurityInterstitialControllerClient>
controller_client,
const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options)
: BaseBlockingPage(ui_manager,
web_contents,
main_frame_url,
unsafe_resources,
std::move(controller_client),
display_options) {}
SafeBrowsingBlockingPage* SafeBrowsingBlockingPage::CreateBlockingPage(
SafeBrowsingUIManager* ui_manager,
content::WebContents* web_contents,
const GURL& main_frame_url,
const UnsafeResource& unsafe_resource) {
const UnsafeResourceList unsafe_resources{unsafe_resource};
content::NavigationEntry* entry =
unsafe_resource.GetNavigationEntryForResource();
GURL url =
(main_frame_url.is_empty() && entry) ? entry->GetURL() : main_frame_url;
return new SafeBrowsingBlockingPage(
ui_manager, web_contents, url, unsafe_resources,
CreateControllerClient(web_contents, unsafe_resources, ui_manager,
nullptr /*pref_service*/),
BaseBlockingPage::CreateDefaultDisplayOptions(unsafe_resources));
}
} // namespace weblayer
// 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 WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_
#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_
#include <memory>
#include "components/safe_browsing/content/base_blocking_page.h"
#include "components/security_interstitials/content/unsafe_resource.h"
#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
namespace content {
class WebContents;
} // namespace content
namespace weblayer {
class SafeBrowsingUIManager;
class SafeBrowsingBlockingPage : public safe_browsing::BaseBlockingPage {
public:
typedef security_interstitials::UnsafeResource UnsafeResource;
static SafeBrowsingBlockingPage* CreateBlockingPage(
SafeBrowsingUIManager* ui_manager,
content::WebContents* web_contents,
const GURL& main_frame_url,
const UnsafeResource& unsafe_resource);
private:
SafeBrowsingBlockingPage(
SafeBrowsingUIManager* ui_manager,
content::WebContents* web_contents,
const GURL& main_frame_url,
const UnsafeResourceList& unsafe_resources,
std::unique_ptr<
security_interstitials::SecurityInterstitialControllerClient>
controller_client,
const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options);
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_
......@@ -5,9 +5,12 @@
#include <map>
#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "components/safe_browsing/android/safe_browsing_api_handler.h"
#include "components/safe_browsing/content/base_blocking_page.h"
#include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
#include "components/safe_browsing/core/features.h"
#include "components/security_interstitials/content/security_interstitial_tab_helper.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/interstitial_page.h"
......@@ -73,9 +76,18 @@ class FakeSafeBrowsingApiHandler
std::map<GURL, safe_browsing::SBThreatType> restrictions_;
};
class SafeBrowsingBrowserTest : public WebLayerBrowserTest {
class SafeBrowsingBrowserTest : public WebLayerBrowserTest,
public ::testing::WithParamInterface<bool> {
public:
SafeBrowsingBrowserTest() : fake_handler_(new FakeSafeBrowsingApiHandler()) {}
SafeBrowsingBrowserTest() : fake_handler_(new FakeSafeBrowsingApiHandler()) {
if (GetParam()) {
feature_list_.InitAndEnableFeature(
safe_browsing::kCommittedSBInterstitials);
} else {
feature_list_.InitAndDisableFeature(
safe_browsing::kCommittedSBInterstitials);
}
}
~SafeBrowsingBrowserTest() override = default;
// WebLayerBrowserTest:
......@@ -98,7 +110,8 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest {
load_observer.Wait();
EXPECT_EQ(expect_interstitial, HasInterstitial());
if (expect_interstitial) {
EXPECT_TRUE(GetBaseBlockingPage()->GetHTMLContents().length() > 0);
EXPECT_TRUE(GetSecurityInterstitialPage()->GetHTMLContents().length() >
0);
}
}
......@@ -109,48 +122,65 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest {
return tab_impl->web_contents();
}
content::InterstitialPage* GetInterstitialPage() {
return GetWebContents()->GetInterstitialPage();
}
security_interstitials::SecurityInterstitialPage*
GetSecurityInterstitialPage() {
if (base::FeatureList::IsEnabled(
safe_browsing::kCommittedSBInterstitials)) {
security_interstitials::SecurityInterstitialTabHelper* helper =
security_interstitials::SecurityInterstitialTabHelper::
FromWebContents(GetWebContents());
return helper
? helper
->GetBlockingPageForCurrentlyCommittedNavigationForTesting()
: nullptr;
}
safe_browsing::BaseBlockingPage* GetBaseBlockingPage() {
return static_cast<safe_browsing::BaseBlockingPage*>(
return static_cast<security_interstitials::SecurityInterstitialPage*>(
content::InterstitialPage::GetInterstitialPage(GetWebContents())
->GetDelegateForTesting());
}
bool HasInterstitial() { return GetInterstitialPage() != nullptr; }
bool HasBaseBlockingPage() { return GetBaseBlockingPage() != nullptr; }
bool HasInterstitial() {
if (base::FeatureList::IsEnabled(
safe_browsing::kCommittedSBInterstitials)) {
return GetSecurityInterstitialPage() != nullptr;
}
return GetWebContents()->GetInterstitialPage() != nullptr;
}
std::unique_ptr<FakeSafeBrowsingApiHandler> fake_handler_;
GURL url_;
base::test::ScopedFeatureList feature_list_;
private:
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBrowserTest);
};
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
INSTANTIATE_TEST_SUITE_P(All, SafeBrowsingBrowserTest, ::testing::Bool());
IN_PROC_BROWSER_TEST_P(SafeBrowsingBrowserTest,
DoesNotShowInterstitial_NoRestriction) {
Navigate(url_, false);
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, DoesNotShowInterstitial_Safe) {
IN_PROC_BROWSER_TEST_P(SafeBrowsingBrowserTest, DoesNotShowInterstitial_Safe) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false);
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Malware) {
IN_PROC_BROWSER_TEST_P(SafeBrowsingBrowserTest, ShowsInterstitial_Malware) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, true);
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Phishing) {
IN_PROC_BROWSER_TEST_P(SafeBrowsingBrowserTest, ShowsInterstitial_Phishing) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, true);
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Unwanted) {
IN_PROC_BROWSER_TEST_P(SafeBrowsingBrowserTest, ShowsInterstitial_Unwanted) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, true);
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Billing) {
IN_PROC_BROWSER_TEST_P(SafeBrowsingBrowserTest, ShowsInterstitial_Billing) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_BILLING, true);
}
......
// 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 "weblayer/browser/safe_browsing/safe_browsing_navigation_throttle.h"
#include "components/security_interstitials/content/security_interstitial_tab_helper.h"
#include "components/security_interstitials/content/unsafe_resource.h"
#include "content/public/browser/navigation_handle.h"
#include "weblayer/browser/safe_browsing/safe_browsing_blocking_page.h"
#include "weblayer/browser/safe_browsing/safe_browsing_service.h"
#include "weblayer/browser/safe_browsing/safe_browsing_ui_manager.h"
namespace weblayer {
SafeBrowsingNavigationThrottle::SafeBrowsingNavigationThrottle(
content::NavigationHandle* handle,
SafeBrowsingUIManager* ui_manager)
: content::NavigationThrottle(handle), ui_manager_(ui_manager) {}
const char* SafeBrowsingNavigationThrottle::GetNameForLogging() {
return "SafeBrowsingNavigationThrottle";
}
content::NavigationThrottle::ThrottleCheckResult
SafeBrowsingNavigationThrottle::WillFailRequest() {
if (ui_manager_) {
security_interstitials::UnsafeResource resource;
content::NavigationHandle* handle = navigation_handle();
if (ui_manager_->PopUnsafeResourceForURL(handle->GetURL(), &resource)) {
SafeBrowsingBlockingPage* blocking_page =
SafeBrowsingBlockingPage::CreateBlockingPage(
ui_manager_, handle->GetWebContents(), handle->GetURL(),
resource);
std::string error_page_content = blocking_page->GetHTMLContents();
security_interstitials::SecurityInterstitialTabHelper::
AssociateBlockingPage(handle->GetWebContents(),
handle->GetNavigationId(),
base::WrapUnique(blocking_page));
return content::NavigationThrottle::ThrottleCheckResult(
CANCEL, net::ERR_BLOCKED_BY_CLIENT, error_page_content);
}
}
return content::NavigationThrottle::PROCEED;
}
} // namespace weblayer
// 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 WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_THROTTLE_H_
#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_THROTTLE_H_
#include "content/public/browser/navigation_throttle.h"
namespace content {
class NavigationHandle;
} // namespace content
namespace weblayer {
class SafeBrowsingUIManager;
class SafeBrowsingNavigationThrottle : public content::NavigationThrottle {
public:
SafeBrowsingNavigationThrottle(content::NavigationHandle* handle,
SafeBrowsingUIManager* ui_manager);
~SafeBrowsingNavigationThrottle() override {}
const char* GetNameForLogging() override;
content::NavigationThrottle::ThrottleCheckResult WillFailRequest() override;
private:
SafeBrowsingUIManager* ui_manager_;
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_THROTTLE_H_
\ No newline at end of file
......@@ -19,6 +19,7 @@
#include "content/public/browser/resource_context.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "weblayer/browser/safe_browsing/safe_browsing_navigation_throttle.h"
#include "weblayer/browser/safe_browsing/url_checker_delegate_impl.h"
namespace weblayer {
......@@ -86,6 +87,13 @@ SafeBrowsingService::CreateURLLoaderThrottle(
/*cache_manager*/ nullptr);
}
std::unique_ptr<content::NavigationThrottle>
SafeBrowsingService::CreateSafeBrowsingNavigationThrottle(
content::NavigationHandle* handle) {
return std::make_unique<SafeBrowsingNavigationThrottle>(
handle, GetSafeBrowsingUIManager());
}
scoped_refptr<safe_browsing::UrlCheckerDelegate>
SafeBrowsingService::GetSafeBrowsingUrlCheckerDelegate() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
......
......@@ -14,6 +14,8 @@
#include "weblayer/browser/safe_browsing/safe_browsing_ui_manager.h"
namespace content {
class NavigationHandle;
class NavigationThrottle;
class RenderProcessHost;
}
......@@ -47,6 +49,8 @@ class SafeBrowsingService {
std::unique_ptr<blink::URLLoaderThrottle> CreateURLLoaderThrottle(
const base::RepeatingCallback<content::WebContents*()>& wc_getter,
int frame_tree_node_id);
std::unique_ptr<content::NavigationThrottle>
CreateSafeBrowsingNavigationThrottle(content::NavigationHandle* handle);
void AddInterface(service_manager::BinderRegistry* registry,
content::RenderProcessHost* render_process_host);
......
......@@ -128,6 +128,7 @@ test("weblayer_browsertests") {
"//android_webview:pak_file_assets",
"//components/safe_browsing/android:safe_browsing_api_handler",
"//components/safe_browsing/content",
"//components/safe_browsing/core:features",
"//components/viz/service:service_java",
"//content/public/test/android:android_test_message_pump_support_java",
"//content/test:android_test_message_pump_support",
......
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