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.
5 // This test creates a fake safebrowsing service, where we can inject
6 // malware and phishing urls. It then uses a real browser to go to
7 // these urls, and sends "goback" or "proceed" commands and verifies
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/prefs/pref_service.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/profiles/profile.h"
17 #include "chrome/browser/safe_browsing/database_manager.h"
18 #include "chrome/browser/safe_browsing/malware_details.h"
19 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
20 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
22 #include "chrome/browser/safe_browsing/ui_manager.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_tabstrip.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/url_constants.h"
28 #include "chrome/test/base/in_process_browser_test.h"
29 #include "chrome/test/base/test_switches.h"
30 #include "chrome/test/base/ui_test_utils.h"
31 #include "content/public/browser/interstitial_page.h"
32 #include "content/public/browser/navigation_controller.h"
33 #include "content/public/browser/notification_types.h"
34 #include "content/public/browser/render_frame_host.h"
35 #include "content/public/browser/render_view_host.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/test/browser_test_utils.h"
38 #include "content/public/test/test_browser_thread.h"
39 #include "content/public/test/test_utils.h"
41 using content::BrowserThread;
42 using content::InterstitialPage;
43 using content::NavigationController;
44 using content::WebContents;
48 const char kEmptyPage[] = "files/empty.html";
49 const char kMalwarePage[] = "files/safe_browsing/malware.html";
50 const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html";
52 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious
54 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
56 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
57 : SafeBrowsingDatabaseManager(service) { }
59 // Called on the IO thread to check if the given url is safe or not. If we
60 // can synchronously determine that the url is safe, CheckUrl returns true.
61 // Otherwise it returns false, and "client" is called asynchronously with the
62 // result when it is ready.
63 // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
64 bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
65 if (badurls[gurl.spec()] == SB_THREAT_TYPE_SAFE)
68 BrowserThread::PostTask(
69 BrowserThread::IO, FROM_HERE,
70 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
75 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
76 std::vector<SBThreatType> expected_threats;
77 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
78 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
79 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
80 std::vector<GURL>(1, gurl),
81 std::vector<SBFullHash>(),
83 safe_browsing_util::MALWARE,
85 sb_check.url_results[0] = badurls[gurl.spec()];
86 client->OnSafeBrowsingResult(sb_check);
89 void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
90 badurls[url.spec()] = threat_type;
94 ~FakeSafeBrowsingDatabaseManager() override {}
96 base::hash_map<std::string, SBThreatType> badurls;
97 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
100 // A SafeBrowingUIManager class that allows intercepting malware details.
101 class FakeSafeBrowsingUIManager : public SafeBrowsingUIManager {
103 explicit FakeSafeBrowsingUIManager(SafeBrowsingService* service) :
104 SafeBrowsingUIManager(service) { }
106 // Overrides SafeBrowsingUIManager
107 void SendSerializedMalwareDetails(const std::string& serialized) override {
108 // Notify the UI thread that we got a report.
109 BrowserThread::PostTask(
112 base::Bind(&FakeSafeBrowsingUIManager::OnMalwareDetailsDone,
117 void OnMalwareDetailsDone(const std::string& serialized) {
118 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 report_ = serialized;
121 EXPECT_FALSE(malware_details_done_callback_.is_null());
122 if (!malware_details_done_callback_.is_null()) {
123 malware_details_done_callback_.Run();
124 malware_details_done_callback_ = base::Closure();
128 void set_malware_details_done_callback(const base::Closure& callback) {
129 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
130 EXPECT_TRUE(malware_details_done_callback_.is_null());
131 malware_details_done_callback_ = callback;
134 std::string GetReport() {
135 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
140 ~FakeSafeBrowsingUIManager() override {}
144 base::Closure malware_details_done_callback_;
146 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager);
149 class FakeSafeBrowsingService : public SafeBrowsingService {
151 FakeSafeBrowsingService()
152 : fake_database_manager_(),
153 fake_ui_manager_() { }
155 // Returned pointer has the same lifespan as the database_manager_ refcounted
157 FakeSafeBrowsingDatabaseManager* fake_database_manager() {
158 return fake_database_manager_;
160 // Returned pointer has the same lifespan as the ui_manager_ refcounted
162 FakeSafeBrowsingUIManager* fake_ui_manager() {
163 return fake_ui_manager_;
167 ~FakeSafeBrowsingService() override {}
169 SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
170 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
171 return fake_database_manager_;
174 SafeBrowsingUIManager* CreateUIManager() override {
175 fake_ui_manager_ = new FakeSafeBrowsingUIManager(this);
176 return fake_ui_manager_;
180 FakeSafeBrowsingDatabaseManager* fake_database_manager_;
181 FakeSafeBrowsingUIManager* fake_ui_manager_;
183 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
186 // Factory that creates FakeSafeBrowsingService instances.
187 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
189 TestSafeBrowsingServiceFactory() :
190 most_recent_service_(NULL) { }
191 ~TestSafeBrowsingServiceFactory() override {}
193 SafeBrowsingService* CreateSafeBrowsingService() override {
194 most_recent_service_ = new FakeSafeBrowsingService();
195 return most_recent_service_;
198 FakeSafeBrowsingService* most_recent_service() const {
199 return most_recent_service_;
203 FakeSafeBrowsingService* most_recent_service_;
206 // A MalwareDetails class lets us intercept calls from the renderer.
207 class FakeMalwareDetails : public MalwareDetails {
210 SafeBrowsingUIManager* delegate,
211 WebContents* web_contents,
212 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource)
213 : MalwareDetails(delegate, web_contents, unsafe_resource),
218 const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params)
220 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
221 MalwareDetails::AddDOMDetails(params);
223 // Notify the UI thread that we got the dom details.
224 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
225 base::Bind(&FakeMalwareDetails::OnDOMDetailsDone,
233 // This condition might not trigger normally, but if you add a
234 // sleep(1) in malware_dom_details it triggers :).
236 content::RunMessageLoop();
237 EXPECT_TRUE(got_dom_);
241 ~FakeMalwareDetails() override {}
243 void OnDOMDetailsDone() {
246 base::MessageLoopForUI::current()->Quit();
250 // Some logic to figure out if we should wait for the dom details or not.
251 // These variables should only be accessed in the UI thread.
256 class TestMalwareDetailsFactory : public MalwareDetailsFactory {
258 TestMalwareDetailsFactory() : details_() { }
259 ~TestMalwareDetailsFactory() override {}
261 MalwareDetails* CreateMalwareDetails(
262 SafeBrowsingUIManager* delegate,
263 WebContents* web_contents,
264 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) override {
265 details_ = new FakeMalwareDetails(delegate, web_contents,
270 FakeMalwareDetails* get_details() {
275 FakeMalwareDetails* details_;
278 // A SafeBrowingBlockingPage class that lets us wait until it's hidden.
279 class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage {
281 TestSafeBrowsingBlockingPage(SafeBrowsingUIManager* manager,
282 WebContents* web_contents,
283 const UnsafeResourceList& unsafe_resources)
284 : SafeBrowsingBlockingPage(manager, web_contents, unsafe_resources),
285 wait_for_delete_(false) {
286 // Don't wait the whole 3 seconds for the browser test.
287 malware_details_proceed_delay_ms_ = 100;
290 ~TestSafeBrowsingBlockingPage() override {
291 if (!wait_for_delete_)
294 // Notify that we are gone
295 base::MessageLoopForUI::current()->Quit();
296 wait_for_delete_ = false;
299 void WaitForDelete() {
300 wait_for_delete_ = true;
301 content::RunMessageLoop();
304 // InterstitialPageDelegate methods:
305 void CommandReceived(const std::string& command) override {
306 SafeBrowsingBlockingPage::CommandReceived(command);
308 void OnProceed() override { SafeBrowsingBlockingPage::OnProceed(); }
309 void OnDontProceed() override { SafeBrowsingBlockingPage::OnDontProceed(); }
312 bool wait_for_delete_;
315 class TestSafeBrowsingBlockingPageFactory
316 : public SafeBrowsingBlockingPageFactory {
318 TestSafeBrowsingBlockingPageFactory() { }
319 ~TestSafeBrowsingBlockingPageFactory() override {}
321 SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
322 SafeBrowsingUIManager* delegate,
323 WebContents* web_contents,
324 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
326 return new TestSafeBrowsingBlockingPage(delegate, web_contents,
333 // Tests the safe browsing blocking page in a browser.
334 class SafeBrowsingBlockingPageBrowserTest
335 : public InProcessBrowserTest,
336 public testing::WithParamInterface<int> {
339 VISIBILITY_ERROR = -1,
344 SafeBrowsingBlockingPageBrowserTest() {
347 void SetUp() override {
348 SafeBrowsingService::RegisterFactory(&factory_);
349 SafeBrowsingBlockingPage::RegisterFactory(&blocking_page_factory_);
350 MalwareDetails::RegisterFactory(&details_factory_);
351 InProcessBrowserTest::SetUp();
354 void TearDown() override {
355 InProcessBrowserTest::TearDown();
356 SafeBrowsingBlockingPage::RegisterFactory(NULL);
357 SafeBrowsingService::RegisterFactory(NULL);
358 MalwareDetails::RegisterFactory(NULL);
361 void SetUpInProcessBrowserTestFixture() override {
362 ASSERT_TRUE(test_server()->Start());
365 void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
366 FakeSafeBrowsingService* service =
367 static_cast<FakeSafeBrowsingService*>(
368 g_browser_process->safe_browsing_service());
370 ASSERT_TRUE(service);
371 service->fake_database_manager()->SetURLThreatType(url, threat_type);
374 // Adds a safebrowsing result of type |threat_type| to the fake safebrowsing
375 // service, navigates to that page, and returns the url.
376 GURL SetupWarningAndNavigate(SBThreatType threat_type) {
377 GURL url = test_server()->GetURL(kEmptyPage);
378 SetURLThreatType(url, threat_type);
380 ui_test_utils::NavigateToURL(browser(), url);
381 EXPECT_TRUE(WaitForReady());
385 // Adds a safebrowsing malware result to the fake safebrowsing service,
386 // navigates to a page with an iframe containing the malware site, and
387 // returns the url of the parent page.
388 GURL SetupMalwareIframeWarningAndNavigate() {
389 GURL url = test_server()->GetURL(kMalwarePage);
390 GURL iframe_url = test_server()->GetURL(kMalwareIframe);
391 SetURLThreatType(iframe_url, SB_THREAT_TYPE_URL_MALWARE);
393 ui_test_utils::NavigateToURL(browser(), url);
394 EXPECT_TRUE(WaitForReady());
398 void SendCommand(const std::string& command) {
399 WebContents* contents =
400 browser()->tab_strip_model()->GetActiveWebContents();
401 // We use InterstitialPage::GetInterstitialPage(tab) instead of
402 // tab->GetInterstitialPage() because the tab doesn't have a pointer
403 // to its interstital page until it gets a command from the renderer
404 // that it has indeed displayed it -- and this sometimes happens after
405 // NavigateToURL returns.
406 SafeBrowsingBlockingPage* interstitial_page =
407 static_cast<SafeBrowsingBlockingPage*>(
408 InterstitialPage::GetInterstitialPage(contents)->
409 GetDelegateForTesting());
410 ASSERT_TRUE(interstitial_page);
411 interstitial_page->CommandReceived(command);
414 void DontProceedThroughInterstitial() {
415 WebContents* contents =
416 browser()->tab_strip_model()->GetActiveWebContents();
417 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
419 ASSERT_TRUE(interstitial_page);
420 interstitial_page->DontProceed();
423 void ProceedThroughInterstitial() {
424 WebContents* contents =
425 browser()->tab_strip_model()->GetActiveWebContents();
426 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
428 ASSERT_TRUE(interstitial_page);
429 interstitial_page->Proceed();
432 void AssertNoInterstitial(bool wait_for_delete) {
433 WebContents* contents =
434 browser()->tab_strip_model()->GetActiveWebContents();
436 if (contents->ShowingInterstitialPage() && wait_for_delete) {
437 // We'll get notified when the interstitial is deleted.
438 TestSafeBrowsingBlockingPage* page =
439 static_cast<TestSafeBrowsingBlockingPage*>(
440 contents->GetInterstitialPage()->GetDelegateForTesting());
441 page->WaitForDelete();
444 // Can't use InterstitialPage::GetInterstitialPage() because that
445 // gets updated after the TestSafeBrowsingBlockingPage destructor
446 ASSERT_FALSE(contents->ShowingInterstitialPage());
449 bool YesInterstitial() {
450 WebContents* contents =
451 browser()->tab_strip_model()->GetActiveWebContents();
452 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
454 return interstitial_page != NULL;
457 void SetReportSentCallback(const base::Closure& callback) {
458 factory_.most_recent_service()
460 ->set_malware_details_done_callback(callback);
463 std::string GetReportSent() {
464 return factory_.most_recent_service()->fake_ui_manager()->GetReport();
467 void MalwareRedirectCancelAndProceed(const std::string& open_function) {
468 GURL load_url = test_server()->GetURL(
469 "files/safe_browsing/interstitial_cancel.html");
470 GURL malware_url("http://localhost/files/safe_browsing/malware.html");
471 SetURLThreatType(malware_url, SB_THREAT_TYPE_URL_MALWARE);
473 // Load the test page.
474 ui_test_utils::NavigateToURL(browser(), load_url);
475 // Trigger the safe browsing interstitial page via a redirect in
477 ui_test_utils::NavigateToURLWithDisposition(
479 GURL("javascript:" + open_function + "()"),
481 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
482 WebContents* contents =
483 browser()->tab_strip_model()->GetActiveWebContents();
484 content::WaitForInterstitialAttach(contents);
485 // Cancel the redirect request while interstitial page is open.
486 browser()->tab_strip_model()->ActivateTabAt(0, true);
487 ui_test_utils::NavigateToURLWithDisposition(
489 GURL("javascript:stopWin()"),
491 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
492 browser()->tab_strip_model()->ActivateTabAt(1, true);
493 // Simulate the user clicking "proceed", there should be no crash. Since
494 // clicking proceed may do nothing (see comment in MalwareRedirectCanceled
495 // below, and crbug.com/76460), we use SendCommand to trigger the callback
496 // directly rather than using ClickAndWaitForDetach since there might not
497 // be a notification to wait for.
498 SendCommand("\"proceed\"");
501 content::RenderViewHost* GetRenderViewHost() {
502 InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage(
503 browser()->tab_strip_model()->GetActiveWebContents());
506 return interstitial->GetRenderViewHostForTesting();
509 bool WaitForReady() {
510 content::RenderViewHost* rvh = GetRenderViewHost();
513 // Wait until all <script> tags have executed, including jstemplate.
514 // TODO(joaodasilva): it would be nice to avoid the busy loop, though in
515 // practice it spins at most once or twice.
516 std::string ready_state;
518 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
519 rvh->GetMainFrame(), "document.readyState");
520 if (!value.get() || !value->GetAsString(&ready_state))
522 } while (ready_state != "complete");
526 Visibility GetVisibility(const std::string& node_id) {
527 content::RenderViewHost* rvh = GetRenderViewHost();
529 return VISIBILITY_ERROR;
530 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
532 "var node = document.getElementById('" + node_id + "');\n"
534 " node.offsetWidth > 0 && node.offsetHeight > 0;"
536 " 'node not found';\n");
538 return VISIBILITY_ERROR;
540 if (!value->GetAsBoolean(&result))
541 return VISIBILITY_ERROR;
542 return result ? VISIBLE : HIDDEN;
545 bool Click(const std::string& node_id) {
546 content::RenderViewHost* rvh = GetRenderViewHost();
549 // We don't use ExecuteScriptAndGetValue for this one, since clicking
550 // the button/link may navigate away before the injected javascript can
551 // reply, hanging the test.
552 rvh->GetMainFrame()->ExecuteJavaScript(
554 "document.getElementById('" + node_id + "').click();\n"));
558 bool ClickAndWaitForDetach(const std::string& node_id) {
559 // We wait for interstitial_detached rather than nav_entry_committed, as
560 // going back from a main-frame malware interstitial page will not cause a
561 // nav entry committed event.
564 content::WaitForInterstitialDetach(
565 browser()->tab_strip_model()->GetActiveWebContents());
570 TestMalwareDetailsFactory details_factory_;
573 TestSafeBrowsingServiceFactory factory_;
574 TestSafeBrowsingBlockingPageFactory blocking_page_factory_;
576 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageBrowserTest);
579 // TODO(linux_aura) http://crbug.com/163931
580 // TODO(win_aura) http://crbug.com/154081
581 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
582 #define MAYBE_MalwareRedirectInIFrameCanceled DISABLED_MalwareRedirectInIFrameCanceled
584 #define MAYBE_MalwareRedirectInIFrameCanceled MalwareRedirectInIFrameCanceled
586 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
587 MAYBE_MalwareRedirectInIFrameCanceled) {
588 // 1. Test the case that redirect is a subresource.
589 MalwareRedirectCancelAndProceed("openWinIFrame");
590 // If the redirect was from subresource but canceled, "proceed" will continue
591 // with the rest of resources.
592 AssertNoInterstitial(true);
595 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
596 MalwareRedirectCanceled) {
597 // 2. Test the case that redirect is the only resource.
598 MalwareRedirectCancelAndProceed("openWin");
599 // Clicking proceed won't do anything if the main request is cancelled
600 // already. See crbug.com/76460.
601 EXPECT_TRUE(YesInterstitial());
604 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
605 MalwareDontProceed) {
606 #if defined(OS_WIN) && defined(USE_ASH)
607 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
608 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
612 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
614 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
615 EXPECT_EQ(HIDDEN, GetVisibility("details"));
616 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
617 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
618 EXPECT_TRUE(Click("details-button"));
619 EXPECT_EQ(VISIBLE, GetVisibility("details"));
620 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
621 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
622 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
624 AssertNoInterstitial(false); // Assert the interstitial is gone
625 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
626 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
629 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
630 HarmfulDontProceed) {
631 #if defined(OS_WIN) && defined(USE_ASH)
632 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
633 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
637 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_UNWANTED);
639 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
640 EXPECT_EQ(HIDDEN, GetVisibility("details"));
641 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
642 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
643 EXPECT_TRUE(Click("details-button"));
644 EXPECT_EQ(VISIBLE, GetVisibility("details"));
645 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
646 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
647 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
649 AssertNoInterstitial(false); // Assert the interstitial is gone
650 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
651 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
654 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest, MalwareProceed) {
655 GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
657 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
658 AssertNoInterstitial(true); // Assert the interstitial is gone.
660 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
663 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest, HarmfulProceed) {
664 GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_UNWANTED);
666 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
667 AssertNoInterstitial(true); // Assert the interstitial is gone.
669 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
672 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
673 MalwareIframeDontProceed) {
674 #if defined(OS_WIN) && defined(USE_ASH)
675 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
676 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
680 SetupMalwareIframeWarningAndNavigate();
682 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
683 EXPECT_EQ(HIDDEN, GetVisibility("details"));
684 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
685 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
686 EXPECT_TRUE(Click("details-button"));
687 EXPECT_EQ(VISIBLE, GetVisibility("details"));
688 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
689 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
690 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
692 AssertNoInterstitial(false); // Assert the interstitial is gone
694 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
695 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
698 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
699 MalwareIframeProceed) {
700 GURL url = SetupMalwareIframeWarningAndNavigate();
702 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
703 AssertNoInterstitial(true); // Assert the interstitial is gone
706 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
709 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
710 MalwareIframeReportDetails) {
711 scoped_refptr<content::MessageLoopRunner> malware_report_sent_runner(
712 new content::MessageLoopRunner);
713 SetReportSentCallback(malware_report_sent_runner->QuitClosure());
715 GURL url = SetupMalwareIframeWarningAndNavigate();
717 // If the DOM details from renderer did not already return, wait for them.
718 details_factory_.get_details()->WaitForDOM();
720 EXPECT_TRUE(Click("opt-in-checkbox"));
721 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
722 AssertNoInterstitial(true); // Assert the interstitial is gone
724 ASSERT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
725 prefs::kSafeBrowsingExtendedReportingEnabled));
727 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
729 malware_report_sent_runner->Run();
730 std::string serialized = GetReportSent();
731 safe_browsing::ClientMalwareReportRequest report;
732 ASSERT_TRUE(report.ParseFromString(serialized));
733 // Verify the report is complete.
734 EXPECT_TRUE(report.complete());
737 // Verifies that the "proceed anyway" link isn't available when it is disabled
738 // by the corresponding policy. Also verifies that sending the "proceed"
739 // command anyway doesn't advance to the malware site.
740 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest, ProceedDisabled) {
741 #if defined(OS_WIN) && defined(USE_ASH)
742 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
743 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
747 // Simulate a policy disabling the "proceed anyway" link.
748 browser()->profile()->GetPrefs()->SetBoolean(
749 prefs::kSafeBrowsingProceedAnywayDisabled, true);
751 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
753 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
754 EXPECT_EQ(HIDDEN, GetVisibility("details"));
755 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
756 EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
757 EXPECT_TRUE(Click("details-button"));
758 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
759 EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
760 SendCommand("proceed");
762 // The "proceed" command should go back instead, if proceeding is disabled.
763 AssertNoInterstitial(true);
764 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
765 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
768 // Verifies that the reporting checkbox is hidden on non-HTTP pages.
769 // TODO(mattm): Should also verify that no report is sent, but there isn't a
770 // good way to do that in the current design.
771 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
773 #if defined(OS_WIN) && defined(USE_ASH)
774 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
775 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
779 browser()->profile()->GetPrefs()->SetBoolean(
780 prefs::kSafeBrowsingExtendedReportingEnabled, true);
782 net::SpawnedTestServer https_server(
783 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
784 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
785 ASSERT_TRUE(https_server.Start());
786 GURL url = https_server.GetURL(kEmptyPage);
787 SetURLThreatType(url, SB_THREAT_TYPE_URL_MALWARE);
788 ui_test_utils::NavigateToURL(browser(), url);
789 ASSERT_TRUE(WaitForReady());
791 EXPECT_EQ(HIDDEN, GetVisibility("malware-opt-in"));
792 EXPECT_EQ(HIDDEN, GetVisibility("opt-in-checkbox"));
793 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
794 EXPECT_TRUE(Click("details-button"));
795 EXPECT_EQ(VISIBLE, GetVisibility("help-link"));
796 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
798 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
799 AssertNoInterstitial(false); // Assert the interstitial is gone
800 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
801 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
804 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest,
805 PhishingDontProceed) {
806 #if defined(OS_WIN) && defined(USE_ASH)
807 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
808 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
812 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
814 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
815 EXPECT_EQ(HIDDEN, GetVisibility("details"));
816 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
817 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
818 EXPECT_TRUE(Click("details-button"));
819 EXPECT_EQ(VISIBLE, GetVisibility("details"));
820 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
821 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
822 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
824 AssertNoInterstitial(false); // Assert the interstitial is gone
825 EXPECT_EQ(GURL(url::kAboutBlankURL), // We are back to "about:blank".
826 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
829 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest, PhishingProceed) {
830 GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
831 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
832 AssertNoInterstitial(true); // Assert the interstitial is gone
834 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
837 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageBrowserTest, PhishingLearnMore) {
838 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
839 EXPECT_TRUE(ClickAndWaitForDetach("help-link"));
840 AssertNoInterstitial(false); // Assert the interstitial is gone
842 // We are in the help page.
844 "/transparencyreport/safebrowsing/",
845 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path());