OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // This test creates a fake safebrowsing service, where we can inject known- | 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 | 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. | 7 // "goback" or "proceed" commands and verifies they work. |
8 | 8 |
| 9 #include <algorithm> |
| 10 |
9 #include "base/bind.h" | 11 #include "base/bind.h" |
10 #include "base/command_line.h" | 12 #include "base/command_line.h" |
11 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
12 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
14 #include "base/test/histogram_tester.h" | 16 #include "base/test/histogram_tester.h" |
15 #include "base/values.h" | 17 #include "base/values.h" |
16 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
17 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" | 19 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" |
18 #include "chrome/browser/net/url_request_mock_util.h" | 20 #include "chrome/browser/net/url_request_mock_util.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 using content::InterstitialPage; | 54 using content::InterstitialPage; |
53 using content::NavigationController; | 55 using content::NavigationController; |
54 using content::WebContents; | 56 using content::WebContents; |
55 | 57 |
56 namespace safe_browsing { | 58 namespace safe_browsing { |
57 | 59 |
58 namespace { | 60 namespace { |
59 | 61 |
60 const char kEmptyPage[] = "empty.html"; | 62 const char kEmptyPage[] = "empty.html"; |
61 const char kMalwarePage[] = "safe_browsing/malware.html"; | 63 const char kMalwarePage[] = "safe_browsing/malware.html"; |
| 64 const char kMalwarePage2[] = "safe_browsing/malware2.html"; |
62 const char kMalwareIframe[] = "safe_browsing/malware_iframe.html"; | 65 const char kMalwareIframe[] = "safe_browsing/malware_iframe.html"; |
63 const char kUnrelatedUrl[] = "https://www.google.com"; | 66 const char kUnrelatedUrl[] = "https://www.google.com"; |
64 | 67 |
65 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious | 68 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious |
66 // URLs. | 69 // URLs. |
67 class FakeSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { | 70 class FakeSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { |
68 public: | 71 public: |
69 FakeSafeBrowsingDatabaseManager() {} | 72 FakeSafeBrowsingDatabaseManager() {} |
70 | 73 |
71 // Called on the IO thread to check if the given url is safe or not. If we | 74 // Called on the IO thread to check if the given url is safe or not. If we |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 | 416 |
414 ui_test_utils::NavigateToURL(browser(), url); | 417 ui_test_utils::NavigateToURL(browser(), url); |
415 EXPECT_TRUE(WaitForReady()); | 418 EXPECT_TRUE(WaitForReady()); |
416 return url; | 419 return url; |
417 } | 420 } |
418 | 421 |
419 // Adds a safebrowsing threat result to the fake safebrowsing service, | 422 // Adds a safebrowsing threat result to the fake safebrowsing service, |
420 // navigates to a page with an iframe containing the threat site, and returns | 423 // navigates to a page with an iframe containing the threat site, and returns |
421 // the url of the parent page. | 424 // the url of the parent page. |
422 GURL SetupThreatIframeWarningAndNavigate() { | 425 GURL SetupThreatIframeWarningAndNavigate() { |
423 GURL url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage); | 426 GURL url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage2); |
424 GURL iframe_url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe); | 427 GURL iframe_url = net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe); |
425 SetURLThreatType(iframe_url, GetParam()); | 428 SetURLThreatType(iframe_url, GetParam()); |
426 | 429 |
427 ui_test_utils::NavigateToURL(browser(), url); | 430 ui_test_utils::NavigateToURL(browser(), url); |
428 EXPECT_TRUE(WaitForReady()); | 431 EXPECT_TRUE(WaitForReady()); |
429 return url; | 432 return url; |
430 } | 433 } |
431 | 434 |
432 void SendCommand( | 435 void SendCommand( |
433 security_interstitials::SecurityInterstitialCommands command) { | 436 security_interstitials::SecurityInterstitialCommands command) { |
434 WebContents* contents = | 437 WebContents* contents = |
435 browser()->tab_strip_model()->GetActiveWebContents(); | 438 browser()->tab_strip_model()->GetActiveWebContents(); |
436 // We use InterstitialPage::GetInterstitialPage(tab) instead of | 439 // We use InterstitialPage::GetInterstitialPage(tab) instead of |
437 // tab->GetInterstitialPage() because the tab doesn't have a pointer | 440 // tab->GetInterstitialPage() because the tab doesn't have a pointer |
438 // to its interstital page until it gets a command from the renderer | 441 // to its interstital page until it gets a command from the renderer |
439 // that it has indeed displayed it -- and this sometimes happens after | 442 // that it has indeed displayed it -- and this sometimes happens after |
440 // NavigateToURL returns. | 443 // NavigateToURL returns. |
441 SafeBrowsingBlockingPage* interstitial_page = | 444 SafeBrowsingBlockingPage* interstitial_page = |
442 static_cast<SafeBrowsingBlockingPage*>( | 445 static_cast<SafeBrowsingBlockingPage*>( |
443 InterstitialPage::GetInterstitialPage(contents)-> | 446 InterstitialPage::GetInterstitialPage(contents)-> |
444 GetDelegateForTesting()); | 447 GetDelegateForTesting()); |
445 ASSERT_TRUE(interstitial_page); | 448 ASSERT_TRUE(interstitial_page); |
446 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting, | 449 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting, |
447 interstitial_page->GetTypeForTesting()); | 450 interstitial_page->GetTypeForTesting()); |
448 interstitial_page->CommandReceived(base::IntToString(command)); | 451 interstitial_page->CommandReceived(base::IntToString(command)); |
449 } | 452 } |
450 | 453 |
451 void DontProceedThroughInterstitial() { | |
452 WebContents* contents = | |
453 browser()->tab_strip_model()->GetActiveWebContents(); | |
454 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( | |
455 contents); | |
456 ASSERT_TRUE(interstitial_page); | |
457 interstitial_page->DontProceed(); | |
458 } | |
459 | |
460 void ProceedThroughInterstitial() { | |
461 WebContents* contents = | |
462 browser()->tab_strip_model()->GetActiveWebContents(); | |
463 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( | |
464 contents); | |
465 ASSERT_TRUE(interstitial_page); | |
466 interstitial_page->Proceed(); | |
467 } | |
468 | |
469 void AssertNoInterstitial(bool wait_for_delete) { | 454 void AssertNoInterstitial(bool wait_for_delete) { |
470 WebContents* contents = | 455 WebContents* contents = |
471 browser()->tab_strip_model()->GetActiveWebContents(); | 456 browser()->tab_strip_model()->GetActiveWebContents(); |
472 | 457 |
473 if (contents->ShowingInterstitialPage() && wait_for_delete) { | 458 if (contents->ShowingInterstitialPage() && wait_for_delete) { |
474 // We'll get notified when the interstitial is deleted. | 459 // We'll get notified when the interstitial is deleted. |
475 TestSafeBrowsingBlockingPage* page = | 460 TestSafeBrowsingBlockingPage* page = |
476 static_cast<TestSafeBrowsingBlockingPage*>( | 461 static_cast<TestSafeBrowsingBlockingPage*>( |
477 contents->GetInterstitialPage()->GetDelegateForTesting()); | 462 contents->GetInterstitialPage()->GetDelegateForTesting()); |
478 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting, | 463 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting, |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 EXPECT_EQ(url, | 734 EXPECT_EQ(url, |
750 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); | 735 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); |
751 | 736 |
752 if (expect_threat_details) { | 737 if (expect_threat_details) { |
753 threat_report_sent_runner->Run(); | 738 threat_report_sent_runner->Run(); |
754 std::string serialized = GetReportSent(); | 739 std::string serialized = GetReportSent(); |
755 ClientSafeBrowsingReportRequest report; | 740 ClientSafeBrowsingReportRequest report; |
756 ASSERT_TRUE(report.ParseFromString(serialized)); | 741 ASSERT_TRUE(report.ParseFromString(serialized)); |
757 // Verify the report is complete. | 742 // Verify the report is complete. |
758 EXPECT_TRUE(report.complete()); | 743 EXPECT_TRUE(report.complete()); |
| 744 // Do some basic verification of report contents. |
| 745 EXPECT_EQ(url.spec(), report.page_url()); |
| 746 EXPECT_EQ(net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe).spec(), |
| 747 report.url()); |
| 748 std::vector<std::string> report_urls; |
| 749 for (int i = 0; i < report.resources_size(); ++i) |
| 750 report_urls.push_back(report.resources(i).url()); |
| 751 ASSERT_EQ(3U, report_urls.size()); |
| 752 std::sort(report_urls.begin(), report_urls.end()); |
| 753 EXPECT_EQ("http://example.com/cross_site_iframe.html", report_urls[0]); |
| 754 EXPECT_EQ(url.spec(), report_urls[1]); |
| 755 EXPECT_EQ(net::URLRequestMockHTTPJob::GetMockUrl(kMalwareIframe).spec(), |
| 756 report_urls[2]); |
759 } | 757 } |
760 } | 758 } |
761 | 759 |
| 760 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, |
| 761 MainFrameBlockedShouldHaveNoDOMDetailsWhenDontProceed) { |
| 762 const bool expect_threat_details = |
| 763 SafeBrowsingBlockingPage::ShouldReportThreatDetails(GetParam()); |
| 764 |
| 765 scoped_refptr<content::MessageLoopRunner> threat_report_sent_runner( |
| 766 new content::MessageLoopRunner); |
| 767 if (expect_threat_details) |
| 768 SetReportSentCallback(threat_report_sent_runner->QuitClosure()); |
| 769 |
| 770 // Navigate to a safe page which contains multiple potential DOM details. |
| 771 // (Despite the name, kMalwarePage is not the page flagged as malware in this |
| 772 // test.) |
| 773 GURL safe_url(net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage)); |
| 774 ui_test_utils::NavigateToURL(browser(), safe_url); |
| 775 |
| 776 EXPECT_EQ(nullptr, details_factory_.get_details()); |
| 777 |
| 778 // Start navigation to bad page (kEmptyPage), which will be blocked before it |
| 779 // is committed. |
| 780 GURL url = SetupWarningAndNavigate(); |
| 781 |
| 782 FakeThreatDetails* fake_threat_details = details_factory_.get_details(); |
| 783 EXPECT_EQ(expect_threat_details, fake_threat_details != nullptr); |
| 784 |
| 785 // Go back. |
| 786 EXPECT_EQ(VISIBLE, GetVisibility("extended-reporting-opt-in")); |
| 787 EXPECT_TRUE(Click("opt-in-checkbox")); |
| 788 EXPECT_TRUE(ClickAndWaitForDetach("primary-button")); |
| 789 AssertNoInterstitial(true); // Assert the interstitial is gone |
| 790 |
| 791 EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean( |
| 792 prefs::kSafeBrowsingExtendedReportingEnabled)); |
| 793 EXPECT_EQ(safe_url, |
| 794 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); |
| 795 |
| 796 if (expect_threat_details) { |
| 797 threat_report_sent_runner->Run(); |
| 798 std::string serialized = GetReportSent(); |
| 799 ClientSafeBrowsingReportRequest report; |
| 800 ASSERT_TRUE(report.ParseFromString(serialized)); |
| 801 // Verify the report is complete. |
| 802 EXPECT_TRUE(report.complete()); |
| 803 EXPECT_EQ(url.spec(), report.page_url()); |
| 804 EXPECT_EQ(url.spec(), report.url()); |
| 805 ASSERT_EQ(1, report.resources_size()); |
| 806 EXPECT_EQ(url.spec(), report.resources(0).url()); |
| 807 } |
| 808 } |
| 809 |
| 810 IN_PROC_BROWSER_TEST_P( |
| 811 SafeBrowsingBlockingPageBrowserTest, |
| 812 MainFrameBlockedShouldHaveNoDOMDetailsWhenProceeding) { |
| 813 const bool expect_threat_details = |
| 814 SafeBrowsingBlockingPage::ShouldReportThreatDetails(GetParam()); |
| 815 |
| 816 scoped_refptr<content::MessageLoopRunner> threat_report_sent_runner( |
| 817 new content::MessageLoopRunner); |
| 818 if (expect_threat_details) |
| 819 SetReportSentCallback(threat_report_sent_runner->QuitClosure()); |
| 820 |
| 821 // Navigate to a safe page which contains multiple potential DOM details. |
| 822 // (Despite the name, kMalwarePage is not the page flagged as malware in this |
| 823 // test.) |
| 824 ui_test_utils::NavigateToURL( |
| 825 browser(), net::URLRequestMockHTTPJob::GetMockUrl(kMalwarePage)); |
| 826 |
| 827 EXPECT_EQ(nullptr, details_factory_.get_details()); |
| 828 |
| 829 // Start navigation to bad page (kEmptyPage), which will be blocked before it |
| 830 // is committed. |
| 831 GURL url = SetupWarningAndNavigate(); |
| 832 |
| 833 FakeThreatDetails* fake_threat_details = details_factory_.get_details(); |
| 834 EXPECT_EQ(expect_threat_details, fake_threat_details != nullptr); |
| 835 |
| 836 // Proceed through the warning. |
| 837 EXPECT_EQ(VISIBLE, GetVisibility("extended-reporting-opt-in")); |
| 838 EXPECT_TRUE(Click("opt-in-checkbox")); |
| 839 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link")); |
| 840 AssertNoInterstitial(true); // Assert the interstitial is gone |
| 841 |
| 842 EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean( |
| 843 prefs::kSafeBrowsingExtendedReportingEnabled)); |
| 844 EXPECT_EQ(url, |
| 845 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); |
| 846 |
| 847 if (expect_threat_details) { |
| 848 threat_report_sent_runner->Run(); |
| 849 std::string serialized = GetReportSent(); |
| 850 ClientSafeBrowsingReportRequest report; |
| 851 ASSERT_TRUE(report.ParseFromString(serialized)); |
| 852 // Verify the report is complete. |
| 853 EXPECT_TRUE(report.complete()); |
| 854 EXPECT_EQ(url.spec(), report.page_url()); |
| 855 EXPECT_EQ(url.spec(), report.url()); |
| 856 ASSERT_EQ(1, report.resources_size()); |
| 857 EXPECT_EQ(url.spec(), report.resources(0).url()); |
| 858 } |
| 859 } |
| 860 |
762 // Verifies that the "proceed anyway" link isn't available when it is disabled | 861 // Verifies that the "proceed anyway" link isn't available when it is disabled |
763 // by the corresponding policy. Also verifies that sending the "proceed" | 862 // by the corresponding policy. Also verifies that sending the "proceed" |
764 // command anyway doesn't advance to the unsafe site. | 863 // command anyway doesn't advance to the unsafe site. |
765 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ProceedDisabled) { | 864 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ProceedDisabled) { |
766 #if defined(OS_WIN) && defined(USE_ASH) | 865 #if defined(OS_WIN) && defined(USE_ASH) |
767 // Disable this test in Metro+Ash for now (https://crbug.com/262796). | 866 // Disable this test in Metro+Ash for now (https://crbug.com/262796). |
768 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 867 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
769 switches::kAshBrowserTests)) { | 868 switches::kAshBrowserTests)) { |
770 return; | 869 return; |
771 } | 870 } |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 EXPECT_TRUE(VerifyIDNDecoded()); | 1125 EXPECT_TRUE(VerifyIDNDecoded()); |
1027 } | 1126 } |
1028 | 1127 |
1029 INSTANTIATE_TEST_CASE_P(SafeBrowsingBlockingPageIDNTestWithThreatType, | 1128 INSTANTIATE_TEST_CASE_P(SafeBrowsingBlockingPageIDNTestWithThreatType, |
1030 SafeBrowsingBlockingPageIDNTest, | 1129 SafeBrowsingBlockingPageIDNTest, |
1031 testing::Values(SB_THREAT_TYPE_URL_MALWARE, | 1130 testing::Values(SB_THREAT_TYPE_URL_MALWARE, |
1032 SB_THREAT_TYPE_URL_PHISHING, | 1131 SB_THREAT_TYPE_URL_PHISHING, |
1033 SB_THREAT_TYPE_URL_UNWANTED)); | 1132 SB_THREAT_TYPE_URL_UNWANTED)); |
1034 | 1133 |
1035 } // namespace safe_browsing | 1134 } // namespace safe_browsing |
OLD | NEW |