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 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 8 // they work. 9 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_view_host.h" 35 #include "content/public/browser/web_contents.h" 36 #include "content/public/browser/web_contents_view.h" 37 #include "content/public/test/test_browser_thread.h" 38 #include "content/public/test/test_utils.h" 39 40 using content::BrowserThread; 41 using content::InterstitialPage; 42 using content::NavigationController; 43 using content::WebContents; 44 45 namespace { 46 47 const char kEmptyPage[] = "files/empty.html"; 48 const char kMalwarePage[] = "files/safe_browsing/malware.html"; 49 const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html"; 50 51 class InterstitialObserver : public content::WebContentsObserver { 52 public: 53 InterstitialObserver(content::WebContents* web_contents, 54 const base::Closure& attach_callback, 55 const base::Closure& detach_callback) 56 : WebContentsObserver(web_contents), 57 attach_callback_(attach_callback), 58 detach_callback_(detach_callback) { 59 } 60 61 virtual void DidAttachInterstitialPage() OVERRIDE { 62 attach_callback_.Run(); 63 } 64 65 virtual void DidDetachInterstitialPage() OVERRIDE { 66 detach_callback_.Run(); 67 } 68 69 private: 70 base::Closure attach_callback_; 71 base::Closure detach_callback_; 72 73 DISALLOW_COPY_AND_ASSIGN(InterstitialObserver); 74 }; 75 76 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious 77 // URLs. 78 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { 79 public: 80 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service) 81 : SafeBrowsingDatabaseManager(service) { } 82 83 // Called on the IO thread to check if the given url is safe or not. If we 84 // can synchronously determine that the url is safe, CheckUrl returns true. 85 // Otherwise it returns false, and "client" is called asynchronously with the 86 // result when it is ready. 87 // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl. 88 virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE { 89 if (badurls[gurl.spec()] == SB_THREAT_TYPE_SAFE) 90 return true; 91 92 BrowserThread::PostTask( 93 BrowserThread::IO, FROM_HERE, 94 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone, 95 this, gurl, client)); 96 return false; 97 } 98 99 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) { 100 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check( 101 std::vector<GURL>(1, gurl), 102 std::vector<SBFullHash>(), 103 client, 104 safe_browsing_util::MALWARE); 105 sb_check.url_results[0] = badurls[gurl.spec()]; 106 client->OnSafeBrowsingResult(sb_check); 107 } 108 109 void SetURLThreatType(const GURL& url, SBThreatType threat_type) { 110 badurls[url.spec()] = threat_type; 111 } 112 113 private: 114 virtual ~FakeSafeBrowsingDatabaseManager() {} 115 116 base::hash_map<std::string, SBThreatType> badurls; 117 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager); 118 }; 119 120 // A SafeBrowingUIManager class that allows intercepting malware details. 121 class FakeSafeBrowsingUIManager : public SafeBrowsingUIManager { 122 public: 123 explicit FakeSafeBrowsingUIManager(SafeBrowsingService* service) : 124 SafeBrowsingUIManager(service) { } 125 126 // Overrides SafeBrowsingUIManager 127 virtual void SendSerializedMalwareDetails( 128 const std::string& serialized) OVERRIDE { 129 reports_.push_back(serialized); 130 // Notify the UI thread that we got a report. 131 BrowserThread::PostTask( 132 BrowserThread::UI, FROM_HERE, 133 base::Bind(&FakeSafeBrowsingUIManager::OnMalwareDetailsDone, this)); 134 } 135 136 void OnMalwareDetailsDone() { 137 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); 138 base::MessageLoopForUI::current()->Quit(); 139 } 140 141 std::string GetReport() { 142 EXPECT_TRUE(reports_.size() == 1); 143 return reports_[0]; 144 } 145 146 protected: 147 virtual ~FakeSafeBrowsingUIManager() { } 148 149 private: 150 std::vector<std::string> reports_; 151 152 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager); 153 }; 154 155 class FakeSafeBrowsingService : public SafeBrowsingService { 156 public: 157 FakeSafeBrowsingService() { } 158 159 // Returned pointer has the same lifespan as the database_manager_ refcounted 160 // object. 161 FakeSafeBrowsingDatabaseManager* fake_database_manager() { 162 return fake_database_manager_; 163 } 164 // Returned pointer has the same lifespan as the ui_manager_ refcounted 165 // object. 166 FakeSafeBrowsingUIManager* fake_ui_manager() { 167 return fake_ui_manager_; 168 } 169 170 protected: 171 virtual ~FakeSafeBrowsingService() { } 172 173 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE { 174 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this); 175 return fake_database_manager_; 176 } 177 178 virtual SafeBrowsingUIManager* CreateUIManager() OVERRIDE { 179 fake_ui_manager_ = new FakeSafeBrowsingUIManager(this); 180 return fake_ui_manager_; 181 } 182 183 private: 184 FakeSafeBrowsingDatabaseManager* fake_database_manager_; 185 FakeSafeBrowsingUIManager* fake_ui_manager_; 186 187 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService); 188 }; 189 190 // Factory that creates FakeSafeBrowsingService instances. 191 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory { 192 public: 193 TestSafeBrowsingServiceFactory() : 194 most_recent_service_(NULL) { } 195 virtual ~TestSafeBrowsingServiceFactory() { } 196 197 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE { 198 most_recent_service_ = new FakeSafeBrowsingService(); 199 return most_recent_service_; 200 } 201 202 FakeSafeBrowsingService* most_recent_service() const { 203 return most_recent_service_; 204 } 205 206 private: 207 FakeSafeBrowsingService* most_recent_service_; 208 }; 209 210 // A MalwareDetails class lets us intercept calls from the renderer. 211 class FakeMalwareDetails : public MalwareDetails { 212 public: 213 FakeMalwareDetails( 214 SafeBrowsingUIManager* delegate, 215 WebContents* web_contents, 216 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) 217 : MalwareDetails(delegate, web_contents, unsafe_resource), 218 got_dom_(false), 219 waiting_(false) { } 220 221 virtual void AddDOMDetails( 222 const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params) 223 OVERRIDE { 224 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 225 MalwareDetails::AddDOMDetails(params); 226 227 // Notify the UI thread that we got the dom details. 228 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 229 base::Bind(&FakeMalwareDetails::OnDOMDetailsDone, 230 this)); 231 } 232 233 void WaitForDOM() { 234 if (got_dom_) { 235 LOG(INFO) << "Already got the dom details."; 236 return; 237 } 238 // This condition might not trigger normally, but if you add a 239 // sleep(1) in malware_dom_details it triggers :). 240 waiting_ = true; 241 LOG(INFO) << "Waiting for dom details."; 242 content::RunMessageLoop(); 243 EXPECT_TRUE(got_dom_); 244 } 245 246 private: 247 virtual ~FakeMalwareDetails() {} 248 249 void OnDOMDetailsDone() { 250 got_dom_ = true; 251 if (waiting_) { 252 base::MessageLoopForUI::current()->Quit(); 253 } 254 } 255 256 // Some logic to figure out if we should wait for the dom details or not. 257 // These variables should only be accessed in the UI thread. 258 bool got_dom_; 259 bool waiting_; 260 }; 261 262 class TestMalwareDetailsFactory : public MalwareDetailsFactory { 263 public: 264 TestMalwareDetailsFactory() { } 265 virtual ~TestMalwareDetailsFactory() { } 266 267 virtual MalwareDetails* CreateMalwareDetails( 268 SafeBrowsingUIManager* delegate, 269 WebContents* web_contents, 270 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) OVERRIDE { 271 details_ = new FakeMalwareDetails(delegate, web_contents, 272 unsafe_resource); 273 return details_; 274 } 275 276 FakeMalwareDetails* get_details() { 277 return details_; 278 } 279 280 private: 281 FakeMalwareDetails* details_; 282 }; 283 284 // A SafeBrowingBlockingPage class that lets us wait until it's hidden. 285 class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPageV2 { 286 public: 287 TestSafeBrowsingBlockingPage(SafeBrowsingUIManager* manager, 288 WebContents* web_contents, 289 const UnsafeResourceList& unsafe_resources) 290 : SafeBrowsingBlockingPageV2(manager, web_contents, unsafe_resources), 291 wait_for_delete_(false) { 292 // Don't wait the whole 3 seconds for the browser test. 293 malware_details_proceed_delay_ms_ = 100; 294 } 295 296 virtual ~TestSafeBrowsingBlockingPage() { 297 if (!wait_for_delete_) 298 return; 299 300 // Notify that we are gone 301 base::MessageLoopForUI::current()->Quit(); 302 wait_for_delete_ = false; 303 } 304 305 void WaitForDelete() { 306 wait_for_delete_ = true; 307 content::RunMessageLoop(); 308 } 309 310 private: 311 bool wait_for_delete_; 312 }; 313 314 class TestSafeBrowsingBlockingPageFactory 315 : public SafeBrowsingBlockingPageFactory { 316 public: 317 TestSafeBrowsingBlockingPageFactory() { } 318 virtual ~TestSafeBrowsingBlockingPageFactory() { } 319 320 virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage( 321 SafeBrowsingUIManager* delegate, 322 WebContents* web_contents, 323 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) 324 OVERRIDE { 325 return new TestSafeBrowsingBlockingPage(delegate, web_contents, 326 unsafe_resources); 327 } 328 }; 329 330 } // namespace 331 332 // Tests the safe browsing blocking page in a browser. 333 class SafeBrowsingBlockingPageTest : public InProcessBrowserTest { 334 public: 335 enum Visibility { 336 VISIBILITY_ERROR = -1, 337 HIDDEN = 0, 338 VISIBLE = 1, 339 }; 340 341 SafeBrowsingBlockingPageTest() { 342 } 343 344 virtual void SetUp() OVERRIDE { 345 SafeBrowsingService::RegisterFactory(&factory_); 346 SafeBrowsingBlockingPage::RegisterFactory(&blocking_page_factory_); 347 MalwareDetails::RegisterFactory(&details_factory_); 348 InProcessBrowserTest::SetUp(); 349 } 350 351 virtual void TearDown() OVERRIDE { 352 InProcessBrowserTest::TearDown(); 353 SafeBrowsingBlockingPage::RegisterFactory(NULL); 354 SafeBrowsingService::RegisterFactory(NULL); 355 MalwareDetails::RegisterFactory(NULL); 356 } 357 358 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 359 ASSERT_TRUE(test_server()->Start()); 360 } 361 362 void SetURLThreatType(const GURL& url, SBThreatType threat_type) { 363 FakeSafeBrowsingService* service = 364 static_cast<FakeSafeBrowsingService*>( 365 g_browser_process->safe_browsing_service()); 366 367 ASSERT_TRUE(service); 368 service->fake_database_manager()->SetURLThreatType(url, threat_type); 369 } 370 371 // Adds a safebrowsing result of type |threat_type| to the fake safebrowsing 372 // service, navigates to that page, and returns the url. 373 GURL SetupWarningAndNavigate(SBThreatType threat_type) { 374 GURL url = test_server()->GetURL(kEmptyPage); 375 SetURLThreatType(url, threat_type); 376 377 ui_test_utils::NavigateToURL(browser(), url); 378 EXPECT_TRUE(WaitForReady()); 379 return url; 380 } 381 382 // Adds a safebrowsing malware result to the fake safebrowsing service, 383 // navigates to a page with an iframe containing the malware site, and 384 // returns the url of the parent page. 385 GURL SetupMalwareIframeWarningAndNavigate() { 386 GURL url = test_server()->GetURL(kMalwarePage); 387 GURL iframe_url = test_server()->GetURL(kMalwareIframe); 388 SetURLThreatType(iframe_url, SB_THREAT_TYPE_URL_MALWARE); 389 390 ui_test_utils::NavigateToURL(browser(), url); 391 EXPECT_TRUE(WaitForReady()); 392 return url; 393 } 394 395 void SendCommand(const std::string& command) { 396 WebContents* contents = 397 browser()->tab_strip_model()->GetActiveWebContents(); 398 // We use InterstitialPage::GetInterstitialPage(tab) instead of 399 // tab->GetInterstitialPage() because the tab doesn't have a pointer 400 // to its interstital page until it gets a command from the renderer 401 // that it has indeed displayed it -- and this sometimes happens after 402 // NavigateToURL returns. 403 SafeBrowsingBlockingPage* interstitial_page = 404 static_cast<SafeBrowsingBlockingPage*>( 405 InterstitialPage::GetInterstitialPage(contents)-> 406 GetDelegateForTesting()); 407 ASSERT_TRUE(interstitial_page); 408 interstitial_page->CommandReceived(command); 409 } 410 411 void DontProceedThroughInterstitial() { 412 WebContents* contents = 413 browser()->tab_strip_model()->GetActiveWebContents(); 414 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( 415 contents); 416 ASSERT_TRUE(interstitial_page); 417 interstitial_page->DontProceed(); 418 } 419 420 void ProceedThroughInterstitial() { 421 WebContents* contents = 422 browser()->tab_strip_model()->GetActiveWebContents(); 423 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( 424 contents); 425 ASSERT_TRUE(interstitial_page); 426 interstitial_page->Proceed(); 427 } 428 429 void AssertNoInterstitial(bool wait_for_delete) { 430 WebContents* contents = 431 browser()->tab_strip_model()->GetActiveWebContents(); 432 433 if (contents->ShowingInterstitialPage() && wait_for_delete) { 434 // We'll get notified when the interstitial is deleted. 435 TestSafeBrowsingBlockingPage* page = 436 static_cast<TestSafeBrowsingBlockingPage*>( 437 contents->GetInterstitialPage()->GetDelegateForTesting()); 438 page->WaitForDelete(); 439 } 440 441 // Can't use InterstitialPage::GetInterstitialPage() because that 442 // gets updated after the TestSafeBrowsingBlockingPage destructor 443 ASSERT_FALSE(contents->ShowingInterstitialPage()); 444 } 445 446 bool YesInterstitial() { 447 WebContents* contents = 448 browser()->tab_strip_model()->GetActiveWebContents(); 449 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( 450 contents); 451 return interstitial_page != NULL; 452 } 453 454 void WaitForInterstitial() { 455 WebContents* contents = 456 browser()->tab_strip_model()->GetActiveWebContents(); 457 scoped_refptr<content::MessageLoopRunner> loop_runner( 458 new content::MessageLoopRunner); 459 InterstitialObserver observer(contents, 460 loop_runner->QuitClosure(), 461 base::Closure()); 462 if (!InterstitialPage::GetInterstitialPage(contents)) 463 loop_runner->Run(); 464 } 465 466 void AssertReportSent() { 467 // When a report is scheduled in the IO thread we should get notified. 468 content::RunMessageLoop(); 469 470 std::string serialized = factory_.most_recent_service()-> 471 fake_ui_manager()->GetReport(); 472 473 safe_browsing::ClientMalwareReportRequest report; 474 ASSERT_TRUE(report.ParseFromString(serialized)); 475 476 // Verify the report is complete. 477 EXPECT_TRUE(report.complete()); 478 } 479 480 void MalwareRedirectCancelAndProceed(const std::string open_function) { 481 GURL load_url = test_server()->GetURL( 482 "files/safe_browsing/interstitial_cancel.html"); 483 GURL malware_url("http://localhost/files/safe_browsing/malware.html"); 484 SetURLThreatType(malware_url, SB_THREAT_TYPE_URL_MALWARE); 485 486 // Load the test page. 487 ui_test_utils::NavigateToURL(browser(), load_url); 488 // Trigger the safe browsing interstitial page via a redirect in 489 // "openWin()". 490 ui_test_utils::NavigateToURLWithDisposition( 491 browser(), 492 GURL("javascript:" + open_function + "()"), 493 CURRENT_TAB, 494 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); 495 WaitForInterstitial(); 496 // Cancel the redirect request while interstitial page is open. 497 browser()->tab_strip_model()->ActivateTabAt(0, true); 498 ui_test_utils::NavigateToURLWithDisposition( 499 browser(), 500 GURL("javascript:stopWin()"), 501 CURRENT_TAB, 502 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 503 browser()->tab_strip_model()->ActivateTabAt(1, true); 504 // Simulate the user clicking "proceed", there should be no crash. Since 505 // clicking proceed may do nothing (see comment in MalwareRedirectCanceled 506 // below, and crbug.com/76460), we use SendCommand to trigger the callback 507 // directly rather than using ClickAndWaitForDetach since there might not 508 // be a notification to wait for. 509 SendCommand("\"proceed\""); 510 } 511 512 content::RenderViewHost* GetRenderViewHost() { 513 InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage( 514 browser()->tab_strip_model()->GetActiveWebContents()); 515 if (!interstitial) 516 return NULL; 517 return interstitial->GetRenderViewHostForTesting(); 518 } 519 520 bool WaitForReady() { 521 content::RenderViewHost* rvh = GetRenderViewHost(); 522 if (!rvh) 523 return false; 524 // Wait until all <script> tags have executed, including jstemplate. 525 // TODO(joaodasilva): it would be nice to avoid the busy loop, though in 526 // practice it spins at most once or twice. 527 std::string ready_state; 528 do { 529 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue( 530 rvh, "document.readyState"); 531 if (!value.get() || !value->GetAsString(&ready_state)) 532 return false; 533 } while (ready_state != "complete"); 534 return true; 535 } 536 537 Visibility GetVisibility(const std::string& node_id) { 538 content::RenderViewHost* rvh = GetRenderViewHost(); 539 if (!rvh) 540 return VISIBILITY_ERROR; 541 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue( 542 rvh, 543 "var node = document.getElementById('" + node_id + "');\n" 544 "if (node)\n" 545 " node.offsetWidth > 0 && node.offsetHeight > 0;" 546 "else\n" 547 " 'node not found';\n"); 548 if (!value.get()) 549 return VISIBILITY_ERROR; 550 bool result = false; 551 if (!value->GetAsBoolean(&result)) 552 return VISIBILITY_ERROR; 553 return result ? VISIBLE : HIDDEN; 554 } 555 556 bool Click(const std::string& node_id) { 557 content::RenderViewHost* rvh = GetRenderViewHost(); 558 if (!rvh) 559 return false; 560 // We don't use ExecuteScriptAndGetValue for this one, since clicking 561 // the button/link may navigate away before the injected javascript can 562 // reply, hanging the test. 563 rvh->ExecuteJavascriptInWebFrame( 564 string16(), 565 ASCIIToUTF16("document.getElementById('" + node_id + "').click();\n")); 566 return true; 567 } 568 569 bool ClickAndWaitForDetach(const std::string& node_id) { 570 // We wait for interstitial_detached rather than nav_entry_committed, as 571 // going back from a main-frame malware interstitial page will not cause a 572 // nav entry committed event. 573 scoped_refptr<content::MessageLoopRunner> loop_runner( 574 new content::MessageLoopRunner); 575 InterstitialObserver observer( 576 browser()->tab_strip_model()->GetActiveWebContents(), 577 base::Closure(), 578 loop_runner->QuitClosure()); 579 if (!Click(node_id)) 580 return false; 581 loop_runner->Run(); 582 return true; 583 } 584 585 protected: 586 TestMalwareDetailsFactory details_factory_; 587 588 private: 589 TestSafeBrowsingServiceFactory factory_; 590 TestSafeBrowsingBlockingPageFactory blocking_page_factory_; 591 592 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageTest); 593 }; 594 595 // TODO(linux_aura) http://crbug.com/163931 596 // TODO(win_aura) http://crbug.com/154081 597 #if defined(USE_AURA) && !defined(OS_CHROMEOS) 598 #define MAYBE_MalwareRedirectInIFrameCanceled DISABLED_MalwareRedirectInIFrameCanceled 599 #else 600 #define MAYBE_MalwareRedirectInIFrameCanceled MalwareRedirectInIFrameCanceled 601 #endif 602 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, 603 MAYBE_MalwareRedirectInIFrameCanceled) { 604 // 1. Test the case that redirect is a subresource. 605 MalwareRedirectCancelAndProceed("openWinIFrame"); 606 // If the redirect was from subresource but canceled, "proceed" will continue 607 // with the rest of resources. 608 AssertNoInterstitial(true); 609 } 610 611 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, 612 MalwareRedirectCanceled) { 613 // 2. Test the case that redirect is the only resource. 614 MalwareRedirectCancelAndProceed("openWin"); 615 // Clicking proceed won't do anything if the main request is cancelled 616 // already. See crbug.com/76460. 617 EXPECT_TRUE(YesInterstitial()); 618 } 619 620 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareDontProceed) { 621 #if defined(OS_WIN) && defined(USE_ASH) 622 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 623 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 624 return; 625 #endif 626 627 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE); 628 629 EXPECT_EQ(VISIBLE, GetVisibility("malware-icon")); 630 EXPECT_EQ(HIDDEN, GetVisibility("subresource-icon")); 631 EXPECT_EQ(HIDDEN, GetVisibility("phishing-icon")); 632 EXPECT_EQ(VISIBLE, GetVisibility("check-report")); 633 EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link")); 634 EXPECT_EQ(HIDDEN, GetVisibility("report-error-link")); 635 EXPECT_EQ(HIDDEN, GetVisibility("proceed")); 636 EXPECT_TRUE(Click("see-more-link")); 637 EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link")); 638 EXPECT_EQ(HIDDEN, GetVisibility("report-error-link")); 639 EXPECT_EQ(VISIBLE, GetVisibility("proceed")); 640 641 EXPECT_TRUE(ClickAndWaitForDetach("back")); 642 AssertNoInterstitial(false); // Assert the interstitial is gone 643 EXPECT_EQ( 644 GURL(content::kAboutBlankURL), // Back to "about:blank" 645 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 646 } 647 648 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareProceed) { 649 GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE); 650 651 EXPECT_TRUE(ClickAndWaitForDetach("proceed")); 652 AssertNoInterstitial(true); // Assert the interstitial is gone. 653 EXPECT_EQ(url, 654 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 655 } 656 657 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, 658 MalwareLearnMore) { 659 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE); 660 661 EXPECT_TRUE(ClickAndWaitForDetach("learn-more-link")); 662 AssertNoInterstitial(false); // Assert the interstitial is gone 663 664 // We are in the help page. 665 EXPECT_EQ( 666 "/goodtoknow/online-safety/malware/", 667 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path()); 668 } 669 670 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, 671 MalwareIframeDontProceed) { 672 #if defined(OS_WIN) && defined(USE_ASH) 673 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 674 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 675 return; 676 #endif 677 678 SetupMalwareIframeWarningAndNavigate(); 679 680 EXPECT_EQ(HIDDEN, GetVisibility("malware-icon")); 681 EXPECT_EQ(VISIBLE, GetVisibility("subresource-icon")); 682 EXPECT_EQ(HIDDEN, GetVisibility("phishing-icon")); 683 EXPECT_EQ(VISIBLE, GetVisibility("check-report")); 684 EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link")); 685 EXPECT_EQ(HIDDEN, GetVisibility("report-error-link")); 686 EXPECT_EQ(HIDDEN, GetVisibility("proceed")); 687 EXPECT_TRUE(Click("see-more-link")); 688 EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link")); 689 EXPECT_EQ(HIDDEN, GetVisibility("report-error-link")); 690 EXPECT_EQ(VISIBLE, GetVisibility("proceed")); 691 692 EXPECT_TRUE(ClickAndWaitForDetach("back")); 693 AssertNoInterstitial(false); // Assert the interstitial is gone 694 695 EXPECT_EQ( 696 GURL(content::kAboutBlankURL), // Back to "about:blank" 697 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 698 } 699 700 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareIframeProceed) { 701 GURL url = SetupMalwareIframeWarningAndNavigate(); 702 703 EXPECT_TRUE(ClickAndWaitForDetach("proceed")); 704 AssertNoInterstitial(true); // Assert the interstitial is gone 705 706 EXPECT_EQ(url, 707 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 708 } 709 710 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, 711 MalwareIframeReportDetails) { 712 GURL url = SetupMalwareIframeWarningAndNavigate(); 713 714 // If the DOM details from renderer did not already return, wait for them. 715 details_factory_.get_details()->WaitForDOM(); 716 717 EXPECT_TRUE(Click("check-report")); 718 719 EXPECT_TRUE(ClickAndWaitForDetach("proceed")); 720 AssertNoInterstitial(true); // Assert the interstitial is gone 721 722 EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean( 723 prefs::kSafeBrowsingReportingEnabled)); 724 725 EXPECT_EQ(url, 726 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 727 AssertReportSent(); 728 } 729 730 // Verifies that the "proceed anyway" link isn't available when it is disabled 731 // by the corresponding policy. Also verifies that sending the "proceed" 732 // command anyway doesn't advance to the malware site. 733 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, ProceedDisabled) { 734 #if defined(OS_WIN) && defined(USE_ASH) 735 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 736 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 737 return; 738 #endif 739 740 // Simulate a policy disabling the "proceed anyway" link. 741 browser()->profile()->GetPrefs()->SetBoolean( 742 prefs::kSafeBrowsingProceedAnywayDisabled, true); 743 744 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE); 745 746 EXPECT_EQ(VISIBLE, GetVisibility("check-report")); 747 EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link")); 748 EXPECT_EQ(HIDDEN, GetVisibility("proceed")); 749 EXPECT_EQ(HIDDEN, GetVisibility("proceed-span")); 750 EXPECT_TRUE(Click("see-more-link")); 751 EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link")); 752 EXPECT_EQ(HIDDEN, GetVisibility("proceed")); 753 EXPECT_EQ(HIDDEN, GetVisibility("proceed-span")); 754 755 // The "proceed" command should go back instead, if proceeding is disabled. 756 EXPECT_TRUE(ClickAndWaitForDetach("proceed")); 757 AssertNoInterstitial(true); 758 EXPECT_EQ( 759 GURL(content::kAboutBlankURL), // Back to "about:blank" 760 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 761 } 762 763 // Verifies that the reporting checkbox is hidden on non-HTTP pages. 764 // TODO(mattm): Should also verify that no report is sent, but there isn't a 765 // good way to do that in the current design. 766 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, ReportingDisabled) { 767 #if defined(OS_WIN) && defined(USE_ASH) 768 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 769 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 770 return; 771 #endif 772 773 browser()->profile()->GetPrefs()->SetBoolean( 774 prefs::kSafeBrowsingReportingEnabled, true); 775 776 net::SpawnedTestServer https_server( 777 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost, 778 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 779 ASSERT_TRUE(https_server.Start()); 780 GURL url = https_server.GetURL(kEmptyPage); 781 SetURLThreatType(url, SB_THREAT_TYPE_URL_MALWARE); 782 ui_test_utils::NavigateToURL(browser(), url); 783 ASSERT_TRUE(WaitForReady()); 784 785 EXPECT_EQ(HIDDEN, GetVisibility("check-report")); 786 EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link")); 787 EXPECT_EQ(HIDDEN, GetVisibility("proceed")); 788 EXPECT_TRUE(Click("see-more-link")); 789 EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link")); 790 EXPECT_EQ(VISIBLE, GetVisibility("proceed")); 791 792 EXPECT_TRUE(ClickAndWaitForDetach("back")); 793 AssertNoInterstitial(false); // Assert the interstitial is gone 794 EXPECT_EQ( 795 GURL(content::kAboutBlankURL), // Back to "about:blank" 796 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 797 } 798 799 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingDontProceed) { 800 #if defined(OS_WIN) && defined(USE_ASH) 801 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 802 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 803 return; 804 #endif 805 806 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING); 807 808 EXPECT_EQ(HIDDEN, GetVisibility("malware-icon")); 809 EXPECT_EQ(HIDDEN, GetVisibility("subresource-icon")); 810 EXPECT_EQ(VISIBLE, GetVisibility("phishing-icon")); 811 EXPECT_EQ(HIDDEN, GetVisibility("check-report")); 812 EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link")); 813 EXPECT_EQ(HIDDEN, GetVisibility("report-error-link")); 814 EXPECT_EQ(HIDDEN, GetVisibility("proceed")); 815 EXPECT_TRUE(Click("see-more-link")); 816 EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link")); 817 EXPECT_EQ(VISIBLE, GetVisibility("report-error-link")); 818 EXPECT_EQ(VISIBLE, GetVisibility("proceed")); 819 820 EXPECT_TRUE(ClickAndWaitForDetach("back")); 821 AssertNoInterstitial(false); // Assert the interstitial is gone 822 EXPECT_EQ( 823 GURL(content::kAboutBlankURL), // We are back to "about:blank". 824 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 825 } 826 827 // http://crbug.com/247763 828 #if defined(OS_WIN) 829 #define MAYBE_PhishingProceed DISABLED_PhishingProceed 830 #else 831 #define MAYBE_PhishingProceed PhishingProceed 832 #endif 833 834 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MAYBE_PhishingProceed) { 835 GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING); 836 837 EXPECT_TRUE(ClickAndWaitForDetach("proceed")); 838 AssertNoInterstitial(true); // Assert the interstitial is gone 839 EXPECT_EQ(url, 840 browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); 841 } 842 843 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingReportError) { 844 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING); 845 846 EXPECT_TRUE(ClickAndWaitForDetach("report-error-link")); 847 AssertNoInterstitial(false); // Assert the interstitial is gone 848 849 // We are in the error reporting page. 850 EXPECT_EQ( 851 "/safebrowsing/report_error/", 852 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path()); 853 } 854 855 // See crbug.com/248447 856 #if defined(OS_WIN) 857 #define MAYBE_PhishingLearnMore DISABLED_PhishingLearnMore 858 #else 859 #define MAYBE_PhishingLearnMore PhishingLearnMore 860 #endif 861 862 IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MAYBE_PhishingLearnMore) { 863 SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING); 864 865 EXPECT_TRUE(ClickAndWaitForDetach("learn-more-link")); 866 AssertNoInterstitial(false); // Assert the interstitial is gone 867 868 // We are in the help page. 869 EXPECT_EQ( 870 "/goodtoknow/online-safety/phishing/", 871 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path()); 872 } 873