blob: c09f9d820af38d57ceb434dedfb54a7e3a5cf092 [file] [log] [blame]
feltbc2eda2d2015-06-23 02:06:031// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
dcheng7bacc0e2016-04-11 20:10:545#include "chrome/browser/safe_browsing/ui_manager.h"
6
Sebastien Marchandf1349f52019-01-25 03:16:417#include "base/bind.h"
Carlos ILe7464b9c2020-01-18 01:38:308#include "base/bind_helpers.h"
clamy4edbf0e2015-12-02 13:35:419#include "base/run_loop.h"
Eric Seckler8652dcd52018-09-20 10:42:2810#include "base/task/post_task.h"
John Abd-El-Malek1b3f5ca2019-06-06 16:42:3211#include "chrome/browser/net/system_network_context_manager.h"
dalecurtis6c58ed02016-10-28 23:02:3712#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
Luke Zielinski12ef88552017-06-23 15:36:2713#include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
Findit86f6ae0fa2017-09-28 02:19:0114#include "chrome/browser/safe_browsing/ui_manager.h"
feltfb118572015-08-18 05:22:0115#include "chrome/test/base/chrome_render_view_host_test_harness.h"
John Abd-El-Malek1b3f5ca2019-06-06 16:42:3216#include "chrome/test/base/scoped_testing_local_state.h"
Luke Zielinski12ef88552017-06-23 15:36:2717#include "chrome/test/base/testing_browser_process.h"
feltfb118572015-08-18 05:22:0118#include "chrome/test/base/testing_profile.h"
Ali Jumafb3dc1f2020-01-07 17:33:4719#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
20#include "components/safe_browsing/core/db/util.h"
edwardjungd7395fb02017-05-12 23:13:2921#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
Eric Seckler8652dcd52018-09-20 10:42:2822#include "content/public/browser/browser_task_traits.h"
estark1ca09ca2016-11-01 04:04:1223#include "content/public/browser/navigation_entry.h"
Lukasz Anforowiczb55fc492017-10-02 18:38:3424#include "content/public/browser/render_frame_host.h"
feltfb118572015-08-18 05:22:0125#include "content/public/browser/render_process_host.h"
26#include "content/public/browser/render_view_host.h"
27#include "content/public/browser/web_contents.h"
dalecurtis6c58ed02016-10-28 23:02:3728#include "content/public/browser/web_contents_delegate.h"
Gabriel Charettec7108742019-08-23 03:31:4029#include "content/public/test/browser_task_environment.h"
clamy511cf022017-08-23 14:11:0630#include "content/public/test/navigation_simulator.h"
feltfb118572015-08-18 05:22:0131#include "content/public/test/web_contents_tester.h"
Helen Lifa36ad62018-06-01 19:52:5932#include "net/url_request/url_request_test_util.h"
feltbc2eda2d2015-06-23 02:06:0333#include "testing/gtest/include/gtest/gtest.h"
34#include "url/gurl.h"
35
clamy4edbf0e2015-12-02 13:35:4136using content::BrowserThread;
37
feltfb118572015-08-18 05:22:0138static const char* kGoodURL = "https://www.good.com";
39static const char* kBadURL = "https://www.malware.com";
40static const char* kBadURLWithPath = "https://www.malware.com/index.html";
mattmbfc4060d2015-12-18 23:11:3841static const char* kAnotherBadURL = "https://www.badware.com";
42static const char* kLandingURL = "https://www.landing.com";
feltfb118572015-08-18 05:22:0143
vakh9a474d832015-11-13 01:43:0944namespace safe_browsing {
45
clamy4edbf0e2015-12-02 13:35:4146class SafeBrowsingCallbackWaiter {
47 public:
48 SafeBrowsingCallbackWaiter() {}
49
50 bool callback_called() const { return callback_called_; }
51 bool proceed() const { return proceed_; }
52
53 void OnBlockingPageDone(bool proceed) {
54 DCHECK_CURRENTLY_ON(BrowserThread::UI);
55 callback_called_ = true;
56 proceed_ = proceed;
57 loop_.Quit();
58 }
59
60 void OnBlockingPageDoneOnIO(bool proceed) {
61 DCHECK_CURRENTLY_ON(BrowserThread::IO);
Sami Kyostilaad439ec2019-08-06 14:49:5262 base::PostTask(
Eric Seckler8652dcd52018-09-20 10:42:2863 FROM_HERE, {BrowserThread::UI},
tzikb5f84b82017-04-20 00:55:2864 base::BindOnce(&SafeBrowsingCallbackWaiter::OnBlockingPageDone,
65 base::Unretained(this), proceed));
clamy4edbf0e2015-12-02 13:35:4166 }
67
68 void WaitForCallback() {
69 DCHECK_CURRENTLY_ON(BrowserThread::UI);
70 loop_.Run();
71 }
72
73 private:
74 bool callback_called_ = false;
75 bool proceed_ = false;
76 base::RunLoop loop_;
77};
78
feltfb118572015-08-18 05:22:0179class SafeBrowsingUIManagerTest : public ChromeRenderViewHostTestHarness {
feltbc2eda2d2015-06-23 02:06:0380 public:
Gabriel Charettecc8362b2017-09-20 21:59:4081 SafeBrowsingUIManagerTest()
John Abd-El-Malek1b3f5ca2019-06-06 16:42:3282 : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {
kylecharb59c3d72019-10-29 05:26:2683 ui_manager_ = new SafeBrowsingUIManager(nullptr);
John Abd-El-Malek1b3f5ca2019-06-06 16:42:3284 }
feltfb118572015-08-18 05:22:0185
juncai1ee189bd2017-06-09 04:25:4386 ~SafeBrowsingUIManagerTest() override {}
feltbc2eda2d2015-06-23 02:06:0387
clamy4edbf0e2015-12-02 13:35:4188 void SetUp() override {
clamy4edbf0e2015-12-02 13:35:4189 ChromeRenderViewHostTestHarness::SetUp();
estark1ca09ca2016-11-01 04:04:1290 SafeBrowsingUIManager::CreateWhitelistForTesting(web_contents());
Luke Zielinski12ef88552017-06-23 15:36:2791
92 safe_browsing::TestSafeBrowsingServiceFactory sb_service_factory;
93 auto* safe_browsing_service =
94 sb_service_factory.CreateSafeBrowsingService();
95 TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(
96 safe_browsing_service);
97 g_browser_process->safe_browsing_service()->Initialize();
98 // A profile was created already but SafeBrowsingService wasn't around to
99 // get notified of it, so include that notification now.
Evan Stade44fb6e382019-10-05 00:43:43100 safe_browsing_service->OnProfileAdded(
101 Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
Ian Vollick381389a62019-06-26 16:49:40102 content::BrowserThread::RunAllPendingTasksOnThreadForTesting(
103 content::BrowserThread::IO);
clamy4edbf0e2015-12-02 13:35:41104 }
feltfb118572015-08-18 05:22:01105
Luke Zielinski12ef88552017-06-23 15:36:27106 void TearDown() override {
107 TestingBrowserProcess::GetGlobal()->safe_browsing_service()->ShutDown();
108 TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(nullptr);
John Abd-El-Malek1b3f5ca2019-06-06 16:42:32109
110 // Depends on LocalState from ChromeRenderViewHostTestHarness.
111 if (SystemNetworkContextManager::GetInstance())
112 SystemNetworkContextManager::DeleteInstance();
113
Luke Zielinski12ef88552017-06-23 15:36:27114 ChromeRenderViewHostTestHarness::TearDown();
115 }
feltfb118572015-08-18 05:22:01116
jialiul792a6662016-12-03 01:44:10117 bool IsWhitelisted(security_interstitials::UnsafeResource resource) {
feltbc2eda2d2015-06-23 02:06:03118 return ui_manager_->IsWhitelisted(resource);
119 }
120
jialiul792a6662016-12-03 01:44:10121 void AddToWhitelist(security_interstitials::UnsafeResource resource) {
estark1ca09ca2016-11-01 04:04:12122 ui_manager_->AddToWhitelistUrlSet(
123 SafeBrowsingUIManager::GetMainFrameWhitelistUrlForResourceForTesting(
124 resource),
estark7ffa8c62016-11-11 23:21:55125 web_contents(), false, resource.threat_type);
feltfb118572015-08-18 05:22:01126 }
127
jialiul792a6662016-12-03 01:44:10128 security_interstitials::UnsafeResource MakeUnsafeResource(
mattmbfc4060d2015-12-18 23:11:38129 const char* url,
130 bool is_subresource) {
jialiul792a6662016-12-03 01:44:10131 security_interstitials::UnsafeResource resource;
feltfb118572015-08-18 05:22:01132 resource.url = GURL(url);
mattmbfc4060d2015-12-18 23:11:38133 resource.is_subresource = is_subresource;
scottmg22e4f25a2016-08-15 21:09:03134 resource.web_contents_getter =
jialiul792a6662016-12-03 01:44:10135 security_interstitials::UnsafeResource::GetWebContentsGetter(
Lukasz Anforowiczb55fc492017-10-02 18:38:34136 web_contents()->GetMainFrame()->GetProcess()->GetID(),
scottmg22e4f25a2016-08-15 21:09:03137 web_contents()->GetMainFrame()->GetRoutingID());
feltfb118572015-08-18 05:22:01138 resource.threat_type = SB_THREAT_TYPE_URL_MALWARE;
139 return resource;
140 }
141
jialiul792a6662016-12-03 01:44:10142 security_interstitials::UnsafeResource MakeUnsafeResourceAndStartNavigation(
feltfb118572015-08-18 05:22:01143 const char* url) {
jialiul792a6662016-12-03 01:44:10144 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38145 MakeUnsafeResource(url, false /* is_subresource */);
feltfb118572015-08-18 05:22:01146
mattmbfc4060d2015-12-18 23:11:38147 // The WC doesn't have a URL without a navigation. A main-frame malware
148 // unsafe resource must be a pending navigation.
clamy511cf022017-08-23 14:11:06149 auto navigation = content::NavigationSimulator::CreateBrowserInitiated(
150 GURL(url), web_contents());
151 navigation->Start();
feltfb118572015-08-18 05:22:01152 return resource;
feltbc2eda2d2015-06-23 02:06:03153 }
154
clamy4edbf0e2015-12-02 13:35:41155 void SimulateBlockingPageDone(
jialiul792a6662016-12-03 01:44:10156 const std::vector<security_interstitials::UnsafeResource>& resources,
clamy4edbf0e2015-12-02 13:35:41157 bool proceed) {
estark1ca09ca2016-11-01 04:04:12158 GURL main_frame_url;
159 content::NavigationEntry* entry =
160 web_contents()->GetController().GetVisibleEntry();
161 if (entry)
162 main_frame_url = entry->GetURL();
163
164 ui_manager_->OnBlockingPageDone(resources, proceed, web_contents(),
165 main_frame_url);
clamy4edbf0e2015-12-02 13:35:41166 }
167
dalecurtis6c58ed02016-10-28 23:02:37168 protected:
169 SafeBrowsingUIManager* ui_manager() { return ui_manager_.get(); }
170
feltbc2eda2d2015-06-23 02:06:03171 private:
172 scoped_refptr<SafeBrowsingUIManager> ui_manager_;
John Abd-El-Malek1b3f5ca2019-06-06 16:42:32173 ScopedTestingLocalState scoped_testing_local_state_;
feltbc2eda2d2015-06-23 02:06:03174};
175
Marc Treib3d26e922017-08-14 16:58:26176// Leaks memory. https://crbug.com/755118
177#if defined(LEAK_SANITIZER)
178#define MAYBE_Whitelist DISABLED_Whitelist
179#else
180#define MAYBE_Whitelist Whitelist
181#endif
182TEST_F(SafeBrowsingUIManagerTest, MAYBE_Whitelist) {
jialiul792a6662016-12-03 01:44:10183 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38184 MakeUnsafeResourceAndStartNavigation(kBadURL);
feltbc2eda2d2015-06-23 02:06:03185 AddToWhitelist(resource);
186 EXPECT_TRUE(IsWhitelisted(resource));
187}
188
Marc Treib3d26e922017-08-14 16:58:26189// Leaks memory. https://crbug.com/755118
190#if defined(LEAK_SANITIZER)
191#define MAYBE_WhitelistIgnoresSitesNotAdded \
192 DISABLED_WhitelistIgnoresSitesNotAdded
193#else
194#define MAYBE_WhitelistIgnoresSitesNotAdded WhitelistIgnoresSitesNotAdded
195#endif
196TEST_F(SafeBrowsingUIManagerTest, MAYBE_WhitelistIgnoresSitesNotAdded) {
jialiul792a6662016-12-03 01:44:10197 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38198 MakeUnsafeResourceAndStartNavigation(kGoodURL);
feltbc2eda2d2015-06-23 02:06:03199 EXPECT_FALSE(IsWhitelisted(resource));
feltfb118572015-08-18 05:22:01200}
201
Marc Treib3d26e922017-08-14 16:58:26202// Leaks memory. https://crbug.com/755118
203#if defined(LEAK_SANITIZER)
204#define MAYBE_WhitelistRemembersThreatType DISABLED_WhitelistRemembersThreatType
205#else
206#define MAYBE_WhitelistRemembersThreatType WhitelistRemembersThreatType
207#endif
208TEST_F(SafeBrowsingUIManagerTest, MAYBE_WhitelistRemembersThreatType) {
jialiul792a6662016-12-03 01:44:10209 security_interstitials::UnsafeResource resource =
estark7ffa8c62016-11-11 23:21:55210 MakeUnsafeResourceAndStartNavigation(kBadURL);
211 AddToWhitelist(resource);
212 EXPECT_TRUE(IsWhitelisted(resource));
213 SBThreatType threat_type;
214 content::NavigationEntry* entry =
215 web_contents()->GetController().GetVisibleEntry();
216 ASSERT_TRUE(entry);
217 EXPECT_TRUE(ui_manager()->IsUrlWhitelistedOrPendingForWebContents(
218 resource.url, resource.is_subresource, entry,
219 resource.web_contents_getter.Run(), true, &threat_type));
220 EXPECT_EQ(resource.threat_type, threat_type);
221}
222
Marc Treib3d26e922017-08-14 16:58:26223// Leaks memory. https://crbug.com/755118
224#if defined(LEAK_SANITIZER)
225#define MAYBE_WhitelistIgnoresPath DISABLED_WhitelistIgnoresPath
226#else
227#define MAYBE_WhitelistIgnoresPath WhitelistIgnoresPath
228#endif
229TEST_F(SafeBrowsingUIManagerTest, MAYBE_WhitelistIgnoresPath) {
jialiul792a6662016-12-03 01:44:10230 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38231 MakeUnsafeResourceAndStartNavigation(kBadURL);
feltbc2eda2d2015-06-23 02:06:03232 AddToWhitelist(resource);
233 EXPECT_TRUE(IsWhitelisted(resource));
feltfb118572015-08-18 05:22:01234
mattmbfc4060d2015-12-18 23:11:38235 content::WebContentsTester::For(web_contents())->CommitPendingNavigation();
236
jialiul792a6662016-12-03 01:44:10237 security_interstitials::UnsafeResource resource_path =
mattmbfc4060d2015-12-18 23:11:38238 MakeUnsafeResourceAndStartNavigation(kBadURLWithPath);
feltfb118572015-08-18 05:22:01239 EXPECT_TRUE(IsWhitelisted(resource_path));
feltbc2eda2d2015-06-23 02:06:03240}
241
Marc Treib3d26e922017-08-14 16:58:26242// Leaks memory. https://crbug.com/755118
243#if defined(LEAK_SANITIZER)
244#define MAYBE_WhitelistIgnoresThreatType DISABLED_WhitelistIgnoresThreatType
245#else
246#define MAYBE_WhitelistIgnoresThreatType WhitelistIgnoresThreatType
247#endif
248TEST_F(SafeBrowsingUIManagerTest, MAYBE_WhitelistIgnoresThreatType) {
jialiul792a6662016-12-03 01:44:10249 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38250 MakeUnsafeResourceAndStartNavigation(kBadURL);
feltfb118572015-08-18 05:22:01251 AddToWhitelist(resource);
252 EXPECT_TRUE(IsWhitelisted(resource));
feltbc2eda2d2015-06-23 02:06:03253
jialiul792a6662016-12-03 01:44:10254 security_interstitials::UnsafeResource resource_phishing =
mattmbfc4060d2015-12-18 23:11:38255 MakeUnsafeResource(kBadURL, false /* is_subresource */);
feltfb118572015-08-18 05:22:01256 resource_phishing.threat_type = SB_THREAT_TYPE_URL_PHISHING;
257 EXPECT_TRUE(IsWhitelisted(resource_phishing));
feltbc2eda2d2015-06-23 02:06:03258}
259
Marc Treib3d26e922017-08-14 16:58:26260// Leaks memory. https://crbug.com/755118
261#if defined(LEAK_SANITIZER)
262#define MAYBE_WhitelistWithUnrelatedPendingLoad \
263 DISABLED_WhitelistWithUnrelatedPendingLoad
264#else
265#define MAYBE_WhitelistWithUnrelatedPendingLoad \
266 WhitelistWithUnrelatedPendingLoad
267#endif
268TEST_F(SafeBrowsingUIManagerTest, MAYBE_WhitelistWithUnrelatedPendingLoad) {
mattmbfc4060d2015-12-18 23:11:38269 // Commit load of landing page.
270 NavigateAndCommit(GURL(kLandingURL));
clamy511cf022017-08-23 14:11:06271 auto unrelated_navigation =
272 content::NavigationSimulator::CreateBrowserInitiated(GURL(kGoodURL),
273 web_contents());
mattmbfc4060d2015-12-18 23:11:38274 {
275 // Simulate subresource malware hit on the landing page.
jialiul792a6662016-12-03 01:44:10276 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38277 MakeUnsafeResource(kBadURL, true /* is_subresource */);
278
279 // Start pending load to unrelated site.
clamy511cf022017-08-23 14:11:06280 unrelated_navigation->Start();
mattmbfc4060d2015-12-18 23:11:38281
282 // Whitelist the resource on the landing page.
283 AddToWhitelist(resource);
284 EXPECT_TRUE(IsWhitelisted(resource));
285 }
286
287 // Commit the pending load of unrelated site.
clamy511cf022017-08-23 14:11:06288 unrelated_navigation->Commit();
mattmbfc4060d2015-12-18 23:11:38289 {
290 // The unrelated site is not on the whitelist, even if the same subresource
291 // was on it.
jialiul792a6662016-12-03 01:44:10292 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38293 MakeUnsafeResource(kBadURL, true /* is_subresource */);
294 EXPECT_FALSE(IsWhitelisted(resource));
295 }
296
297 // Navigate back to the original landing url.
298 NavigateAndCommit(GURL(kLandingURL));
299 {
jialiul792a6662016-12-03 01:44:10300 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38301 MakeUnsafeResource(kBadURL, true /* is_subresource */);
302 // Original resource url is whitelisted.
303 EXPECT_TRUE(IsWhitelisted(resource));
304 }
305 {
306 // A different malware subresource on the same page is also whitelisted.
307 // (The whitelist is by the page url, not the resource url.)
jialiul792a6662016-12-03 01:44:10308 security_interstitials::UnsafeResource resource2 =
mattmbfc4060d2015-12-18 23:11:38309 MakeUnsafeResource(kAnotherBadURL, true /* is_subresource */);
310 EXPECT_TRUE(IsWhitelisted(resource2));
311 }
312}
313
Evgenii Stepanov199c0132017-08-18 21:19:41314// Leaks memory. https://crbug.com/755118
315#if defined(LEAK_SANITIZER)
316#define MAYBE_UICallbackProceed DISABLED_UICallbackProceed
317#else
318#define MAYBE_UICallbackProceed UICallbackProceed
319#endif
320TEST_F(SafeBrowsingUIManagerTest, MAYBE_UICallbackProceed) {
jialiul792a6662016-12-03 01:44:10321 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38322 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41323 SafeBrowsingCallbackWaiter waiter;
324 resource.callback =
325 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone,
326 base::Unretained(&waiter));
327 resource.callback_thread =
Sami Kyostilaad439ec2019-08-06 14:49:52328 base::CreateSingleThreadTaskRunner({BrowserThread::UI});
jialiul792a6662016-12-03 01:44:10329 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41330 resources.push_back(resource);
331 SimulateBlockingPageDone(resources, true);
332 EXPECT_TRUE(IsWhitelisted(resource));
333 waiter.WaitForCallback();
334 EXPECT_TRUE(waiter.callback_called());
335 EXPECT_TRUE(waiter.proceed());
336}
337
Evgenii Stepanov199c0132017-08-18 21:19:41338// Leaks memory. https://crbug.com/755118
339#if defined(LEAK_SANITIZER)
340#define MAYBE_UICallbackDontProceed DISABLED_UICallbackDontProceed
341#else
342#define MAYBE_UICallbackDontProceed UICallbackDontProceed
343#endif
344TEST_F(SafeBrowsingUIManagerTest, MAYBE_UICallbackDontProceed) {
jialiul792a6662016-12-03 01:44:10345 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38346 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41347 SafeBrowsingCallbackWaiter waiter;
348 resource.callback =
349 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone,
350 base::Unretained(&waiter));
351 resource.callback_thread =
Sami Kyostilaad439ec2019-08-06 14:49:52352 base::CreateSingleThreadTaskRunner({BrowserThread::UI});
jialiul792a6662016-12-03 01:44:10353 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41354 resources.push_back(resource);
355 SimulateBlockingPageDone(resources, false);
356 EXPECT_FALSE(IsWhitelisted(resource));
357 waiter.WaitForCallback();
358 EXPECT_TRUE(waiter.callback_called());
359 EXPECT_FALSE(waiter.proceed());
360}
361
Evgenii Stepanov199c0132017-08-18 21:19:41362// Leaks memory. https://crbug.com/755118
363#if defined(LEAK_SANITIZER)
364#define MAYBE_IOCallbackProceed DISABLED_IOCallbackProceed
365#else
366#define MAYBE_IOCallbackProceed IOCallbackProceed
367#endif
368TEST_F(SafeBrowsingUIManagerTest, MAYBE_IOCallbackProceed) {
jialiul792a6662016-12-03 01:44:10369 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38370 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41371 SafeBrowsingCallbackWaiter waiter;
372 resource.callback =
373 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO,
374 base::Unretained(&waiter));
375 resource.callback_thread =
Sami Kyostilaad439ec2019-08-06 14:49:52376 base::CreateSingleThreadTaskRunner({BrowserThread::IO});
jialiul792a6662016-12-03 01:44:10377 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41378 resources.push_back(resource);
379 SimulateBlockingPageDone(resources, true);
380 EXPECT_TRUE(IsWhitelisted(resource));
381 waiter.WaitForCallback();
382 EXPECT_TRUE(waiter.callback_called());
383 EXPECT_TRUE(waiter.proceed());
384}
385
Evgenii Stepanov199c0132017-08-18 21:19:41386// Leaks memory. https://crbug.com/755118
387#if defined(LEAK_SANITIZER)
388#define MAYBE_IOCallbackDontProceed DISABLED_IOCallbackDontProceed
389#else
390#define MAYBE_IOCallbackDontProceed IOCallbackDontProceed
391#endif
392TEST_F(SafeBrowsingUIManagerTest, MAYBE_IOCallbackDontProceed) {
jialiul792a6662016-12-03 01:44:10393 security_interstitials::UnsafeResource resource =
mattmbfc4060d2015-12-18 23:11:38394 MakeUnsafeResourceAndStartNavigation(kBadURL);
clamy4edbf0e2015-12-02 13:35:41395 SafeBrowsingCallbackWaiter waiter;
396 resource.callback =
397 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO,
398 base::Unretained(&waiter));
399 resource.callback_thread =
Sami Kyostilaad439ec2019-08-06 14:49:52400 base::CreateSingleThreadTaskRunner({BrowserThread::IO});
jialiul792a6662016-12-03 01:44:10401 std::vector<security_interstitials::UnsafeResource> resources;
clamy4edbf0e2015-12-02 13:35:41402 resources.push_back(resource);
403 SimulateBlockingPageDone(resources, false);
404 EXPECT_FALSE(IsWhitelisted(resource));
405 waiter.WaitForCallback();
406 EXPECT_TRUE(waiter.callback_called());
407 EXPECT_FALSE(waiter.proceed());
408}
409
dalecurtis6c58ed02016-10-28 23:02:37410namespace {
411
412// A WebContentsDelegate that records whether
413// VisibleSecurityStateChanged() was called.
414class SecurityStateWebContentsDelegate : public content::WebContentsDelegate {
415 public:
416 SecurityStateWebContentsDelegate() {}
417 ~SecurityStateWebContentsDelegate() override {}
418
419 bool visible_security_state_changed() const {
420 return visible_security_state_changed_;
421 }
422
423 void ClearVisibleSecurityStateChanged() {
424 visible_security_state_changed_ = false;
425 }
426
427 // WebContentsDelegate:
428 void VisibleSecurityStateChanged(content::WebContents* source) override {
429 visible_security_state_changed_ = true;
430 }
431
432 private:
433 bool visible_security_state_changed_ = false;
434 DISALLOW_COPY_AND_ASSIGN(SecurityStateWebContentsDelegate);
435};
436
437// A test blocking page that does not create windows.
438class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage {
439 public:
jialiul3d6032e2017-01-12 00:41:31440 TestSafeBrowsingBlockingPage(BaseUIManager* manager,
dalecurtis6c58ed02016-10-28 23:02:37441 content::WebContents* web_contents,
442 const GURL& main_frame_url,
443 const UnsafeResourceList& unsafe_resources)
jialiul3d6032e2017-01-12 00:41:31444 : SafeBrowsingBlockingPage(
445 manager,
446 web_contents,
447 main_frame_url,
448 unsafe_resources,
edwardjungd7395fb02017-05-12 23:13:29449 BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
ntfschra5448fa2017-02-02 01:01:31450 BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources),
Carlos IL43dfc262019-11-27 19:40:31451 false, // is_extended_reporting_opt_in_allowed
452 false, // is_off_the_record
453 false, // is_extended_reporting_enabled
454 false, // is_extended_reporting_policy_managed
455 false, // is_proceed_anyway_disabled
456 true, // should_open_links_in_new_tab
457 true, // always_show_back_to_safety
458 "cpn_safe_browsing"), // help_center_article_link
459 true) { // should_trigger_reporting
dalecurtis6c58ed02016-10-28 23:02:37460 // Don't delay details at all for the unittest.
ntfschrfef42f92017-02-24 02:15:47461 SetThreatDetailsProceedDelayForTesting(0);
dalecurtis6c58ed02016-10-28 23:02:37462 DontCreateViewForTesting();
463 }
464};
465
466// A factory that creates TestSafeBrowsingBlockingPages.
467class TestSafeBrowsingBlockingPageFactory
468 : public SafeBrowsingBlockingPageFactory {
469 public:
470 TestSafeBrowsingBlockingPageFactory() {}
471 ~TestSafeBrowsingBlockingPageFactory() override {}
472
473 SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
jialiul3d6032e2017-01-12 00:41:31474 BaseUIManager* delegate,
dalecurtis6c58ed02016-10-28 23:02:37475 content::WebContents* web_contents,
476 const GURL& main_frame_url,
Carlos IL43dfc262019-11-27 19:40:31477 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources,
478 bool should_trigger_reporting) override {
dalecurtis6c58ed02016-10-28 23:02:37479 return new TestSafeBrowsingBlockingPage(delegate, web_contents,
480 main_frame_url, unsafe_resources);
481 }
482};
483
484} // namespace
485
486// Tests that the WebContentsDelegate is notified of a visible security
487// state change when a blocking page is shown for a subresource.
Evgenii Stepanov199c0132017-08-18 21:19:41488// Leaks memory. https://crbug.com/755118
489#if defined(LEAK_SANITIZER)
490#define MAYBE_VisibleSecurityStateChangedForUnsafeSubresource \
491 DISABLED_VisibleSecurityStateChangedForUnsafeSubresource
492#else
493#define MAYBE_VisibleSecurityStateChangedForUnsafeSubresource \
494 VisibleSecurityStateChangedForUnsafeSubresource
495#endif
dalecurtis6c58ed02016-10-28 23:02:37496TEST_F(SafeBrowsingUIManagerTest,
Evgenii Stepanov199c0132017-08-18 21:19:41497 MAYBE_VisibleSecurityStateChangedForUnsafeSubresource) {
dalecurtis6c58ed02016-10-28 23:02:37498 TestSafeBrowsingBlockingPageFactory factory;
499 SafeBrowsingBlockingPage::RegisterFactory(&factory);
500 SecurityStateWebContentsDelegate delegate;
501 web_contents()->SetDelegate(&delegate);
502
503 // Simulate a blocking page showing for an unsafe subresource.
jialiul792a6662016-12-03 01:44:10504 security_interstitials::UnsafeResource resource =
dalecurtis6c58ed02016-10-28 23:02:37505 MakeUnsafeResource(kBadURL, true /* is_subresource */);
506 // Needed for showing the blocking page.
507 resource.threat_source = safe_browsing::ThreatSource::REMOTE;
Carlos ILe7464b9c2020-01-18 01:38:30508
509 // The callback needs to be set for committed interstitials, just set it to do
510 // nothing.
511 resource.callback = base::DoNothing();
512 resource.callback_thread =
513 base::CreateSingleThreadTaskRunner({BrowserThread::IO});
514
dalecurtis6c58ed02016-10-28 23:02:37515 NavigateAndCommit(GURL("http://example.test"));
516
517 delegate.ClearVisibleSecurityStateChanged();
518 EXPECT_FALSE(delegate.visible_security_state_changed());
519 ui_manager()->DisplayBlockingPage(resource);
520 EXPECT_TRUE(delegate.visible_security_state_changed());
521
522 // Simulate proceeding through the blocking page.
523 SafeBrowsingCallbackWaiter waiter;
524 resource.callback =
525 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO,
526 base::Unretained(&waiter));
527 resource.callback_thread =
Sami Kyostilaad439ec2019-08-06 14:49:52528 base::CreateSingleThreadTaskRunner({BrowserThread::IO});
jialiul792a6662016-12-03 01:44:10529 std::vector<security_interstitials::UnsafeResource> resources;
dalecurtis6c58ed02016-10-28 23:02:37530 resources.push_back(resource);
531
532 delegate.ClearVisibleSecurityStateChanged();
533 EXPECT_FALSE(delegate.visible_security_state_changed());
534 SimulateBlockingPageDone(resources, true);
535 EXPECT_TRUE(delegate.visible_security_state_changed());
536
537 waiter.WaitForCallback();
538 EXPECT_TRUE(waiter.callback_called());
539 EXPECT_TRUE(waiter.proceed());
540 EXPECT_TRUE(IsWhitelisted(resource));
541}
542
vakh9a474d832015-11-13 01:43:09543} // namespace safe_browsing