[Sync] Rename PSS::IsSyncEnabled to PSS::IsSyncAllowedByFlag.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_blocking_page_test.cc
blob03e229e0dc40101992d95d1a0c974f520971fb1f
1 // Copyright (c) 2012 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 //
5 // This test creates a fake safebrowsing service, where we can inject known-
6 // threat urls. It then uses a real browser to go to these urls, and sends
7 // "goback" or "proceed" commands and verifies they work.
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/safe_browsing/database_manager.h"
19 #include "chrome/browser/safe_browsing/local_database_manager.h"
20 #include "chrome/browser/safe_browsing/malware_details.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
22 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
23 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
24 #include "chrome/browser/safe_browsing/test_database_manager.h"
25 #include "chrome/browser/safe_browsing/ui_manager.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_tabstrip.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/test/base/in_process_browser_test.h"
33 #include "chrome/test/base/test_switches.h"
34 #include "chrome/test/base/ui_test_utils.h"
35 #include "content/public/browser/interstitial_page.h"
36 #include "content/public/browser/navigation_controller.h"
37 #include "content/public/browser/notification_types.h"
38 #include "content/public/browser/render_frame_host.h"
39 #include "content/public/browser/render_process_host.h"
40 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/web_contents.h"
42 #include "content/public/test/browser_test_utils.h"
43 #include "content/public/test/test_browser_thread.h"
44 #include "content/public/test/test_utils.h"
46 using chrome_browser_interstitials::SecurityInterstitialIDNTest;
47 using content::BrowserThread;
48 using content::InterstitialPage;
49 using content::NavigationController;
50 using content::WebContents;
52 namespace {
54 const char kEmptyPage[] = "files/empty.html";
55 const char kMalwarePage[] = "files/safe_browsing/malware.html";
56 const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html";
58 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious
59 // URLs.
60 class FakeSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager {
61 public:
62 FakeSafeBrowsingDatabaseManager() {}
64 // Called on the IO thread to check if the given url is safe or not. If we
65 // can synchronously determine that the url is safe, CheckUrl returns true.
66 // Otherwise it returns false, and "client" is called asynchronously with the
67 // result when it is ready.
68 // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
69 bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
70 if (badurls[gurl.spec()] == SB_THREAT_TYPE_SAFE)
71 return true;
73 BrowserThread::PostTask(
74 BrowserThread::IO, FROM_HERE,
75 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
76 this, gurl, client));
77 return false;
80 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
81 std::vector<SBThreatType> expected_threats;
82 // TODO(nparker): Remove ref to LocalSafeBrowsingDatabase by calling
83 // client->OnCheckBrowseUrlResult(..) directly.
84 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
85 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
86 expected_threats.push_back(SB_THREAT_TYPE_URL_UNWANTED);
87 LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
88 std::vector<GURL>(1, gurl),
89 std::vector<SBFullHash>(),
90 client,
91 safe_browsing_util::MALWARE,
92 expected_threats);
93 sb_check.url_results[0] = badurls[gurl.spec()];
94 sb_check.OnSafeBrowsingResult();
97 void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
98 badurls[url.spec()] = threat_type;
101 // Called during startup, so must not check-fail.
102 bool CheckExtensionIDs(const std::set<std::string>& extension_ids,
103 Client* client) override {
104 return true;
107 private:
108 ~FakeSafeBrowsingDatabaseManager() override {}
110 base::hash_map<std::string, SBThreatType> badurls;
111 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
114 // A SafeBrowingUIManager class that allows intercepting malware details.
115 class FakeSafeBrowsingUIManager : public SafeBrowsingUIManager {
116 public:
117 explicit FakeSafeBrowsingUIManager(SafeBrowsingService* service) :
118 SafeBrowsingUIManager(service) { }
120 // Overrides SafeBrowsingUIManager
121 void SendSerializedMalwareDetails(const std::string& serialized) override {
122 // Notify the UI thread that we got a report.
123 BrowserThread::PostTask(
124 BrowserThread::UI,
125 FROM_HERE,
126 base::Bind(&FakeSafeBrowsingUIManager::OnMalwareDetailsDone,
127 this,
128 serialized));
131 void OnMalwareDetailsDone(const std::string& serialized) {
132 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
133 report_ = serialized;
135 EXPECT_FALSE(malware_details_done_callback_.is_null());
136 if (!malware_details_done_callback_.is_null()) {
137 malware_details_done_callback_.Run();
138 malware_details_done_callback_ = base::Closure();
142 void set_malware_details_done_callback(const base::Closure& callback) {
143 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
144 EXPECT_TRUE(malware_details_done_callback_.is_null());
145 malware_details_done_callback_ = callback;
148 std::string GetReport() {
149 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
150 return report_;
153 protected:
154 ~FakeSafeBrowsingUIManager() override {}
156 private:
157 std::string report_;
158 base::Closure malware_details_done_callback_;
160 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager);
163 class FakeSafeBrowsingService : public SafeBrowsingService {
164 public:
165 FakeSafeBrowsingService()
166 : fake_database_manager_(),
167 fake_ui_manager_() { }
169 // Returned pointer has the same lifespan as the database_manager_ refcounted
170 // object.
171 FakeSafeBrowsingDatabaseManager* fake_database_manager() {
172 return fake_database_manager_;
174 // Returned pointer has the same lifespan as the ui_manager_ refcounted
175 // object.
176 FakeSafeBrowsingUIManager* fake_ui_manager() {
177 return fake_ui_manager_;
180 protected:
181 ~FakeSafeBrowsingService() override {}
183 SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
184 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager();
185 return fake_database_manager_;
188 SafeBrowsingUIManager* CreateUIManager() override {
189 fake_ui_manager_ = new FakeSafeBrowsingUIManager(this);
190 return fake_ui_manager_;
193 SafeBrowsingProtocolManagerDelegate* GetProtocolManagerDelegate() override {
194 // Our SafeBrowsingDatabaseManager doesn't implement this delegate.
195 return NULL;
198 private:
199 FakeSafeBrowsingDatabaseManager* fake_database_manager_;
200 FakeSafeBrowsingUIManager* fake_ui_manager_;
202 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
205 // Factory that creates FakeSafeBrowsingService instances.
206 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
207 public:
208 TestSafeBrowsingServiceFactory() :
209 most_recent_service_(NULL) { }
210 ~TestSafeBrowsingServiceFactory() override {}
212 SafeBrowsingService* CreateSafeBrowsingService() override {
213 most_recent_service_ = new FakeSafeBrowsingService();
214 return most_recent_service_;
217 FakeSafeBrowsingService* most_recent_service() const {
218 return most_recent_service_;
221 private:
222 FakeSafeBrowsingService* most_recent_service_;
225 // A MalwareDetails class lets us intercept calls from the renderer.
226 class FakeMalwareDetails : public MalwareDetails {
227 public:
228 FakeMalwareDetails(
229 SafeBrowsingUIManager* delegate,
230 WebContents* web_contents,
231 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource)
232 : MalwareDetails(delegate, web_contents, unsafe_resource),
233 got_dom_(false),
234 waiting_(false) { }
236 void AddDOMDetails(
237 const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params)
238 override {
239 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
240 MalwareDetails::AddDOMDetails(params);
242 // Notify the UI thread that we got the dom details.
243 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
244 base::Bind(&FakeMalwareDetails::OnDOMDetailsDone,
245 this));
248 void WaitForDOM() {
249 if (got_dom_) {
250 return;
252 // This condition might not trigger normally, but if you add a
253 // sleep(1) in malware_dom_details it triggers :).
254 waiting_ = true;
255 content::RunMessageLoop();
256 EXPECT_TRUE(got_dom_);
259 private:
260 ~FakeMalwareDetails() override {}
262 void OnDOMDetailsDone() {
263 got_dom_ = true;
264 if (waiting_) {
265 base::MessageLoopForUI::current()->Quit();
269 // Some logic to figure out if we should wait for the dom details or not.
270 // These variables should only be accessed in the UI thread.
271 bool got_dom_;
272 bool waiting_;
275 class TestMalwareDetailsFactory : public MalwareDetailsFactory {
276 public:
277 TestMalwareDetailsFactory() : details_() { }
278 ~TestMalwareDetailsFactory() override {}
280 MalwareDetails* CreateMalwareDetails(
281 SafeBrowsingUIManager* delegate,
282 WebContents* web_contents,
283 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) override {
284 details_ = new FakeMalwareDetails(delegate, web_contents,
285 unsafe_resource);
286 return details_;
289 FakeMalwareDetails* get_details() {
290 return details_;
293 private:
294 FakeMalwareDetails* details_;
297 // A SafeBrowingBlockingPage class that lets us wait until it's hidden.
298 class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage {
299 public:
300 TestSafeBrowsingBlockingPage(SafeBrowsingUIManager* manager,
301 WebContents* web_contents,
302 const UnsafeResourceList& unsafe_resources)
303 : SafeBrowsingBlockingPage(manager, web_contents, unsafe_resources),
304 wait_for_delete_(false) {
305 // Don't wait the whole 3 seconds for the browser test.
306 malware_details_proceed_delay_ms_ = 100;
309 ~TestSafeBrowsingBlockingPage() override {
310 if (!wait_for_delete_)
311 return;
313 // Notify that we are gone
314 base::MessageLoopForUI::current()->Quit();
315 wait_for_delete_ = false;
318 void WaitForDelete() {
319 wait_for_delete_ = true;
320 content::RunMessageLoop();
323 // InterstitialPageDelegate methods:
324 void CommandReceived(const std::string& command) override {
325 SafeBrowsingBlockingPage::CommandReceived(command);
327 void OnProceed() override { SafeBrowsingBlockingPage::OnProceed(); }
328 void OnDontProceed() override { SafeBrowsingBlockingPage::OnDontProceed(); }
330 private:
331 bool wait_for_delete_;
334 class TestSafeBrowsingBlockingPageFactory
335 : public SafeBrowsingBlockingPageFactory {
336 public:
337 TestSafeBrowsingBlockingPageFactory() { }
338 ~TestSafeBrowsingBlockingPageFactory() override {}
340 SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
341 SafeBrowsingUIManager* delegate,
342 WebContents* web_contents,
343 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
344 override {
345 return new TestSafeBrowsingBlockingPage(delegate, web_contents,
346 unsafe_resources);
350 } // namespace
352 // Tests the safe browsing blocking page in a browser.
353 class SafeBrowsingBlockingPageBrowserTest
354 : public InProcessBrowserTest,
355 public testing::WithParamInterface<SBThreatType> {
356 public:
357 enum Visibility {
358 VISIBILITY_ERROR = -1,
359 HIDDEN = 0,
360 VISIBLE = 1
363 SafeBrowsingBlockingPageBrowserTest() {}
365 void SetUp() override {
366 SafeBrowsingService::RegisterFactory(&factory_);
367 SafeBrowsingBlockingPage::RegisterFactory(&blocking_page_factory_);
368 MalwareDetails::RegisterFactory(&details_factory_);
369 InProcessBrowserTest::SetUp();
372 void SetUpCommandLine(base::CommandLine* command_line) override {
373 command_line->AppendSwitchASCII(
374 switches::kForceFieldTrials, "UwSInterstitialStatus/On/");
377 void TearDown() override {
378 InProcessBrowserTest::TearDown();
379 SafeBrowsingBlockingPage::RegisterFactory(NULL);
380 SafeBrowsingService::RegisterFactory(NULL);
381 MalwareDetails::RegisterFactory(NULL);
384 void SetUpInProcessBrowserTestFixture() override {
385 ASSERT_TRUE(test_server()->Start());
388 void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
389 FakeSafeBrowsingService* service =
390 static_cast<FakeSafeBrowsingService*>(
391 g_browser_process->safe_browsing_service());
393 ASSERT_TRUE(service);
394 service->fake_database_manager()->SetURLThreatType(url, threat_type);
397 // Adds a safebrowsing result of the current test threat to the fake
398 // safebrowsing service, navigates to that page, and returns the url.
399 GURL SetupWarningAndNavigate() {
400 GURL url = test_server()->GetURL(kEmptyPage);
401 SetURLThreatType(url, GetParam());
403 ui_test_utils::NavigateToURL(browser(), url);
404 EXPECT_TRUE(WaitForReady());
405 return url;
408 // Adds a safebrowsing threat result to the fake safebrowsing service,
409 // navigates to a page with an iframe containing the threat site, and returns
410 // the url of the parent page.
411 GURL SetupThreatIframeWarningAndNavigate() {
412 GURL url = test_server()->GetURL(kMalwarePage);
413 GURL iframe_url = test_server()->GetURL(kMalwareIframe);
414 SetURLThreatType(iframe_url, GetParam());
416 ui_test_utils::NavigateToURL(browser(), url);
417 EXPECT_TRUE(WaitForReady());
418 return url;
421 void SendCommand(
422 SecurityInterstitialPage::SecurityInterstitialCommands command) {
423 WebContents* contents =
424 browser()->tab_strip_model()->GetActiveWebContents();
425 // We use InterstitialPage::GetInterstitialPage(tab) instead of
426 // tab->GetInterstitialPage() because the tab doesn't have a pointer
427 // to its interstital page until it gets a command from the renderer
428 // that it has indeed displayed it -- and this sometimes happens after
429 // NavigateToURL returns.
430 SafeBrowsingBlockingPage* interstitial_page =
431 static_cast<SafeBrowsingBlockingPage*>(
432 InterstitialPage::GetInterstitialPage(contents)->
433 GetDelegateForTesting());
434 ASSERT_TRUE(interstitial_page);
435 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting,
436 interstitial_page->GetTypeForTesting());
437 interstitial_page->CommandReceived(base::IntToString(command));
440 void DontProceedThroughInterstitial() {
441 WebContents* contents =
442 browser()->tab_strip_model()->GetActiveWebContents();
443 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
444 contents);
445 ASSERT_TRUE(interstitial_page);
446 interstitial_page->DontProceed();
449 void ProceedThroughInterstitial() {
450 WebContents* contents =
451 browser()->tab_strip_model()->GetActiveWebContents();
452 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
453 contents);
454 ASSERT_TRUE(interstitial_page);
455 interstitial_page->Proceed();
458 void AssertNoInterstitial(bool wait_for_delete) {
459 WebContents* contents =
460 browser()->tab_strip_model()->GetActiveWebContents();
462 if (contents->ShowingInterstitialPage() && wait_for_delete) {
463 // We'll get notified when the interstitial is deleted.
464 TestSafeBrowsingBlockingPage* page =
465 static_cast<TestSafeBrowsingBlockingPage*>(
466 contents->GetInterstitialPage()->GetDelegateForTesting());
467 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting,
468 page->GetTypeForTesting());
469 page->WaitForDelete();
472 // Can't use InterstitialPage::GetInterstitialPage() because that
473 // gets updated after the TestSafeBrowsingBlockingPage destructor
474 ASSERT_FALSE(contents->ShowingInterstitialPage());
477 bool YesInterstitial() {
478 WebContents* contents =
479 browser()->tab_strip_model()->GetActiveWebContents();
480 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
481 contents);
482 return interstitial_page != NULL;
485 void SetReportSentCallback(const base::Closure& callback) {
486 factory_.most_recent_service()
487 ->fake_ui_manager()
488 ->set_malware_details_done_callback(callback);
491 std::string GetReportSent() {
492 return factory_.most_recent_service()->fake_ui_manager()->GetReport();
495 void MalwareRedirectCancelAndProceed(const std::string& open_function) {
496 GURL load_url = test_server()->GetURL(
497 "files/safe_browsing/interstitial_cancel.html");
498 GURL malware_url("http://localhost/files/safe_browsing/malware.html");
499 SetURLThreatType(malware_url, GetParam());
501 // Load the test page.
502 ui_test_utils::NavigateToURL(browser(), load_url);
503 // Trigger the safe browsing interstitial page via a redirect in
504 // "openWin()".
505 ui_test_utils::NavigateToURLWithDisposition(
506 browser(),
507 GURL("javascript:" + open_function + "()"),
508 CURRENT_TAB,
509 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
510 WebContents* contents =
511 browser()->tab_strip_model()->GetActiveWebContents();
512 content::WaitForInterstitialAttach(contents);
513 // Cancel the redirect request while interstitial page is open.
514 browser()->tab_strip_model()->ActivateTabAt(0, true);
515 ui_test_utils::NavigateToURL(browser(), GURL("javascript:stopWin()"));
516 browser()->tab_strip_model()->ActivateTabAt(1, true);
517 // Simulate the user clicking "proceed", there should be no crash. Since
518 // clicking proceed may do nothing (see comment in RedirectCanceled
519 // below, and crbug.com/76460), we use SendCommand to trigger the callback
520 // directly rather than using ClickAndWaitForDetach since there might not
521 // be a notification to wait for.
522 SendCommand(SecurityInterstitialPage::CMD_PROCEED);
525 content::RenderViewHost* GetRenderViewHost() {
526 InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage(
527 browser()->tab_strip_model()->GetActiveWebContents());
528 if (!interstitial)
529 return NULL;
530 return interstitial->GetMainFrame()->GetRenderViewHost();
533 bool WaitForReady() {
534 InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage(
535 browser()->tab_strip_model()->GetActiveWebContents());
536 if (!interstitial)
537 return false;
538 return content::WaitForRenderFrameReady(interstitial->GetMainFrame());
541 Visibility GetVisibility(const std::string& node_id) {
542 content::RenderViewHost* rvh = GetRenderViewHost();
543 if (!rvh)
544 return VISIBILITY_ERROR;
545 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
546 rvh->GetMainFrame(),
547 "var node = document.getElementById('" + node_id + "');\n"
548 "if (node)\n"
549 " node.offsetWidth > 0 && node.offsetHeight > 0;"
550 "else\n"
551 " 'node not found';\n");
552 if (!value.get())
553 return VISIBILITY_ERROR;
554 bool result = false;
555 if (!value->GetAsBoolean(&result))
556 return VISIBILITY_ERROR;
557 return result ? VISIBLE : HIDDEN;
560 bool Click(const std::string& node_id) {
561 content::RenderViewHost* rvh = GetRenderViewHost();
562 if (!rvh)
563 return false;
564 // We don't use ExecuteScriptAndGetValue for this one, since clicking
565 // the button/link may navigate away before the injected javascript can
566 // reply, hanging the test.
567 rvh->GetMainFrame()->ExecuteJavaScript(
568 base::ASCIIToUTF16(
569 "document.getElementById('" + node_id + "').click();\n"));
570 return true;
573 bool ClickAndWaitForDetach(const std::string& node_id) {
574 // We wait for interstitial_detached rather than nav_entry_committed, as
575 // going back from a main-frame malware interstitial page will not cause a
576 // nav entry committed event.
577 if (!Click(node_id))
578 return false;
579 content::WaitForInterstitialDetach(
580 browser()->tab_strip_model()->GetActiveWebContents());
581 return true;
584 void TestReportingDisabledAndDontProceed(const GURL& url) {
585 SetURLThreatType(url, GetParam());
586 ui_test_utils::NavigateToURL(browser(), url);
587 ASSERT_TRUE(WaitForReady());
589 EXPECT_EQ(HIDDEN, GetVisibility("extended-reporting-opt-in"));
590 EXPECT_EQ(HIDDEN, GetVisibility("opt-in-checkbox"));
591 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
592 EXPECT_TRUE(Click("details-button"));
593 EXPECT_EQ(VISIBLE, GetVisibility("help-link"));
594 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
596 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
597 AssertNoInterstitial(false); // Assert the interstitial is gone
598 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
599 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
602 protected:
603 TestMalwareDetailsFactory details_factory_;
605 private:
606 TestSafeBrowsingServiceFactory factory_;
607 TestSafeBrowsingBlockingPageFactory blocking_page_factory_;
609 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageBrowserTest);
612 // TODO(linux_aura) http://crbug.com/163931
613 // TODO(win_aura) http://crbug.com/154081
614 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
615 #define MAYBE_RedirectInIFrameCanceled DISABLED_RedirectInIFrameCanceled
616 #else
617 #define MAYBE_RedirectInIFrameCanceled RedirectInIFrameCanceled
618 #endif
619 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
620 MAYBE_RedirectInIFrameCanceled) {
621 // 1. Test the case that redirect is a subresource.
622 MalwareRedirectCancelAndProceed("openWinIFrame");
623 // If the redirect was from subresource but canceled, "proceed" will continue
624 // with the rest of resources.
625 AssertNoInterstitial(true);
628 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, RedirectCanceled) {
629 // 2. Test the case that redirect is the only resource.
630 MalwareRedirectCancelAndProceed("openWin");
631 // Clicking proceed won't do anything if the main request is cancelled
632 // already. See crbug.com/76460.
633 EXPECT_TRUE(YesInterstitial());
636 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, DontProceed) {
637 #if defined(OS_WIN) && defined(USE_ASH)
638 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
639 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
640 switches::kAshBrowserTests))
641 return;
642 #endif
644 SetupWarningAndNavigate();
646 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
647 EXPECT_EQ(HIDDEN, GetVisibility("details"));
648 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
649 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
650 EXPECT_TRUE(Click("details-button"));
651 EXPECT_EQ(VISIBLE, GetVisibility("details"));
652 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
653 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
654 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
656 AssertNoInterstitial(false); // Assert the interstitial is gone
657 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
658 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
661 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, Proceed) {
662 GURL url = SetupWarningAndNavigate();
664 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
665 AssertNoInterstitial(true); // Assert the interstitial is gone.
666 EXPECT_EQ(url,
667 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
670 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, IframeDontProceed) {
671 #if defined(OS_WIN) && defined(USE_ASH)
672 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
673 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
674 switches::kAshBrowserTests))
675 return;
676 #endif
678 SetupThreatIframeWarningAndNavigate();
680 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
681 EXPECT_EQ(HIDDEN, GetVisibility("details"));
682 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
683 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
684 EXPECT_TRUE(Click("details-button"));
685 EXPECT_EQ(VISIBLE, GetVisibility("details"));
686 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
687 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
688 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
690 AssertNoInterstitial(false); // Assert the interstitial is gone
692 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
693 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
696 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, IframeProceed) {
697 GURL url = SetupThreatIframeWarningAndNavigate();
699 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
700 AssertNoInterstitial(true); // Assert the interstitial is gone
702 EXPECT_EQ(url,
703 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
706 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
707 IframeOptInAndReportMalwareDetails) {
708 // The extended reporting opt-in is presented in the interstitial for malware,
709 // phishing, and UwS threats. It however only results in uploading further
710 // details about the immediate threat when facing malware threats.
711 const bool expect_malware_details = GetParam() == SB_THREAT_TYPE_URL_MALWARE;
713 scoped_refptr<content::MessageLoopRunner> malware_report_sent_runner(
714 new content::MessageLoopRunner);
715 if (expect_malware_details)
716 SetReportSentCallback(malware_report_sent_runner->QuitClosure());
718 GURL url = SetupThreatIframeWarningAndNavigate();
720 FakeMalwareDetails* fake_malware_details = details_factory_.get_details();
721 EXPECT_EQ(expect_malware_details, fake_malware_details != nullptr);
723 // If the DOM details from renderer did not already return when they are
724 // expected, wait for them.
725 if (expect_malware_details)
726 fake_malware_details->WaitForDOM();
728 EXPECT_EQ(VISIBLE, GetVisibility("extended-reporting-opt-in"));
729 EXPECT_TRUE(Click("opt-in-checkbox"));
730 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
731 AssertNoInterstitial(true); // Assert the interstitial is gone
733 EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
734 prefs::kSafeBrowsingExtendedReportingEnabled));
735 EXPECT_EQ(url,
736 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
738 if (expect_malware_details) {
739 malware_report_sent_runner->Run();
740 std::string serialized = GetReportSent();
741 safe_browsing::ClientMalwareReportRequest report;
742 ASSERT_TRUE(report.ParseFromString(serialized));
743 // Verify the report is complete.
744 EXPECT_TRUE(report.complete());
748 // Verifies that the "proceed anyway" link isn't available when it is disabled
749 // by the corresponding policy. Also verifies that sending the "proceed"
750 // command anyway doesn't advance to the malware site.
751 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ProceedDisabled) {
752 #if defined(OS_WIN) && defined(USE_ASH)
753 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
754 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
755 switches::kAshBrowserTests))
756 return;
757 #endif
759 // Simulate a policy disabling the "proceed anyway" link.
760 browser()->profile()->GetPrefs()->SetBoolean(
761 prefs::kSafeBrowsingProceedAnywayDisabled, true);
763 SetupWarningAndNavigate();
765 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
766 EXPECT_EQ(HIDDEN, GetVisibility("details"));
767 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
768 EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
769 EXPECT_TRUE(Click("details-button"));
770 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
771 EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
772 SendCommand(SecurityInterstitialPage::CMD_PROCEED);
774 // The "proceed" command should go back instead, if proceeding is disabled.
775 AssertNoInterstitial(true);
776 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
777 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
780 // Verifies that the reporting checkbox is hidden on non-HTTP pages.
781 // TODO(mattm): Should also verify that no report is sent, but there isn't a
782 // good way to do that in the current design.
783 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ReportingDisabled) {
784 #if defined(OS_WIN) && defined(USE_ASH)
785 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
786 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
787 switches::kAshBrowserTests))
788 return;
789 #endif
791 browser()->profile()->GetPrefs()->SetBoolean(
792 prefs::kSafeBrowsingExtendedReportingEnabled, true);
794 net::SpawnedTestServer https_server(
795 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
796 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
797 ASSERT_TRUE(https_server.Start());
798 GURL url = https_server.GetURL(kEmptyPage);
800 TestReportingDisabledAndDontProceed(url);
803 // Verifies that the reporting checkbox is hidden when opt-in is
804 // disabled by policy.
805 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
806 ReportingDisabledByPolicy) {
807 #if defined(OS_WIN) && defined(USE_ASH)
808 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
809 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
810 switches::kAshBrowserTests))
811 return;
812 #endif
814 browser()->profile()->GetPrefs()->SetBoolean(
815 prefs::kSafeBrowsingExtendedReportingEnabled, true);
816 browser()->profile()->GetPrefs()->SetBoolean(
817 prefs::kSafeBrowsingExtendedReportingOptInAllowed, false);
819 TestReportingDisabledAndDontProceed(test_server()->GetURL(kEmptyPage));
822 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, LearnMore) {
823 SetupWarningAndNavigate();
824 EXPECT_TRUE(ClickAndWaitForDetach("help-link"));
825 AssertNoInterstitial(false); // Assert the interstitial is gone
827 // We are in the help page.
828 EXPECT_EQ(
829 GetParam() == SB_THREAT_TYPE_URL_PHISHING
830 ? "/transparencyreport/safebrowsing/"
831 : "/safebrowsing/diagnostic",
832 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path());
835 INSTANTIATE_TEST_CASE_P(SafeBrowsingBlockingPageBrowserTestWithThreatType,
836 SafeBrowsingBlockingPageBrowserTest,
837 testing::Values(SB_THREAT_TYPE_URL_MALWARE,
838 SB_THREAT_TYPE_URL_PHISHING,
839 SB_THREAT_TYPE_URL_UNWANTED));
841 // Test that SafeBrowsingBlockingPage properly decodes IDN URLs that are
842 // displayed.
843 class SafeBrowsingBlockingPageIDNTest
844 : public SecurityInterstitialIDNTest,
845 public testing::WithParamInterface<SBThreatType> {
846 protected:
847 // SecurityInterstitialIDNTest implementation
848 SecurityInterstitialPage* CreateInterstitial(
849 content::WebContents* contents,
850 const GURL& request_url) const override {
851 SafeBrowsingService* sb_service =
852 g_browser_process->safe_browsing_service();
853 SafeBrowsingBlockingPage::UnsafeResource resource;
855 resource.url = request_url;
856 resource.is_subresource = false;
857 resource.threat_type = GetParam();
858 resource.render_process_host_id = contents->GetRenderProcessHost()->GetID();
859 resource.render_view_id = contents->GetRenderViewHost()->GetRoutingID();
861 return SafeBrowsingBlockingPage::CreateBlockingPage(
862 sb_service->ui_manager().get(), contents, resource);
866 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageIDNTest,
867 SafeBrowsingBlockingPageDecodesIDN) {
868 EXPECT_TRUE(VerifyIDNDecoded());
871 INSTANTIATE_TEST_CASE_P(SafeBrowsingBlockingPageIDNTestWithThreatType,
872 SafeBrowsingBlockingPageIDNTest,
873 testing::Values(SB_THREAT_TYPE_URL_MALWARE,
874 SB_THREAT_TYPE_URL_PHISHING,
875 SB_THREAT_TYPE_URL_UNWANTED));