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 #include "base/bind.h" 6 #include "base/bind_helpers.h" 7 #include "base/command_line.h" 8 #include "base/path_service.h" 9 #include "base/prefs/pref_service.h" 10 #include "base/strings/string_util.h" 11 #include "base/strings/stringprintf.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "base/time/time.h" 14 #include "chrome/app/chrome_command_ids.h" 15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/content_settings/host_content_settings_map.h" 17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/ssl/ssl_blocking_page.h" 19 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser_commands.h" 21 #include "chrome/browser/ui/browser_navigator.h" 22 #include "chrome/browser/ui/browser_tabstrip.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" 24 #include "chrome/common/chrome_paths.h" 25 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/pref_names.h" 27 #include "chrome/test/base/in_process_browser_test.h" 28 #include "chrome/test/base/ui_test_utils.h" 29 #include "components/web_modal/web_contents_modal_dialog_manager.h" 30 #include "content/public/browser/browser_context.h" 31 #include "content/public/browser/interstitial_page.h" 32 #include "content/public/browser/navigation_controller.h" 33 #include "content/public/browser/navigation_entry.h" 34 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/render_view_host.h" 36 #include "content/public/browser/render_widget_host_view.h" 37 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_contents_observer.h" 39 #include "content/public/common/security_style.h" 40 #include "content/public/common/ssl_status.h" 41 #include "content/public/test/browser_test_utils.h" 42 #include "content/public/test/download_test_observer.h" 43 #include "content/public/test/test_renderer_host.h" 44 #include "net/base/net_errors.h" 45 #include "net/base/test_data_directory.h" 46 #include "net/cert/cert_status_flags.h" 47 #include "net/test/spawned_test_server/spawned_test_server.h" 48 49 #if defined(USE_NSS) 50 #include "chrome/browser/net/nss_context.h" 51 #include "net/base/crypto_module.h" 52 #include "net/cert/nss_cert_database.h" 53 #endif // defined(USE_NSS) 54 55 using base::ASCIIToUTF16; 56 using content::InterstitialPage; 57 using content::NavigationController; 58 using content::NavigationEntry; 59 using content::SSLStatus; 60 using content::WebContents; 61 using web_modal::WebContentsModalDialogManager; 62 63 const base::FilePath::CharType kDocRoot[] = 64 FILE_PATH_LITERAL("chrome/test/data"); 65 66 namespace { 67 68 class ProvisionalLoadWaiter : public content::WebContentsObserver { 69 public: 70 explicit ProvisionalLoadWaiter(WebContents* tab) 71 : WebContentsObserver(tab), waiting_(false), seen_(false) {} 72 73 void Wait() { 74 if (seen_) 75 return; 76 77 waiting_ = true; 78 content::RunMessageLoop(); 79 } 80 81 virtual void DidFailProvisionalLoad( 82 content::RenderFrameHost* render_frame_host, 83 const GURL& validated_url, 84 int error_code, 85 const base::string16& error_description) OVERRIDE { 86 seen_ = true; 87 if (waiting_) 88 base::MessageLoopForUI::current()->Quit(); 89 } 90 91 private: 92 bool waiting_; 93 bool seen_; 94 }; 95 96 namespace AuthState { 97 98 enum AuthStateFlags { 99 NONE = 0, 100 DISPLAYED_INSECURE_CONTENT = 1 << 0, 101 RAN_INSECURE_CONTENT = 1 << 1, 102 SHOWING_INTERSTITIAL = 1 << 2, 103 SHOWING_ERROR = 1 << 3 104 }; 105 106 void Check(const NavigationEntry& entry, int expected_authentication_state) { 107 if (expected_authentication_state == AuthState::SHOWING_ERROR) { 108 EXPECT_EQ(content::PAGE_TYPE_ERROR, entry.GetPageType()); 109 } else { 110 EXPECT_EQ( 111 !!(expected_authentication_state & AuthState::SHOWING_INTERSTITIAL) 112 ? content::PAGE_TYPE_INTERSTITIAL 113 : content::PAGE_TYPE_NORMAL, 114 entry.GetPageType()); 115 } 116 117 bool displayed_insecure_content = 118 !!(entry.GetSSL().content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT); 119 EXPECT_EQ( 120 !!(expected_authentication_state & AuthState::DISPLAYED_INSECURE_CONTENT), 121 displayed_insecure_content); 122 123 bool ran_insecure_content = 124 !!(entry.GetSSL().content_status & SSLStatus::RAN_INSECURE_CONTENT); 125 EXPECT_EQ(!!(expected_authentication_state & AuthState::RAN_INSECURE_CONTENT), 126 ran_insecure_content); 127 } 128 129 } // namespace AuthState 130 131 namespace SecurityStyle { 132 133 void Check(const NavigationEntry& entry, 134 content::SecurityStyle expected_security_style) { 135 EXPECT_EQ(expected_security_style, entry.GetSSL().security_style); 136 } 137 138 } // namespace SecurityStyle 139 140 namespace CertError { 141 142 enum CertErrorFlags { 143 NONE = 0 144 }; 145 146 void Check(const NavigationEntry& entry, net::CertStatus error) { 147 if (error) { 148 EXPECT_EQ(error, entry.GetSSL().cert_status & error); 149 net::CertStatus extra_cert_errors = 150 error ^ (entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS); 151 if (extra_cert_errors) 152 LOG(WARNING) << "Got unexpected cert error: " << extra_cert_errors; 153 } else { 154 EXPECT_EQ(0U, entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS); 155 } 156 } 157 158 } // namespace CertError 159 160 void CheckSecurityState(WebContents* tab, 161 net::CertStatus error, 162 content::SecurityStyle expected_security_style, 163 int expected_authentication_state) { 164 ASSERT_FALSE(tab->IsCrashed()); 165 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 166 ASSERT_TRUE(entry); 167 CertError::Check(*entry, error); 168 SecurityStyle::Check(*entry, expected_security_style); 169 AuthState::Check(*entry, expected_authentication_state); 170 } 171 172 } // namespace 173 174 class SSLUITest : public InProcessBrowserTest { 175 public: 176 SSLUITest() 177 : https_server_(net::SpawnedTestServer::TYPE_HTTPS, 178 SSLOptions(SSLOptions::CERT_OK), 179 base::FilePath(kDocRoot)), 180 https_server_expired_(net::SpawnedTestServer::TYPE_HTTPS, 181 SSLOptions(SSLOptions::CERT_EXPIRED), 182 base::FilePath(kDocRoot)), 183 https_server_mismatched_(net::SpawnedTestServer::TYPE_HTTPS, 184 SSLOptions(SSLOptions::CERT_MISMATCHED_NAME), 185 base::FilePath(kDocRoot)), 186 wss_server_expired_(net::SpawnedTestServer::TYPE_WSS, 187 SSLOptions(SSLOptions::CERT_EXPIRED), 188 net::GetWebSocketTestDataDirectory()) {} 189 190 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 191 // Browser will both run and display insecure content. 192 command_line->AppendSwitch(switches::kAllowRunningInsecureContent); 193 // Use process-per-site so that navigating to a same-site page in a 194 // new tab will use the same process. 195 command_line->AppendSwitch(switches::kProcessPerSite); 196 } 197 198 void CheckAuthenticatedState(WebContents* tab, 199 int expected_authentication_state) { 200 CheckSecurityState(tab, 201 CertError::NONE, 202 content::SECURITY_STYLE_AUTHENTICATED, 203 expected_authentication_state); 204 } 205 206 void CheckUnauthenticatedState(WebContents* tab, 207 int expected_authentication_state) { 208 CheckSecurityState(tab, 209 CertError::NONE, 210 content::SECURITY_STYLE_UNAUTHENTICATED, 211 expected_authentication_state); 212 } 213 214 void CheckAuthenticationBrokenState(WebContents* tab, 215 net::CertStatus error, 216 int expected_authentication_state) { 217 CheckSecurityState(tab, 218 error, 219 content::SECURITY_STYLE_AUTHENTICATION_BROKEN, 220 expected_authentication_state); 221 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION doesn't lower the security style 222 // to SECURITY_STYLE_AUTHENTICATION_BROKEN. 223 ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error); 224 } 225 226 void CheckWorkerLoadResult(WebContents* tab, bool expected_load) { 227 // Workers are async and we don't have notifications for them passing 228 // messages since they do it between renderer and worker processes. 229 // So have a polling loop, check every 200ms, timeout at 30s. 230 const int kTimeoutMS = 200; 231 base::Time time_to_quit = base::Time::Now() + 232 base::TimeDelta::FromMilliseconds(30000); 233 234 while (base::Time::Now() < time_to_quit) { 235 bool worker_finished = false; 236 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 237 tab, 238 "window.domAutomationController.send(IsWorkerFinished());", 239 &worker_finished)); 240 241 if (worker_finished) 242 break; 243 244 // Wait a bit. 245 base::MessageLoop::current()->PostDelayedTask( 246 FROM_HERE, 247 base::MessageLoop::QuitClosure(), 248 base::TimeDelta::FromMilliseconds(kTimeoutMS)); 249 content::RunMessageLoop(); 250 } 251 252 bool actually_loaded_content = false; 253 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 254 tab, 255 "window.domAutomationController.send(IsContentLoaded());", 256 &actually_loaded_content)); 257 EXPECT_EQ(expected_load, actually_loaded_content); 258 } 259 260 void ProceedThroughInterstitial(WebContents* tab) { 261 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 262 ASSERT_TRUE(interstitial_page); 263 content::WindowedNotificationObserver observer( 264 content::NOTIFICATION_LOAD_STOP, 265 content::Source<NavigationController>(&tab->GetController())); 266 interstitial_page->Proceed(); 267 observer.Wait(); 268 } 269 270 bool IsShowingWebContentsModalDialog() const { 271 return WebContentsModalDialogManager::FromWebContents( 272 browser()->tab_strip_model()->GetActiveWebContents())-> 273 IsDialogActive(); 274 } 275 276 static bool GetFilePathWithHostAndPortReplacement( 277 const std::string& original_file_path, 278 const net::HostPortPair& host_port_pair, 279 std::string* replacement_path) { 280 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 281 replacement_text.push_back( 282 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString())); 283 return net::SpawnedTestServer::GetFilePathWithReplacements( 284 original_file_path, replacement_text, replacement_path); 285 } 286 287 static bool GetTopFramePath(const net::SpawnedTestServer& http_server, 288 const net::SpawnedTestServer& good_https_server, 289 const net::SpawnedTestServer& bad_https_server, 290 std::string* top_frame_path) { 291 // The "frame_left.html" page contained in the top_frame.html page contains 292 // <a href>'s to three different servers. This sets up all of the 293 // replacement text to work with test servers which listen on ephemeral 294 // ports. 295 GURL http_url = http_server.GetURL("files/ssl/google.html"); 296 GURL good_https_url = good_https_server.GetURL("files/ssl/google.html"); 297 GURL bad_https_url = bad_https_server.GetURL( 298 "files/ssl/bad_iframe.html"); 299 300 std::vector<net::SpawnedTestServer::StringPair> replacement_text_frame_left; 301 replacement_text_frame_left.push_back( 302 make_pair("REPLACE_WITH_HTTP_PAGE", http_url.spec())); 303 replacement_text_frame_left.push_back( 304 make_pair("REPLACE_WITH_GOOD_HTTPS_PAGE", good_https_url.spec())); 305 replacement_text_frame_left.push_back( 306 make_pair("REPLACE_WITH_BAD_HTTPS_PAGE", bad_https_url.spec())); 307 std::string frame_left_path; 308 if (!net::SpawnedTestServer::GetFilePathWithReplacements( 309 "frame_left.html", 310 replacement_text_frame_left, 311 &frame_left_path)) 312 return false; 313 314 // Substitute the generated frame_left URL into the top_frame page. 315 std::vector<net::SpawnedTestServer::StringPair> replacement_text_top_frame; 316 replacement_text_top_frame.push_back( 317 make_pair("REPLACE_WITH_FRAME_LEFT_PATH", frame_left_path)); 318 return net::SpawnedTestServer::GetFilePathWithReplacements( 319 "files/ssl/top_frame.html", 320 replacement_text_top_frame, 321 top_frame_path); 322 } 323 324 static bool GetPageWithUnsafeWorkerPath( 325 const net::SpawnedTestServer& expired_https_server, 326 std::string* page_with_unsafe_worker_path) { 327 // Get the "imported.js" URL from the expired https server and 328 // substitute it into the unsafe_worker.js file. 329 GURL imported_js_url = expired_https_server.GetURL("files/ssl/imported.js"); 330 std::vector<net::SpawnedTestServer::StringPair> 331 replacement_text_for_unsafe_worker; 332 replacement_text_for_unsafe_worker.push_back( 333 make_pair("REPLACE_WITH_IMPORTED_JS_URL", imported_js_url.spec())); 334 std::string unsafe_worker_path; 335 if (!net::SpawnedTestServer::GetFilePathWithReplacements( 336 "unsafe_worker.js", 337 replacement_text_for_unsafe_worker, 338 &unsafe_worker_path)) 339 return false; 340 341 // Now, substitute this into the page with unsafe worker. 342 std::vector<net::SpawnedTestServer::StringPair> 343 replacement_text_for_page_with_unsafe_worker; 344 replacement_text_for_page_with_unsafe_worker.push_back( 345 make_pair("REPLACE_WITH_UNSAFE_WORKER_PATH", unsafe_worker_path)); 346 return net::SpawnedTestServer::GetFilePathWithReplacements( 347 "files/ssl/page_with_unsafe_worker.html", 348 replacement_text_for_page_with_unsafe_worker, 349 page_with_unsafe_worker_path); 350 } 351 352 net::SpawnedTestServer https_server_; 353 net::SpawnedTestServer https_server_expired_; 354 net::SpawnedTestServer https_server_mismatched_; 355 net::SpawnedTestServer wss_server_expired_; 356 357 private: 358 typedef net::SpawnedTestServer::SSLOptions SSLOptions; 359 360 DISALLOW_COPY_AND_ASSIGN(SSLUITest); 361 }; 362 363 class SSLUITestBlock : public SSLUITest { 364 public: 365 SSLUITestBlock() : SSLUITest() {} 366 367 // Browser will neither run nor display insecure content. 368 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 369 command_line->AppendSwitch(switches::kNoDisplayingInsecureContent); 370 } 371 }; 372 373 class SSLUITestIgnoreCertErrors : public SSLUITest { 374 public: 375 SSLUITestIgnoreCertErrors() : SSLUITest() {} 376 377 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 378 // Browser will ignore certificate errors. 379 command_line->AppendSwitch(switches::kIgnoreCertificateErrors); 380 } 381 }; 382 383 // Visits a regular page over http. 384 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) { 385 ASSERT_TRUE(test_server()->Start()); 386 387 ui_test_utils::NavigateToURL(browser(), 388 test_server()->GetURL("files/ssl/google.html")); 389 390 CheckUnauthenticatedState( 391 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE); 392 } 393 394 // Visits a page over http which includes broken https resources (status should 395 // be OK). 396 // TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give 397 // the secure cookies away!). 398 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) { 399 ASSERT_TRUE(test_server()->Start()); 400 ASSERT_TRUE(https_server_expired_.Start()); 401 402 std::string replacement_path; 403 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 404 "files/ssl/page_with_unsafe_contents.html", 405 https_server_expired_.host_port_pair(), 406 &replacement_path)); 407 408 ui_test_utils::NavigateToURL( 409 browser(), test_server()->GetURL(replacement_path)); 410 411 CheckUnauthenticatedState( 412 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE); 413 } 414 415 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSWithInsecureContent) { 416 ASSERT_TRUE(test_server()->Start()); 417 ASSERT_TRUE(https_server_expired_.Start()); 418 419 std::string replacement_path; 420 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 421 "files/ssl/page_displays_insecure_content.html", 422 test_server()->host_port_pair(), 423 &replacement_path)); 424 425 ui_test_utils::NavigateToURL(browser(), 426 https_server_expired_.GetURL(replacement_path)); 427 428 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 429 CheckAuthenticationBrokenState( 430 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 431 432 ProceedThroughInterstitial(tab); 433 434 CheckAuthenticationBrokenState(tab, 435 net::CERT_STATUS_DATE_INVALID, 436 AuthState::DISPLAYED_INSECURE_CONTENT); 437 } 438 439 // http://crbug.com/91745 440 #if defined(OS_CHROMEOS) 441 #define MAYBE_TestOKHTTPS DISABLED_TestOKHTTPS 442 #else 443 #define MAYBE_TestOKHTTPS TestOKHTTPS 444 #endif 445 446 // Visits a page over OK https: 447 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestOKHTTPS) { 448 ASSERT_TRUE(https_server_.Start()); 449 450 ui_test_utils::NavigateToURL(browser(), 451 https_server_.GetURL("files/ssl/google.html")); 452 453 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 454 AuthState::NONE); 455 } 456 457 // Visits a page with https error and proceed: 458 #if defined(OS_LINUX) 459 // flaky http://crbug.com/396462 460 #define MAYBE_TestHTTPSExpiredCertAndProceed \ 461 DISABLED_TestHTTPSExpiredCertAndProceed 462 #else 463 #define MAYBE_TestHTTPSExpiredCertAndProceed TestHTTPSExpiredCertAndProceed 464 #endif 465 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndProceed) { 466 ASSERT_TRUE(https_server_expired_.Start()); 467 468 ui_test_utils::NavigateToURL(browser(), 469 https_server_expired_.GetURL("files/ssl/google.html")); 470 471 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 472 CheckAuthenticationBrokenState( 473 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 474 475 ProceedThroughInterstitial(tab); 476 477 CheckAuthenticationBrokenState( 478 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 479 } 480 481 #ifndef NEDBUG 482 // Flaky on Windows debug (http://crbug.com/280537). 483 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \ 484 DISABLED_TestHTTPSExpiredCertAndDontProceed 485 #else 486 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \ 487 TestHTTPSExpiredCertAndDontProceed 488 #endif 489 490 // Visits a page with https error and don't proceed (and ensure we can still 491 // navigate at that point): 492 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) { 493 ASSERT_TRUE(test_server()->Start()); 494 ASSERT_TRUE(https_server_.Start()); 495 ASSERT_TRUE(https_server_expired_.Start()); 496 497 // First navigate to an OK page. 498 ui_test_utils::NavigateToURL(browser(), 499 https_server_.GetURL("files/ssl/google.html")); 500 501 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 502 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 503 ASSERT_TRUE(entry); 504 505 GURL cross_site_url = 506 https_server_expired_.GetURL("files/ssl/google.html"); 507 // Change the host name from 127.0.0.1 to localhost so it triggers a 508 // cross-site navigation so we can test http://crbug.com/5800 is gone. 509 ASSERT_EQ("127.0.0.1", cross_site_url.host()); 510 GURL::Replacements replacements; 511 std::string new_host("localhost"); 512 replacements.SetHostStr(new_host); 513 cross_site_url = cross_site_url.ReplaceComponents(replacements); 514 515 // Now go to a bad HTTPS page. 516 ui_test_utils::NavigateToURL(browser(), cross_site_url); 517 518 // An interstitial should be showing. 519 CheckAuthenticationBrokenState(tab, 520 net::CERT_STATUS_COMMON_NAME_INVALID, 521 AuthState::SHOWING_INTERSTITIAL); 522 523 // Simulate user clicking "Take me back". 524 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 525 ASSERT_TRUE(interstitial_page); 526 interstitial_page->DontProceed(); 527 528 // We should be back to the original good page. 529 CheckAuthenticatedState(tab, AuthState::NONE); 530 531 // Try to navigate to a new page. (to make sure bug 5800 is fixed). 532 ui_test_utils::NavigateToURL(browser(), 533 test_server()->GetURL("files/ssl/google.html")); 534 CheckUnauthenticatedState(tab, AuthState::NONE); 535 } 536 537 // Visits a page with https error and then goes back using Browser::GoBack. 538 IN_PROC_BROWSER_TEST_F(SSLUITest, 539 TestHTTPSExpiredCertAndGoBackViaButton) { 540 ASSERT_TRUE(test_server()->Start()); 541 ASSERT_TRUE(https_server_expired_.Start()); 542 543 // First navigate to an HTTP page. 544 ui_test_utils::NavigateToURL(browser(), 545 test_server()->GetURL("files/ssl/google.html")); 546 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 547 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 548 ASSERT_TRUE(entry); 549 550 // Now go to a bad HTTPS page that shows an interstitial. 551 ui_test_utils::NavigateToURL(browser(), 552 https_server_expired_.GetURL("files/ssl/google.html")); 553 CheckAuthenticationBrokenState( 554 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 555 556 ProvisionalLoadWaiter load_failed_observer(tab); 557 558 // Simulate user clicking on back button (crbug.com/39248). 559 chrome::GoBack(browser(), CURRENT_TAB); 560 561 // Wait until we hear the load failure, and make sure we haven't swapped out 562 // the previous page. Prevents regression of http://crbug.com/82667. 563 load_failed_observer.Wait(); 564 EXPECT_FALSE(content::RenderViewHostTester::IsRenderViewHostSwappedOut( 565 tab->GetRenderViewHost())); 566 567 // We should be back at the original good page. 568 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()-> 569 GetInterstitialPage()); 570 CheckUnauthenticatedState(tab, AuthState::NONE); 571 } 572 573 // Visits a page with https error and then goes back using GoToOffset. 574 // Disabled because its flaky: http://crbug.com/40932, http://crbug.com/43575. 575 IN_PROC_BROWSER_TEST_F(SSLUITest, 576 TestHTTPSExpiredCertAndGoBackViaMenu) { 577 ASSERT_TRUE(test_server()->Start()); 578 ASSERT_TRUE(https_server_expired_.Start()); 579 580 // First navigate to an HTTP page. 581 ui_test_utils::NavigateToURL(browser(), 582 test_server()->GetURL("files/ssl/google.html")); 583 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 584 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 585 ASSERT_TRUE(entry); 586 587 // Now go to a bad HTTPS page that shows an interstitial. 588 ui_test_utils::NavigateToURL(browser(), 589 https_server_expired_.GetURL("files/ssl/google.html")); 590 CheckAuthenticationBrokenState( 591 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 592 593 // Simulate user clicking and holding on back button (crbug.com/37215). 594 tab->GetController().GoToOffset(-1); 595 596 // We should be back at the original good page. 597 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()-> 598 GetInterstitialPage()); 599 CheckUnauthenticatedState(tab, AuthState::NONE); 600 } 601 602 // Visits a page with https error and then goes forward using GoToOffset. 603 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoForward) { 604 ASSERT_TRUE(test_server()->Start()); 605 ASSERT_TRUE(https_server_expired_.Start()); 606 607 // First navigate to two HTTP pages. 608 ui_test_utils::NavigateToURL(browser(), 609 test_server()->GetURL("files/ssl/google.html")); 610 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 611 NavigationEntry* entry1 = tab->GetController().GetActiveEntry(); 612 ASSERT_TRUE(entry1); 613 ui_test_utils::NavigateToURL(browser(), 614 test_server()->GetURL("files/ssl/blank_page.html")); 615 NavigationEntry* entry2 = tab->GetController().GetActiveEntry(); 616 ASSERT_TRUE(entry2); 617 618 // Now go back so that a page is in the forward history. 619 { 620 content::WindowedNotificationObserver observer( 621 content::NOTIFICATION_LOAD_STOP, 622 content::Source<NavigationController>(&tab->GetController())); 623 tab->GetController().GoBack(); 624 observer.Wait(); 625 } 626 ASSERT_TRUE(tab->GetController().CanGoForward()); 627 NavigationEntry* entry3 = tab->GetController().GetActiveEntry(); 628 ASSERT_TRUE(entry1 == entry3); 629 630 // Now go to a bad HTTPS page that shows an interstitial. 631 ui_test_utils::NavigateToURL(browser(), 632 https_server_expired_.GetURL("files/ssl/google.html")); 633 CheckAuthenticationBrokenState( 634 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 635 636 // Simulate user clicking and holding on forward button. 637 { 638 content::WindowedNotificationObserver observer( 639 content::NOTIFICATION_LOAD_STOP, 640 content::Source<NavigationController>(&tab->GetController())); 641 tab->GetController().GoToOffset(1); 642 observer.Wait(); 643 } 644 645 // We should be showing the second good page. 646 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()-> 647 GetInterstitialPage()); 648 CheckUnauthenticatedState(tab, AuthState::NONE); 649 EXPECT_FALSE(tab->GetController().CanGoForward()); 650 NavigationEntry* entry4 = tab->GetController().GetActiveEntry(); 651 EXPECT_TRUE(entry2 == entry4); 652 } 653 654 // Visit a HTTP page which request WSS connection to a server providing invalid 655 // certificate. Close the page while WSS connection waits for SSLManager's 656 // response from UI thread. 657 // Disabled on Windows because it was flaking on XP Tests (1). crbug.com/165258 658 #if defined(OS_WIN) 659 #define MAYBE_TestWSSInvalidCertAndClose DISABLED_TestWSSInvalidCertAndClose 660 #else 661 #define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose 662 #endif 663 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) { 664 ASSERT_TRUE(test_server()->Start()); 665 ASSERT_TRUE(wss_server_expired_.Start()); 666 667 // Setup page title observer. 668 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 669 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 670 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 671 672 // Create GURLs to test pages. 673 std::string master_url_path = base::StringPrintf("%s?%d", 674 test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(), 675 wss_server_expired_.host_port_pair().port()); 676 GURL master_url(master_url_path); 677 std::string slave_url_path = base::StringPrintf("%s?%d", 678 test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(), 679 wss_server_expired_.host_port_pair().port()); 680 GURL slave_url(slave_url_path); 681 682 // Create tabs and visit pages which keep on creating wss connections. 683 WebContents* tabs[16]; 684 for (int i = 0; i < 16; ++i) { 685 tabs[i] = chrome::AddSelectedTabWithURL(browser(), slave_url, 686 ui::PAGE_TRANSITION_LINK); 687 } 688 chrome::SelectNextTab(browser()); 689 690 // Visit a page which waits for one TLS handshake failure. 691 // The title will be changed to 'PASS'. 692 ui_test_utils::NavigateToURL(browser(), master_url); 693 const base::string16 result = watcher.WaitAndGetTitle(); 694 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 695 696 // Close tabs which contains the test page. 697 for (int i = 0; i < 16; ++i) 698 chrome::CloseWebContents(browser(), tabs[i], false); 699 chrome::CloseWebContents(browser(), tab, false); 700 } 701 702 // Visit a HTTPS page and proceeds despite an invalid certificate. The page 703 // requests WSS connection to the same origin host to check if WSS connection 704 // share certificates policy with HTTPS correcly. 705 IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) { 706 ASSERT_TRUE(test_server()->Start()); 707 ASSERT_TRUE(wss_server_expired_.Start()); 708 709 // Setup page title observer. 710 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 711 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 712 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 713 714 // Visit bad HTTPS page. 715 std::string scheme("https"); 716 GURL::Replacements replacements; 717 replacements.SetSchemeStr(scheme); 718 ui_test_utils::NavigateToURL( 719 browser(), 720 wss_server_expired_.GetURL( 721 "connect_check.html").ReplaceComponents(replacements)); 722 CheckAuthenticationBrokenState( 723 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 724 725 // Proceed anyway. 726 ProceedThroughInterstitial(tab); 727 728 // Test page run a WebSocket wss connection test. The result will be shown 729 // as page title. 730 const base::string16 result = watcher.WaitAndGetTitle(); 731 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 732 } 733 734 #if defined(USE_NSS) 735 class SSLUITestWithClientCert : public SSLUITest { 736 public: 737 SSLUITestWithClientCert() : cert_db_(NULL) {} 738 739 virtual void SetUpOnMainThread() OVERRIDE { 740 SSLUITest::SetUpOnMainThread(); 741 742 base::RunLoop loop; 743 GetNSSCertDatabaseForProfile( 744 browser()->profile(), 745 base::Bind(&SSLUITestWithClientCert::DidGetCertDatabase, 746 base::Unretained(this), 747 &loop)); 748 loop.Run(); 749 } 750 751 protected: 752 void DidGetCertDatabase(base::RunLoop* loop, net::NSSCertDatabase* cert_db) { 753 cert_db_ = cert_db; 754 loop->Quit(); 755 } 756 757 net::NSSCertDatabase* cert_db_; 758 }; 759 760 // SSL client certificate tests are only enabled when using NSS for private key 761 // storage, as only NSS can avoid modifying global machine state when testing. 762 // See http://crbug.com/51132 763 764 // Visit a HTTPS page which requires client cert authentication. The client 765 // cert will be selected automatically, then a test which uses WebSocket runs. 766 IN_PROC_BROWSER_TEST_F(SSLUITestWithClientCert, TestWSSClientCert) { 767 // Import a client cert for test. 768 scoped_refptr<net::CryptoModule> crypt_module = cert_db_->GetPublicModule(); 769 std::string pkcs12_data; 770 base::FilePath cert_path = net::GetTestCertsDirectory().Append( 771 FILE_PATH_LITERAL("websocket_client_cert.p12")); 772 EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data)); 773 EXPECT_EQ(net::OK, 774 cert_db_->ImportFromPKCS12( 775 crypt_module.get(), pkcs12_data, base::string16(), true, NULL)); 776 777 // Start WebSocket test server with TLS and client cert authentication. 778 net::SpawnedTestServer::SSLOptions options( 779 net::SpawnedTestServer::SSLOptions::CERT_OK); 780 options.request_client_certificate = true; 781 base::FilePath ca_path = net::GetTestCertsDirectory().Append( 782 FILE_PATH_LITERAL("websocket_cacert.pem")); 783 options.client_authorities.push_back(ca_path); 784 net::SpawnedTestServer wss_server(net::SpawnedTestServer::TYPE_WSS, 785 options, 786 net::GetWebSocketTestDataDirectory()); 787 ASSERT_TRUE(wss_server.Start()); 788 std::string scheme("https"); 789 GURL::Replacements replacements; 790 replacements.SetSchemeStr(scheme); 791 GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents( 792 replacements); 793 794 // Setup page title observer. 795 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 796 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 797 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 798 799 // Add an entry into AutoSelectCertificateForUrls policy for automatic client 800 // cert selection. 801 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); 802 DCHECK(profile); 803 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 804 dict->SetString("ISSUER.CN", "pywebsocket"); 805 profile->GetHostContentSettingsMap()->SetWebsiteSetting( 806 ContentSettingsPattern::FromURL(url), 807 ContentSettingsPattern::FromURL(url), 808 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 809 std::string(), 810 dict.release()); 811 812 // Visit a HTTPS page which requires client certs. 813 ui_test_utils::NavigateToURL(browser(), url); 814 CheckAuthenticatedState(tab, AuthState::NONE); 815 816 // Test page runs a WebSocket wss connection test. The result will be shown 817 // as page title. 818 const base::string16 result = watcher.WaitAndGetTitle(); 819 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 820 } 821 #endif // defined(USE_NSS) 822 823 // Flaky on CrOS http://crbug.com/92292 824 #if defined(OS_CHROMEOS) 825 #define MAYBE_TestHTTPSErrorWithNoNavEntry \ 826 DISABLED_TestHTTPSErrorWithNoNavEntry 827 #else 828 #define MAYBE_TestHTTPSErrorWithNoNavEntry TestHTTPSErrorWithNoNavEntry 829 #endif // defined(OS_CHROMEOS) 830 831 // Open a page with a HTTPS error in a tab with no prior navigation (through a 832 // link with a blank target). This is to test that the lack of navigation entry 833 // does not cause any problems (it was causing a crasher, see 834 // http://crbug.com/19941). 835 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) { 836 ASSERT_TRUE(https_server_expired_.Start()); 837 838 GURL url = https_server_expired_.GetURL("files/ssl/google.htm"); 839 WebContents* tab2 = chrome::AddSelectedTabWithURL( 840 browser(), url, ui::PAGE_TRANSITION_TYPED); 841 content::WaitForLoadStop(tab2); 842 843 // Verify our assumption that there was no prior navigation. 844 EXPECT_FALSE(chrome::CanGoBack(browser())); 845 846 // We should have an interstitial page showing. 847 ASSERT_TRUE(tab2->GetInterstitialPage()); 848 } 849 850 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) { 851 ASSERT_TRUE(test_server()->Start()); 852 ASSERT_TRUE(https_server_expired_.Start()); 853 GURL url_non_dangerous = test_server()->GetURL(std::string()); 854 GURL url_dangerous = 855 https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe"); 856 base::ScopedTempDir downloads_directory_; 857 858 // Need empty temp dir to avoid having Chrome ask us for a new filename 859 // when we've downloaded dangerous.exe one hundred times. 860 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); 861 862 browser()->profile()->GetPrefs()->SetFilePath( 863 prefs::kDownloadDefaultDirectory, 864 downloads_directory_.path()); 865 866 // Visit a non-dangerous page. 867 ui_test_utils::NavigateToURL(browser(), url_non_dangerous); 868 869 // Now, start a transition to dangerous download. 870 { 871 content::WindowedNotificationObserver observer( 872 content::NOTIFICATION_LOAD_STOP, 873 content::NotificationService::AllSources()); 874 chrome::NavigateParams navigate_params(browser(), url_dangerous, 875 ui::PAGE_TRANSITION_TYPED); 876 chrome::Navigate(&navigate_params); 877 observer.Wait(); 878 } 879 880 // To exit the browser cleanly (and this test) we need to complete the 881 // download after completing this test. 882 content::DownloadTestObserverTerminal dangerous_download_observer( 883 content::BrowserContext::GetDownloadManager(browser()->profile()), 884 1, 885 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT); 886 887 // Proceed through the SSL interstitial. This doesn't use 888 // |ProceedThroughInterstitial| since no page load will commit. 889 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 890 ASSERT_TRUE(tab != NULL); 891 ASSERT_TRUE(tab->GetInterstitialPage() != NULL); 892 { 893 content::WindowedNotificationObserver observer( 894 chrome::NOTIFICATION_DOWNLOAD_INITIATED, 895 content::NotificationService::AllSources()); 896 tab->GetInterstitialPage()->Proceed(); 897 observer.Wait(); 898 } 899 900 // There should still be an interstitial at this point. Press the 901 // back button on the browser. Note that this doesn't wait for a 902 // NAV_ENTRY_COMMITTED notification because going back with an 903 // active interstitial simply hides the interstitial. 904 ASSERT_TRUE(tab->GetInterstitialPage() != NULL); 905 EXPECT_TRUE(chrome::CanGoBack(browser())); 906 chrome::GoBack(browser(), CURRENT_TAB); 907 908 dangerous_download_observer.WaitForFinished(); 909 } 910 911 // 912 // Insecure content 913 // 914 915 #if defined(OS_WIN) 916 // http://crbug.com/152940 Flaky on win. 917 #define MAYBE_TestDisplaysInsecureContent DISABLED_TestDisplaysInsecureContent 918 #else 919 #define MAYBE_TestDisplaysInsecureContent TestDisplaysInsecureContent 920 #endif 921 922 // Visits a page that displays insecure content. 923 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) { 924 ASSERT_TRUE(test_server()->Start()); 925 ASSERT_TRUE(https_server_.Start()); 926 927 std::string replacement_path; 928 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 929 "files/ssl/page_displays_insecure_content.html", 930 test_server()->host_port_pair(), 931 &replacement_path)); 932 933 // Load a page that displays insecure content. 934 ui_test_utils::NavigateToURL(browser(), 935 https_server_.GetURL(replacement_path)); 936 937 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 938 AuthState::DISPLAYED_INSECURE_CONTENT); 939 } 940 941 // Visits a page that runs insecure content and tries to suppress the insecure 942 // content warnings by randomizing location.hash. 943 // Based on http://crbug.com/8706 944 IN_PROC_BROWSER_TEST_F(SSLUITest, 945 TestRunsInsecuredContentRandomizeHash) { 946 ASSERT_TRUE(test_server()->Start()); 947 ASSERT_TRUE(https_server_.Start()); 948 949 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 950 "files/ssl/page_runs_insecure_content.html")); 951 952 CheckAuthenticationBrokenState( 953 browser()->tab_strip_model()->GetActiveWebContents(), 954 CertError::NONE, 955 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 956 } 957 958 // Visits a page with unsafe content and make sure that: 959 // - frames content is replaced with warning 960 // - images and scripts are filtered out entirely 961 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) { 962 ASSERT_TRUE(https_server_.Start()); 963 ASSERT_TRUE(https_server_expired_.Start()); 964 965 std::string replacement_path; 966 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 967 "files/ssl/page_with_unsafe_contents.html", 968 https_server_expired_.host_port_pair(), 969 &replacement_path)); 970 ui_test_utils::NavigateToURL(browser(), 971 https_server_.GetURL(replacement_path)); 972 973 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 974 // When the bad content is filtered, the state is expected to be 975 // authenticated. 976 CheckAuthenticatedState(tab, AuthState::NONE); 977 978 // Because of cross-frame scripting restrictions, we cannot access the iframe 979 // content. So to know if the frame was loaded, we just check if a popup was 980 // opened (the iframe content opens one). 981 // Note: because of bug 1115868, no web contents modal dialog is opened right 982 // now. Once the bug is fixed, this will do the real check. 983 EXPECT_FALSE(IsShowingWebContentsModalDialog()); 984 985 int img_width; 986 EXPECT_TRUE(content::ExecuteScriptAndExtractInt( 987 tab, 988 "window.domAutomationController.send(ImageWidth());", 989 &img_width)); 990 // In order to check that the image was not loaded, we check its width. 991 // The actual image (Google logo) is 114 pixels wide, we assume the broken 992 // image is less than 100. 993 EXPECT_LT(img_width, 100); 994 995 bool js_result = false; 996 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 997 tab, 998 "window.domAutomationController.send(IsFooSet());", 999 &js_result)); 1000 EXPECT_FALSE(js_result); 1001 } 1002 1003 // Visits a page with insecure content loaded by JS (after the initial page 1004 // load). 1005 #if defined(OS_LINUX) 1006 // flaky http://crbug.com/396462 1007 #define MAYBE_TestDisplaysInsecureContentLoadedFromJS \ 1008 DISABLED_TestDisplaysInsecureContentLoadedFromJS 1009 #else 1010 #define MAYBE_TestDisplaysInsecureContentLoadedFromJS \ 1011 TestDisplaysInsecureContentLoadedFromJS 1012 #endif 1013 IN_PROC_BROWSER_TEST_F(SSLUITest, 1014 MAYBE_TestDisplaysInsecureContentLoadedFromJS) { 1015 ASSERT_TRUE(test_server()->Start()); 1016 ASSERT_TRUE(https_server_.Start()); 1017 1018 std::string replacement_path; 1019 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1020 "files/ssl/page_with_dynamic_insecure_content.html", 1021 test_server()->host_port_pair(), 1022 &replacement_path)); 1023 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 1024 replacement_path)); 1025 1026 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1027 CheckAuthenticatedState(tab, AuthState::NONE); 1028 1029 // Load the insecure image. 1030 bool js_result = false; 1031 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1032 tab, 1033 "loadBadImage();", 1034 &js_result)); 1035 EXPECT_TRUE(js_result); 1036 1037 // We should now have insecure content. 1038 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT); 1039 } 1040 1041 // Visits two pages from the same origin: one that displays insecure content and 1042 // one that doesn't. The test checks that we do not propagate the insecure 1043 // content state from one to the other. 1044 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) { 1045 ASSERT_TRUE(test_server()->Start()); 1046 ASSERT_TRUE(https_server_.Start()); 1047 1048 ui_test_utils::NavigateToURL(browser(), 1049 https_server_.GetURL("files/ssl/blank_page.html")); 1050 1051 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents(); 1052 1053 // This tab should be fine. 1054 CheckAuthenticatedState(tab1, AuthState::NONE); 1055 1056 // Create a new tab. 1057 std::string replacement_path; 1058 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1059 "files/ssl/page_displays_insecure_content.html", 1060 test_server()->host_port_pair(), 1061 &replacement_path)); 1062 1063 GURL url = https_server_.GetURL(replacement_path); 1064 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED); 1065 params.disposition = NEW_FOREGROUND_TAB; 1066 params.tabstrip_index = 0; 1067 params.source_contents = tab1; 1068 content::WindowedNotificationObserver observer( 1069 content::NOTIFICATION_LOAD_STOP, 1070 content::NotificationService::AllSources()); 1071 chrome::Navigate(¶ms); 1072 WebContents* tab2 = params.target_contents; 1073 observer.Wait(); 1074 1075 // The new tab has insecure content. 1076 CheckAuthenticatedState(tab2, AuthState::DISPLAYED_INSECURE_CONTENT); 1077 1078 // The original tab should not be contaminated. 1079 CheckAuthenticatedState(tab1, AuthState::NONE); 1080 } 1081 1082 // Visits two pages from the same origin: one that runs insecure content and one 1083 // that doesn't. The test checks that we propagate the insecure content state 1084 // from one to the other. 1085 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) { 1086 ASSERT_TRUE(test_server()->Start()); 1087 ASSERT_TRUE(https_server_.Start()); 1088 1089 ui_test_utils::NavigateToURL(browser(), 1090 https_server_.GetURL("files/ssl/blank_page.html")); 1091 1092 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents(); 1093 1094 // This tab should be fine. 1095 CheckAuthenticatedState(tab1, AuthState::NONE); 1096 1097 std::string replacement_path; 1098 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1099 "files/ssl/page_runs_insecure_content.html", 1100 test_server()->host_port_pair(), 1101 &replacement_path)); 1102 1103 // Create a new tab in the same process. Using a NEW_FOREGROUND_TAB 1104 // disposition won't usually stay in the same process, but this works 1105 // because we are using process-per-site in SetUpCommandLine. 1106 GURL url = https_server_.GetURL(replacement_path); 1107 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED); 1108 params.disposition = NEW_FOREGROUND_TAB; 1109 params.source_contents = tab1; 1110 content::WindowedNotificationObserver observer( 1111 content::NOTIFICATION_LOAD_STOP, 1112 content::NotificationService::AllSources()); 1113 chrome::Navigate(¶ms); 1114 WebContents* tab2 = params.target_contents; 1115 observer.Wait(); 1116 1117 // Both tabs should have the same process. 1118 EXPECT_EQ(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost()); 1119 1120 // The new tab has insecure content. 1121 CheckAuthenticationBrokenState( 1122 tab2, 1123 CertError::NONE, 1124 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1125 1126 // Which means the origin for the first tab has also been contaminated with 1127 // insecure content. 1128 CheckAuthenticationBrokenState( 1129 tab1, CertError::NONE, AuthState::RAN_INSECURE_CONTENT); 1130 } 1131 1132 // Visits a page with an image over http. Visits another page over https 1133 // referencing that same image over http (hoping it is coming from the webcore 1134 // memory cache). 1135 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) { 1136 ASSERT_TRUE(test_server()->Start()); 1137 ASSERT_TRUE(https_server_.Start()); 1138 1139 std::string replacement_path; 1140 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1141 "files/ssl/page_displays_insecure_content.html", 1142 test_server()->host_port_pair(), 1143 &replacement_path)); 1144 1145 // Load original page over HTTP. 1146 const GURL url_http = test_server()->GetURL(replacement_path); 1147 ui_test_utils::NavigateToURL(browser(), url_http); 1148 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1149 CheckUnauthenticatedState(tab, AuthState::NONE); 1150 1151 // Load again but over SSL. It should be marked as displaying insecure 1152 // content (even though the image comes from the WebCore memory cache). 1153 const GURL url_https = https_server_.GetURL(replacement_path); 1154 ui_test_utils::NavigateToURL(browser(), url_https); 1155 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT); 1156 } 1157 1158 // http://crbug.com/84729 1159 #if defined(OS_CHROMEOS) 1160 #define MAYBE_TestRunsCachedInsecureContent \ 1161 DISABLED_TestRunsCachedInsecureContent 1162 #else 1163 #define MAYBE_TestRunsCachedInsecureContent TestRunsCachedInsecureContent 1164 #endif // defined(OS_CHROMEOS) 1165 1166 // Visits a page with script over http. Visits another page over https 1167 // referencing that same script over http (hoping it is coming from the webcore 1168 // memory cache). 1169 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) { 1170 ASSERT_TRUE(test_server()->Start()); 1171 ASSERT_TRUE(https_server_.Start()); 1172 1173 std::string replacement_path; 1174 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1175 "files/ssl/page_runs_insecure_content.html", 1176 test_server()->host_port_pair(), 1177 &replacement_path)); 1178 1179 // Load original page over HTTP. 1180 const GURL url_http = test_server()->GetURL(replacement_path); 1181 ui_test_utils::NavigateToURL(browser(), url_http); 1182 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1183 CheckUnauthenticatedState(tab, AuthState::NONE); 1184 1185 // Load again but over SSL. It should be marked as displaying insecure 1186 // content (even though the image comes from the WebCore memory cache). 1187 const GURL url_https = https_server_.GetURL(replacement_path); 1188 ui_test_utils::NavigateToURL(browser(), url_https); 1189 CheckAuthenticationBrokenState( 1190 tab, 1191 CertError::NONE, 1192 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1193 } 1194 1195 // This test ensures the CN invalid status does not 'stick' to a certificate 1196 // (see bug #1044942) and that it depends on the host-name. 1197 // Test if disabled due to flakiness http://crbug.com/368280 . 1198 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) { 1199 ASSERT_TRUE(https_server_.Start()); 1200 ASSERT_TRUE(https_server_mismatched_.Start()); 1201 1202 // First we hit the server with hostname, this generates an invalid policy 1203 // error. 1204 ui_test_utils::NavigateToURL(browser(), 1205 https_server_mismatched_.GetURL("files/ssl/google.html")); 1206 1207 // We get an interstitial page as a result. 1208 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1209 CheckAuthenticationBrokenState(tab, 1210 net::CERT_STATUS_COMMON_NAME_INVALID, 1211 AuthState::SHOWING_INTERSTITIAL); 1212 ProceedThroughInterstitial(tab); 1213 CheckAuthenticationBrokenState( 1214 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE); 1215 1216 // Now we try again with the right host name this time. 1217 GURL url(https_server_.GetURL("files/ssl/google.html")); 1218 ui_test_utils::NavigateToURL(browser(), url); 1219 1220 // Security state should be OK. 1221 CheckAuthenticatedState(tab, AuthState::NONE); 1222 1223 // Now try again the broken one to make sure it is still broken. 1224 ui_test_utils::NavigateToURL(browser(), 1225 https_server_mismatched_.GetURL("files/ssl/google.html")); 1226 1227 // Since we OKed the interstitial last time, we get right to the page. 1228 CheckAuthenticationBrokenState( 1229 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE); 1230 } 1231 1232 #if defined(OS_CHROMEOS) 1233 // This test seems to be flaky and hang on chromiumos. 1234 // http://crbug.com/84419 1235 #define MAYBE_TestRefNavigation DISABLED_TestRefNavigation 1236 #else 1237 #define MAYBE_TestRefNavigation TestRefNavigation 1238 #endif 1239 1240 // Test that navigating to a #ref does not change a bad security state. 1241 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) { 1242 ASSERT_TRUE(https_server_expired_.Start()); 1243 1244 ui_test_utils::NavigateToURL(browser(), 1245 https_server_expired_.GetURL("files/ssl/page_with_refs.html")); 1246 1247 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1248 CheckAuthenticationBrokenState( 1249 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1250 1251 ProceedThroughInterstitial(tab); 1252 1253 CheckAuthenticationBrokenState( 1254 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1255 // Now navigate to a ref in the page, the security state should not have 1256 // changed. 1257 ui_test_utils::NavigateToURL(browser(), 1258 https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp")); 1259 1260 CheckAuthenticationBrokenState( 1261 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1262 } 1263 1264 // Tests that closing a page that has a unsafe pop-up does not crash the 1265 // browser (bug #1966). 1266 // TODO(jcampan): http://crbug.com/2136 disabled because the popup is not 1267 // opened as it is not initiated by a user gesture. 1268 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) { 1269 ASSERT_TRUE(test_server()->Start()); 1270 ASSERT_TRUE(https_server_expired_.Start()); 1271 1272 std::string replacement_path; 1273 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1274 "files/ssl/page_with_unsafe_popup.html", 1275 https_server_expired_.host_port_pair(), 1276 &replacement_path)); 1277 1278 ui_test_utils::NavigateToURL(browser(), 1279 test_server()->GetURL(replacement_path)); 1280 1281 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents(); 1282 // It is probably overkill to add a notification for a popup-opening, let's 1283 // just poll. 1284 for (int i = 0; i < 10; i++) { 1285 if (IsShowingWebContentsModalDialog()) 1286 break; 1287 base::MessageLoop::current()->PostDelayedTask( 1288 FROM_HERE, 1289 base::MessageLoop::QuitClosure(), 1290 base::TimeDelta::FromSeconds(1)); 1291 content::RunMessageLoop(); 1292 } 1293 ASSERT_TRUE(IsShowingWebContentsModalDialog()); 1294 1295 // Let's add another tab to make sure the browser does not exit when we close 1296 // the first tab. 1297 GURL url = test_server()->GetURL("files/ssl/google.html"); 1298 content::WindowedNotificationObserver observer( 1299 content::NOTIFICATION_LOAD_STOP, 1300 content::NotificationService::AllSources()); 1301 chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED); 1302 observer.Wait(); 1303 1304 // Close the first tab. 1305 chrome::CloseWebContents(browser(), tab1, false); 1306 } 1307 1308 // Visit a page over bad https that is a redirect to a page with good https. 1309 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) { 1310 ASSERT_TRUE(https_server_.Start()); 1311 ASSERT_TRUE(https_server_expired_.Start()); 1312 1313 GURL url1 = https_server_expired_.GetURL("server-redirect?"); 1314 GURL url2 = https_server_.GetURL("files/ssl/google.html"); 1315 1316 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); 1317 1318 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1319 1320 CheckAuthenticationBrokenState( 1321 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1322 1323 ProceedThroughInterstitial(tab); 1324 1325 // We have been redirected to the good page. 1326 CheckAuthenticatedState(tab, AuthState::NONE); 1327 } 1328 1329 // Flaky on Linux. http://crbug.com/368280. 1330 #if defined(OS_LINUX) 1331 #define MAYBE_TestRedirectGoodToBadHTTPS DISABLED_TestRedirectGoodToBadHTTPS 1332 #else 1333 #define MAYBE_TestRedirectGoodToBadHTTPS TestRedirectGoodToBadHTTPS 1334 #endif 1335 1336 // Visit a page over good https that is a redirect to a page with bad https. 1337 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectGoodToBadHTTPS) { 1338 ASSERT_TRUE(https_server_.Start()); 1339 ASSERT_TRUE(https_server_expired_.Start()); 1340 1341 GURL url1 = https_server_.GetURL("server-redirect?"); 1342 GURL url2 = https_server_expired_.GetURL("files/ssl/google.html"); 1343 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); 1344 1345 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1346 CheckAuthenticationBrokenState( 1347 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1348 1349 ProceedThroughInterstitial(tab); 1350 1351 CheckAuthenticationBrokenState( 1352 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1353 } 1354 1355 // Visit a page over http that is a redirect to a page with good HTTPS. 1356 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) { 1357 ASSERT_TRUE(test_server()->Start()); 1358 ASSERT_TRUE(https_server_.Start()); 1359 1360 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1361 1362 // HTTP redirects to good HTTPS. 1363 GURL http_url = test_server()->GetURL("server-redirect?"); 1364 GURL good_https_url = 1365 https_server_.GetURL("files/ssl/google.html"); 1366 1367 ui_test_utils::NavigateToURL(browser(), 1368 GURL(http_url.spec() + good_https_url.spec())); 1369 CheckAuthenticatedState(tab, AuthState::NONE); 1370 } 1371 1372 // Flaky on Linux. http://crbug.com/368280. 1373 #if defined(OS_LINUX) 1374 #define MAYBE_TestRedirectHTTPToBadHTTPS DISABLED_TestRedirectHTTPToBadHTTPS 1375 #else 1376 #define MAYBE_TestRedirectHTTPToBadHTTPS TestRedirectHTTPToBadHTTPS 1377 #endif 1378 1379 // Visit a page over http that is a redirect to a page with bad HTTPS. 1380 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectHTTPToBadHTTPS) { 1381 ASSERT_TRUE(test_server()->Start()); 1382 ASSERT_TRUE(https_server_expired_.Start()); 1383 1384 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1385 1386 GURL http_url = test_server()->GetURL("server-redirect?"); 1387 GURL bad_https_url = 1388 https_server_expired_.GetURL("files/ssl/google.html"); 1389 ui_test_utils::NavigateToURL(browser(), 1390 GURL(http_url.spec() + bad_https_url.spec())); 1391 CheckAuthenticationBrokenState( 1392 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1393 1394 ProceedThroughInterstitial(tab); 1395 1396 CheckAuthenticationBrokenState( 1397 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1398 } 1399 1400 // Visit a page over https that is a redirect to a page with http (to make sure 1401 // we don't keep the secure state). 1402 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) { 1403 ASSERT_TRUE(test_server()->Start()); 1404 ASSERT_TRUE(https_server_.Start()); 1405 1406 GURL https_url = https_server_.GetURL("server-redirect?"); 1407 GURL http_url = test_server()->GetURL("files/ssl/google.html"); 1408 1409 ui_test_utils::NavigateToURL(browser(), 1410 GURL(https_url.spec() + http_url.spec())); 1411 CheckUnauthenticatedState( 1412 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE); 1413 } 1414 1415 // Visits a page to which we could not connect (bad port) over http and https 1416 // and make sure the security style is correct. 1417 IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) { 1418 ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17")); 1419 CheckUnauthenticatedState( 1420 browser()->tab_strip_model()->GetActiveWebContents(), 1421 AuthState::SHOWING_ERROR); 1422 1423 // Same thing over HTTPS. 1424 ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17")); 1425 CheckUnauthenticatedState( 1426 browser()->tab_strip_model()->GetActiveWebContents(), 1427 AuthState::SHOWING_ERROR); 1428 } 1429 1430 // 1431 // Frame navigation 1432 // 1433 1434 // From a good HTTPS top frame: 1435 // - navigate to an OK HTTPS frame 1436 // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then 1437 // back 1438 // - navigate to HTTP (expect insecure content), then back 1439 IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) { 1440 ASSERT_TRUE(test_server()->Start()); 1441 ASSERT_TRUE(https_server_.Start()); 1442 ASSERT_TRUE(https_server_expired_.Start()); 1443 1444 std::string top_frame_path; 1445 ASSERT_TRUE(GetTopFramePath(*test_server(), 1446 https_server_, 1447 https_server_expired_, 1448 &top_frame_path)); 1449 1450 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1451 ui_test_utils::NavigateToURL(browser(), 1452 https_server_.GetURL(top_frame_path)); 1453 1454 CheckAuthenticatedState(tab, AuthState::NONE); 1455 1456 bool success = false; 1457 // Now navigate inside the frame. 1458 { 1459 content::WindowedNotificationObserver observer( 1460 content::NOTIFICATION_LOAD_STOP, 1461 content::Source<NavigationController>(&tab->GetController())); 1462 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1463 tab, 1464 "window.domAutomationController.send(clickLink('goodHTTPSLink'));", 1465 &success)); 1466 ASSERT_TRUE(success); 1467 observer.Wait(); 1468 } 1469 1470 // We should still be fine. 1471 CheckAuthenticatedState(tab, AuthState::NONE); 1472 1473 // Now let's hit a bad page. 1474 { 1475 content::WindowedNotificationObserver observer( 1476 content::NOTIFICATION_LOAD_STOP, 1477 content::Source<NavigationController>(&tab->GetController())); 1478 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1479 tab, 1480 "window.domAutomationController.send(clickLink('badHTTPSLink'));", 1481 &success)); 1482 ASSERT_TRUE(success); 1483 observer.Wait(); 1484 } 1485 1486 // The security style should still be secure. 1487 CheckAuthenticatedState(tab, AuthState::NONE); 1488 1489 // And the frame should be blocked. 1490 bool is_content_evil = true; 1491 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate( 1492 tab, base::Bind(&content::FrameMatchesName, "contentFrame")); 1493 std::string is_evil_js("window.domAutomationController.send(" 1494 "document.getElementById('evilDiv') != null);"); 1495 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame, 1496 is_evil_js, 1497 &is_content_evil)); 1498 EXPECT_FALSE(is_content_evil); 1499 1500 // Now go back, our state should still be OK. 1501 { 1502 content::WindowedNotificationObserver observer( 1503 content::NOTIFICATION_LOAD_STOP, 1504 content::Source<NavigationController>(&tab->GetController())); 1505 tab->GetController().GoBack(); 1506 observer.Wait(); 1507 } 1508 CheckAuthenticatedState(tab, AuthState::NONE); 1509 1510 // Navigate to a page served over HTTP. 1511 { 1512 content::WindowedNotificationObserver observer( 1513 content::NOTIFICATION_LOAD_STOP, 1514 content::Source<NavigationController>(&tab->GetController())); 1515 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1516 tab, 1517 "window.domAutomationController.send(clickLink('HTTPLink'));", 1518 &success)); 1519 ASSERT_TRUE(success); 1520 observer.Wait(); 1521 } 1522 1523 // Our state should be unathenticated (in the ran mixed script sense) 1524 CheckAuthenticationBrokenState( 1525 tab, 1526 CertError::NONE, 1527 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1528 1529 // Go back, our state should be unchanged. 1530 { 1531 content::WindowedNotificationObserver observer( 1532 content::NOTIFICATION_LOAD_STOP, 1533 content::Source<NavigationController>(&tab->GetController())); 1534 tab->GetController().GoBack(); 1535 observer.Wait(); 1536 } 1537 1538 CheckAuthenticationBrokenState( 1539 tab, 1540 CertError::NONE, 1541 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1542 } 1543 1544 // From a bad HTTPS top frame: 1545 // - navigate to an OK HTTPS frame (expected to be still authentication broken). 1546 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) { 1547 ASSERT_TRUE(https_server_.Start()); 1548 ASSERT_TRUE(https_server_expired_.Start()); 1549 1550 std::string top_frame_path; 1551 ASSERT_TRUE(GetTopFramePath(*test_server(), 1552 https_server_, 1553 https_server_expired_, 1554 &top_frame_path)); 1555 1556 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1557 ui_test_utils::NavigateToURL(browser(), 1558 https_server_expired_.GetURL(top_frame_path)); 1559 CheckAuthenticationBrokenState( 1560 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1561 1562 ProceedThroughInterstitial(tab); 1563 1564 // Navigate to a good frame. 1565 bool success = false; 1566 content::WindowedNotificationObserver observer( 1567 content::NOTIFICATION_LOAD_STOP, 1568 content::Source<NavigationController>(&tab->GetController())); 1569 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1570 tab, 1571 "window.domAutomationController.send(clickLink('goodHTTPSLink'));", 1572 &success)); 1573 ASSERT_TRUE(success); 1574 observer.Wait(); 1575 1576 // We should still be authentication broken. 1577 CheckAuthenticationBrokenState( 1578 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1579 } 1580 1581 // From an HTTP top frame, navigate to good and bad HTTPS (security state should 1582 // stay unauthenticated). 1583 // Disabled, flakily exceeds test timeout, http://crbug.com/43437. 1584 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestUnauthenticatedFrameNavigation) { 1585 ASSERT_TRUE(test_server()->Start()); 1586 ASSERT_TRUE(https_server_.Start()); 1587 ASSERT_TRUE(https_server_expired_.Start()); 1588 1589 std::string top_frame_path; 1590 ASSERT_TRUE(GetTopFramePath(*test_server(), 1591 https_server_, 1592 https_server_expired_, 1593 &top_frame_path)); 1594 1595 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1596 ui_test_utils::NavigateToURL(browser(), 1597 test_server()->GetURL(top_frame_path)); 1598 CheckUnauthenticatedState(tab, AuthState::NONE); 1599 1600 // Now navigate inside the frame to a secure HTTPS frame. 1601 { 1602 bool success = false; 1603 content::WindowedNotificationObserver observer( 1604 content::NOTIFICATION_LOAD_STOP, 1605 content::Source<NavigationController>(&tab->GetController())); 1606 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1607 tab, 1608 "window.domAutomationController.send(clickLink('goodHTTPSLink'));", 1609 &success)); 1610 ASSERT_TRUE(success); 1611 observer.Wait(); 1612 } 1613 1614 // We should still be unauthenticated. 1615 CheckUnauthenticatedState(tab, AuthState::NONE); 1616 1617 // Now navigate to a bad HTTPS frame. 1618 { 1619 bool success = false; 1620 content::WindowedNotificationObserver observer( 1621 content::NOTIFICATION_LOAD_STOP, 1622 content::Source<NavigationController>(&tab->GetController())); 1623 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1624 tab, 1625 "window.domAutomationController.send(clickLink('badHTTPSLink'));", 1626 &success)); 1627 ASSERT_TRUE(success); 1628 observer.Wait(); 1629 } 1630 1631 // State should not have changed. 1632 CheckUnauthenticatedState(tab, AuthState::NONE); 1633 1634 // And the frame should have been blocked (see bug #2316). 1635 bool is_content_evil = true; 1636 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate( 1637 tab, base::Bind(&content::FrameMatchesName, "contentFrame")); 1638 std::string is_evil_js("window.domAutomationController.send(" 1639 "document.getElementById('evilDiv') != null);"); 1640 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame, 1641 is_evil_js, 1642 &is_content_evil)); 1643 EXPECT_FALSE(is_content_evil); 1644 } 1645 1646 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) { 1647 ASSERT_TRUE(https_server_.Start()); 1648 ASSERT_TRUE(https_server_expired_.Start()); 1649 1650 // This page will spawn a Worker which will try to load content from 1651 // BadCertServer. 1652 std::string page_with_unsafe_worker_path; 1653 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_, 1654 &page_with_unsafe_worker_path)); 1655 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 1656 page_with_unsafe_worker_path)); 1657 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1658 // Expect Worker not to load insecure content. 1659 CheckWorkerLoadResult(tab, false); 1660 // The bad content is filtered, expect the state to be authenticated. 1661 CheckAuthenticatedState(tab, AuthState::NONE); 1662 } 1663 1664 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorker) { 1665 ASSERT_TRUE(https_server_.Start()); 1666 ASSERT_TRUE(https_server_expired_.Start()); 1667 1668 // Navigate to an unsafe site. Proceed with interstitial page to indicate 1669 // the user approves the bad certificate. 1670 ui_test_utils::NavigateToURL(browser(), 1671 https_server_expired_.GetURL("files/ssl/blank_page.html")); 1672 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1673 CheckAuthenticationBrokenState( 1674 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1675 ProceedThroughInterstitial(tab); 1676 CheckAuthenticationBrokenState( 1677 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1678 1679 // Navigate to safe page that has Worker loading unsafe content. 1680 // Expect content to load but be marked as auth broken due to running insecure 1681 // content. 1682 std::string page_with_unsafe_worker_path; 1683 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_, 1684 &page_with_unsafe_worker_path)); 1685 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 1686 page_with_unsafe_worker_path)); 1687 CheckWorkerLoadResult(tab, true); // Worker loads insecure content 1688 CheckAuthenticationBrokenState( 1689 tab, CertError::NONE, AuthState::RAN_INSECURE_CONTENT); 1690 } 1691 1692 // Test that when the browser blocks displaying insecure content (images), the 1693 // indicator shows a secure page, because the blocking made the otherwise 1694 // unsafe page safe (the notification of this state is handled by other means). 1695 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureImage) { 1696 ASSERT_TRUE(test_server()->Start()); 1697 ASSERT_TRUE(https_server_.Start()); 1698 1699 std::string replacement_path; 1700 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1701 "files/ssl/page_displays_insecure_content.html", 1702 test_server()->host_port_pair(), 1703 &replacement_path)); 1704 1705 ui_test_utils::NavigateToURL(browser(), 1706 https_server_.GetURL(replacement_path)); 1707 1708 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 1709 AuthState::NONE); 1710 } 1711 1712 // Test that when the browser blocks displaying insecure content (iframes), the 1713 // indicator shows a secure page, because the blocking made the otherwise 1714 // unsafe page safe (the notification of this state is handled by other means) 1715 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureIframe) { 1716 ASSERT_TRUE(test_server()->Start()); 1717 ASSERT_TRUE(https_server_.Start()); 1718 1719 std::string replacement_path; 1720 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1721 "files/ssl/page_displays_insecure_iframe.html", 1722 test_server()->host_port_pair(), 1723 &replacement_path)); 1724 1725 ui_test_utils::NavigateToURL(browser(), 1726 https_server_.GetURL(replacement_path)); 1727 1728 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 1729 AuthState::NONE); 1730 } 1731 1732 // Test that when the browser blocks running insecure content, the 1733 // indicator shows a secure page, because the blocking made the otherwise 1734 // unsafe page safe (the notification of this state is handled by other means). 1735 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockRunningInsecureContent) { 1736 ASSERT_TRUE(test_server()->Start()); 1737 ASSERT_TRUE(https_server_.Start()); 1738 1739 std::string replacement_path; 1740 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1741 "files/ssl/page_runs_insecure_content.html", 1742 test_server()->host_port_pair(), 1743 &replacement_path)); 1744 1745 ui_test_utils::NavigateToURL(browser(), 1746 https_server_.GetURL(replacement_path)); 1747 1748 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 1749 AuthState::NONE); 1750 } 1751 1752 // Visit a page and establish a WebSocket connection over bad https with 1753 // --ignore-certificate-errors. The connection should be established without 1754 // interstitial page showing. 1755 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreCertErrors, TestWSS) { 1756 ASSERT_TRUE(test_server()->Start()); 1757 ASSERT_TRUE(wss_server_expired_.Start()); 1758 1759 // Setup page title observer. 1760 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1761 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 1762 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 1763 1764 // Visit bad HTTPS page. 1765 std::string scheme("https"); 1766 GURL::Replacements replacements; 1767 replacements.SetSchemeStr(scheme); 1768 ui_test_utils::NavigateToURL( 1769 browser(), 1770 wss_server_expired_.GetURL( 1771 "connect_check.html").ReplaceComponents(replacements)); 1772 1773 // We shouldn't have an interstitial page showing here. 1774 1775 // Test page run a WebSocket wss connection test. The result will be shown 1776 // as page title. 1777 const base::string16 result = watcher.WaitAndGetTitle(); 1778 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 1779 } 1780 1781 // Verifies that the interstitial can proceed, even if JavaScript is disabled. 1782 // http://crbug.com/322948 1783 #if defined(OS_LINUX) 1784 // flaky http://crbug.com/396458 1785 #define MAYBE_TestInterstitialJavaScriptProceeds \ 1786 DISABLED_TestInterstitialJavaScriptProceeds 1787 #else 1788 #define MAYBE_TestInterstitialJavaScriptProceeds \ 1789 TestInterstitialJavaScriptProceeds 1790 #endif 1791 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestInterstitialJavaScriptProceeds) { 1792 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 1793 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); 1794 1795 ASSERT_TRUE(https_server_expired_.Start()); 1796 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1797 ui_test_utils::NavigateToURL(browser(), 1798 https_server_expired_.GetURL("files/ssl/google.html")); 1799 CheckAuthenticationBrokenState( 1800 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1801 1802 content::WindowedNotificationObserver observer( 1803 content::NOTIFICATION_LOAD_STOP, 1804 content::Source<NavigationController>(&tab->GetController())); 1805 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 1806 content::RenderViewHost* interstitial_rvh = 1807 interstitial_page->GetRenderViewHostForTesting(); 1808 int result = -1; 1809 std::string javascript = base::StringPrintf( 1810 "window.domAutomationController.send(%d);", 1811 SSLBlockingPage::CMD_PROCEED); 1812 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( 1813 interstitial_rvh, javascript, &result)); 1814 // The above will hang without the fix. 1815 EXPECT_EQ(1, result); 1816 observer.Wait(); 1817 CheckAuthenticationBrokenState( 1818 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1819 } 1820 1821 // Verifies that the interstitial can go back, even if JavaScript is disabled. 1822 // http://crbug.com/322948 1823 IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptGoesBack) { 1824 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 1825 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); 1826 1827 ASSERT_TRUE(https_server_expired_.Start()); 1828 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1829 ui_test_utils::NavigateToURL(browser(), 1830 https_server_expired_.GetURL("files/ssl/google.html")); 1831 CheckAuthenticationBrokenState( 1832 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1833 1834 content::WindowedNotificationObserver observer( 1835 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 1836 content::NotificationService::AllSources()); 1837 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 1838 content::RenderViewHost* interstitial_rvh = 1839 interstitial_page->GetRenderViewHostForTesting(); 1840 int result = -1; 1841 std::string javascript = base::StringPrintf( 1842 "window.domAutomationController.send(%d);", 1843 SSLBlockingPage::CMD_DONT_PROCEED); 1844 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( 1845 interstitial_rvh, javascript, &result)); 1846 // The above will hang without the fix. 1847 EXPECT_EQ(0, result); 1848 observer.Wait(); 1849 EXPECT_EQ("about:blank", tab->GetVisibleURL().spec()); 1850 } 1851 1852 // Verifies that switching tabs, while showing interstitial page, will not 1853 // affect the visibility of the interestitial. 1854 // https://crbug.com/381439 1855 IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) { 1856 ASSERT_TRUE(https_server_expired_.Start()); 1857 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1858 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); 1859 ui_test_utils::NavigateToURL( 1860 browser(), https_server_expired_.GetURL("files/ssl/google.html")); 1861 CheckAuthenticationBrokenState( 1862 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1863 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); 1864 1865 AddTabAtIndex(0, 1866 https_server_.GetURL("files/ssl/google.html"), 1867 ui::PAGE_TRANSITION_TYPED); 1868 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 1869 EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); 1870 EXPECT_EQ(tab, browser()->tab_strip_model()->GetWebContentsAt(1)); 1871 EXPECT_FALSE(tab->GetRenderWidgetHostView()->IsShowing()); 1872 1873 browser()->tab_strip_model()->ActivateTabAt(1, true); 1874 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); 1875 } 1876 1877 // TODO(jcampan): more tests to do below. 1878 1879 // Visit a page over https that contains a frame with a redirect. 1880 1881 // XMLHttpRequest insecure content in synchronous mode. 1882 1883 // XMLHttpRequest insecure content in asynchronous mode. 1884 1885 // XMLHttpRequest over bad ssl in synchronous mode. 1886 1887 // XMLHttpRequest over OK ssl in synchronous mode. 1888