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