OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/ssl_test_util.h" | 5 #include "chrome/browser/browser.h" |
6 | 6 #include "chrome/browser/tab_contents/interstitial_page.h" |
| 7 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 8 #include "chrome/browser/tab_contents/tab_contents.h" |
| 9 #include "chrome/browser/tab_contents/web_contents.h" |
| 10 #include "chrome/common/pref_names.h" |
| 11 #include "chrome/common/pref_service.h" |
7 #include "chrome/test/in_process_browser_test.h" | 12 #include "chrome/test/in_process_browser_test.h" |
8 | 13 #include "chrome/test/ui_test_utils.h" |
9 namespace { | 14 |
10 | 15 const wchar_t kDocRoot[] = L"chrome/test/data"; |
11 const wchar_t* const kDocRoot = L"chrome/test/data"; | 16 |
12 | 17 class SSLUITest : public InProcessBrowserTest { |
13 class SSLBrowserTest : public InProcessBrowserTest { | 18 public: |
| 19 SSLUITest() { |
| 20 EnableDOMAutomation(); |
| 21 } |
| 22 |
| 23 scoped_refptr<HTTPTestServer> PlainServer() { |
| 24 return HTTPTestServer::CreateServer(kDocRoot, NULL); |
| 25 } |
| 26 |
| 27 scoped_refptr<HTTPSTestServer> GoodCertServer() { |
| 28 return HTTPSTestServer::CreateGoodServer(kDocRoot); |
| 29 } |
| 30 |
| 31 scoped_refptr<HTTPSTestServer> BadCertServer() { |
| 32 return HTTPSTestServer::CreateExpiredServer(kDocRoot); |
| 33 } |
| 34 |
| 35 void CheckAuthenticatedState(TabContents* tab, |
| 36 bool mixed_content, |
| 37 bool unsafe_content) { |
| 38 NavigationEntry* entry = tab->controller().GetActiveEntry(); |
| 39 ASSERT_TRUE(entry); |
| 40 EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type()); |
| 41 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, entry->ssl().security_style()); |
| 42 EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS); |
| 43 EXPECT_EQ(mixed_content, entry->ssl().has_mixed_content()); |
| 44 EXPECT_EQ(unsafe_content, entry->ssl().has_unsafe_content()); |
| 45 } |
| 46 |
| 47 void CheckUnauthenticatedState(TabContents* tab) { |
| 48 NavigationEntry* entry = tab->controller().GetActiveEntry(); |
| 49 ASSERT_TRUE(entry); |
| 50 EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type()); |
| 51 EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, entry->ssl().security_style()); |
| 52 EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS); |
| 53 EXPECT_FALSE(entry->ssl().has_mixed_content()); |
| 54 EXPECT_FALSE(entry->ssl().has_unsafe_content()); |
| 55 } |
| 56 |
| 57 void CheckAuthenticationBrokenState(TabContents* tab, |
| 58 int error, |
| 59 bool interstitial) { |
| 60 NavigationEntry* entry = tab->controller().GetActiveEntry(); |
| 61 ASSERT_TRUE(entry); |
| 62 EXPECT_EQ(interstitial ? NavigationEntry::INTERSTITIAL_PAGE : |
| 63 NavigationEntry::NORMAL_PAGE, |
| 64 entry->page_type()); |
| 65 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, |
| 66 entry->ssl().security_style()); |
| 67 EXPECT_EQ(error, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS); |
| 68 EXPECT_FALSE(entry->ssl().has_mixed_content()); |
| 69 EXPECT_FALSE(entry->ssl().has_unsafe_content()); |
| 70 } |
| 71 |
| 72 private: |
| 73 DISALLOW_COPY_AND_ASSIGN(SSLUITest); |
14 }; | 74 }; |
15 | 75 |
16 } // namespace | 76 // Visits a regular page over http. |
17 | 77 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) { |
18 // TODO(jcampan): port SSLUITest to SSLBrowserTest. | 78 scoped_refptr<HTTPTestServer> server = PlainServer(); |
19 IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TestHTTP) { | 79 |
20 } | 80 ui_test_utils::NavigateToURL(browser(), |
| 81 server->TestServerPageW(L"files/ssl/google.html")); |
| 82 |
| 83 CheckUnauthenticatedState(browser()->GetSelectedTabContents()); |
| 84 } |
| 85 |
| 86 // Visits a page over http which includes broken https resources (status should |
| 87 // be OK). |
| 88 // TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give |
| 89 // the secure cookies away!). |
| 90 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) { |
| 91 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 92 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 93 |
| 94 ui_test_utils::NavigateToURL(browser(), http_server->TestServerPageW( |
| 95 L"files/ssl/page_with_unsafe_contents.html")); |
| 96 |
| 97 CheckUnauthenticatedState(browser()->GetSelectedTabContents()); |
| 98 } |
| 99 |
| 100 // Visits a page over OK https: |
| 101 IN_PROC_BROWSER_TEST_F(SSLUITest, TestOKHTTPS) { |
| 102 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 103 |
| 104 ui_test_utils::NavigateToURL(browser(), |
| 105 https_server->TestServerPageW(L"files/ssl/google.html")); |
| 106 |
| 107 CheckAuthenticatedState(browser()->GetSelectedTabContents(), |
| 108 false, false); // No mixed/unsafe content. |
| 109 } |
| 110 |
| 111 // Visits a page with https error and proceed: |
| 112 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) { |
| 113 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 114 |
| 115 ui_test_utils::NavigateToURL(browser(), |
| 116 bad_https_server->TestServerPageW(L"files/ssl/google.html")); |
| 117 |
| 118 TabContents* tab = browser()->GetSelectedTabContents(); |
| 119 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 120 true); // Interstitial showing |
| 121 |
| 122 // Proceed through the interstitial. |
| 123 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 124 ASSERT_TRUE(interstitial_page); |
| 125 interstitial_page->Proceed(); |
| 126 // Wait for the navigation to be done. |
| 127 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 128 |
| 129 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 130 false); // No interstitial showing |
| 131 } |
| 132 |
| 133 // Visits a page with https error and don't proceed (and ensure we can still |
| 134 // navigate at that point): |
| 135 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndDontProceed) { |
| 136 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 137 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 138 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 139 |
| 140 // First navigate to an OK page. |
| 141 ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPageW( |
| 142 L"files/ssl/google.html")); |
| 143 |
| 144 TabContents* tab = browser()->GetSelectedTabContents(); |
| 145 NavigationEntry* entry = tab->controller().GetActiveEntry(); |
| 146 ASSERT_TRUE(entry); |
| 147 |
| 148 GURL cross_site_url = |
| 149 bad_https_server->TestServerPageW(L"files/ssl/google.html"); |
| 150 // Change the host name from 127.0.0.1 to localhost so it triggers a |
| 151 // cross-site navigation so we can test http://crbug.com/5800 is gone. |
| 152 ASSERT_EQ("127.0.0.1", cross_site_url.host()); |
| 153 GURL::Replacements replacements; |
| 154 std::string new_host("localhost"); |
| 155 replacements.SetHostStr(new_host); |
| 156 cross_site_url = cross_site_url.ReplaceComponents(replacements); |
| 157 |
| 158 // Now go to a bad HTTPS page. |
| 159 ui_test_utils::NavigateToURL(browser(), cross_site_url); |
| 160 |
| 161 // An interstitial should be showing. |
| 162 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, |
| 163 true); // Interstitial showing. |
| 164 |
| 165 // Simulate user clicking "Take me back". |
| 166 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 167 ASSERT_TRUE(interstitial_page); |
| 168 interstitial_page->DontProceed(); |
| 169 |
| 170 // We should be back to the original good page. |
| 171 CheckAuthenticatedState(tab, false, false); |
| 172 |
| 173 // Try to navigate to a new page. (to make sure bug 5800 is fixed). |
| 174 ui_test_utils::NavigateToURL(browser(), |
| 175 http_server->TestServerPageW(L"files/ssl/google.html")); |
| 176 CheckUnauthenticatedState(tab); |
| 177 } |
| 178 |
| 179 // |
| 180 // Mixed contents |
| 181 // |
| 182 |
| 183 // Visits a page with mixed content. |
| 184 IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContents) { |
| 185 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 186 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 187 |
| 188 // Load a page with mixed-content, the default behavior is to show the mixed |
| 189 // content. |
| 190 ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW( |
| 191 L"files/ssl/page_with_mixed_contents.html")); |
| 192 |
| 193 CheckAuthenticatedState(browser()->GetSelectedTabContents(), |
| 194 true /* mixed-content */, false); |
| 195 } |
| 196 |
| 197 // Visits a page with mixed content. |
| 198 IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsFilterAll) { |
| 199 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 200 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 201 |
| 202 // Set the "block mixed-content" preference. |
| 203 browser()->profile()->GetPrefs()->SetInteger(prefs::kMixedContentFiltering, |
| 204 FilterPolicy::FILTER_ALL); |
| 205 |
| 206 // Load a page with mixed-content, the mixed content shouldn't load. |
| 207 ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW( |
| 208 L"files/ssl/page_with_mixed_contents.html")); |
| 209 |
| 210 TabContents* tab = browser()->GetSelectedTabContents(); |
| 211 NavigationEntry* entry = tab->controller().GetActiveEntry(); |
| 212 ASSERT_TRUE(entry); |
| 213 EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type()); |
| 214 |
| 215 // The image should be filtered. |
| 216 int img_width = 0; |
| 217 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt( |
| 218 tab, L"", L"window.domAutomationController.send(ImageWidth());", |
| 219 &img_width)); |
| 220 // In order to check that the image was not loaded, we check its width. |
| 221 // The actual image (Google logo) is 114 pixels wide, we assume the broken |
| 222 // image is less than 100. |
| 223 EXPECT_GT(100, img_width); |
| 224 |
| 225 // The state should be OK since we are not showing the resource. |
| 226 CheckAuthenticatedState(tab, false, false); |
| 227 |
| 228 // There should be one info-bar to show the mixed-content. |
| 229 EXPECT_EQ(1, tab->infobar_delegate_count()); |
| 230 |
| 231 // Activate the link on the info-bar to show the mixed-content. |
| 232 InfoBarDelegate* delegate = tab->GetInfoBarDelegateAt(0); |
| 233 ASSERT_TRUE(delegate->AsConfirmInfoBarDelegate()); |
| 234 delegate->AsConfirmInfoBarDelegate()->Accept(); |
| 235 // Showing the mixed-contents triggered a page reload, let's wait for it to |
| 236 // finish. |
| 237 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 238 |
| 239 // The image should show now. |
| 240 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt( |
| 241 tab, L"", L"window.domAutomationController.send(ImageWidth());", |
| 242 &img_width)); |
| 243 EXPECT_LT(100, img_width); |
| 244 |
| 245 // And our status should be mixed-content. |
| 246 CheckAuthenticatedState(tab, true /* mixed-content */, false); |
| 247 } |
| 248 |
| 249 // Visits a page with an http script that tries to suppress our mixed content |
| 250 // warnings by randomize location.hash. |
| 251 // Based on http://crbug.com/8706 |
| 252 IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsRandomizeHash) { |
| 253 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 254 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 255 |
| 256 ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW( |
| 257 L"files/ssl/page_with_http_script.html")); |
| 258 |
| 259 CheckAuthenticatedState(browser()->GetSelectedTabContents(), |
| 260 true /* mixed-content */, false); |
| 261 } |
| 262 |
| 263 // Visits a page with unsafe content and make sure that: |
| 264 // - frames content is replaced with warning |
| 265 // - images and scripts are filtered out entirely |
| 266 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) { |
| 267 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 268 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 269 |
| 270 ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPageW( |
| 271 L"files/ssl/page_with_unsafe_contents.html")); |
| 272 |
| 273 TabContents* tab = browser()->GetSelectedTabContents(); |
| 274 // When the bad content is filtered, the state is expected to be |
| 275 // authenticated. |
| 276 CheckAuthenticatedState(tab, false, false); |
| 277 |
| 278 // Because of cross-frame scripting restrictions, we cannot access the iframe |
| 279 // content. So to know if the frame was loaded, we just check if a popup was |
| 280 // opened (the iframe content opens one). |
| 281 // Note: because of bug 1115868, no constrained window is opened right now. |
| 282 // Once the bug is fixed, this will do the real check. |
| 283 EXPECT_EQ(0, tab->constrained_window_count()); |
| 284 |
| 285 int img_width; |
| 286 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt( |
| 287 tab, L"", L"window.domAutomationController.send(ImageWidth());", |
| 288 &img_width)); |
| 289 // In order to check that the image was not loaded, we check its width. |
| 290 // The actual image (Google logo) is 114 pixels wide, we assume the broken |
| 291 // image is less than 100. |
| 292 EXPECT_GT(100, img_width); |
| 293 |
| 294 bool js_result = false; |
| 295 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
| 296 tab, L"", L"window.domAutomationController.send(IsFooSet());", |
| 297 &js_result)); |
| 298 EXPECT_FALSE(js_result); |
| 299 } |
| 300 |
| 301 // Visits a page with mixed content loaded by JS (after the initial page load). |
| 302 IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsLoadedFromJS) { |
| 303 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 304 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 305 |
| 306 ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW( |
| 307 L"files/ssl/page_with_dynamic_mixed_contents.html")); |
| 308 |
| 309 TabContents* tab = browser()->GetSelectedTabContents(); |
| 310 CheckAuthenticatedState(tab, false, false); |
| 311 |
| 312 // Load the insecure image. |
| 313 bool js_result = false; |
| 314 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( |
| 315 tab, L"", L"loadBadImage();", &js_result)); |
| 316 EXPECT_TRUE(js_result); |
| 317 |
| 318 // We should now have mixed-contents. |
| 319 CheckAuthenticatedState(tab, true /* mixed-content */, false); |
| 320 } |
| 321 |
| 322 // Visits two pages from the same origin: one with mixed content and one |
| 323 // without. The test checks that we propagate the mixed content state from one |
| 324 // to the other. |
| 325 IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsTwoTabs) { |
| 326 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 327 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 328 |
| 329 ui_test_utils::NavigateToURL(browser(), |
| 330 https_server->TestServerPageW(L"files/ssl/blank_page.html")); |
| 331 |
| 332 TabContents* tab1 = browser()->GetSelectedTabContents(); |
| 333 |
| 334 // This tab should be fine. |
| 335 CheckAuthenticatedState(tab1, false, false); |
| 336 |
| 337 // Create a new tab. |
| 338 GURL url = |
| 339 https_server->TestServerPageW(L"files/ssl/page_with_http_script.html"); |
| 340 TabContents* tab2 = browser()->AddTabWithURL(url, |
| 341 GURL(), |
| 342 PageTransition::TYPED, true, 0, |
| 343 NULL); |
| 344 ui_test_utils::WaitForNavigation(&(tab2->controller())); |
| 345 |
| 346 // The new tab has mixed content. |
| 347 CheckAuthenticatedState(tab2, true /* mixed-content */, false); |
| 348 |
| 349 // Which means the origin for the first tab has also been contaminated with |
| 350 // mixed content. |
| 351 CheckAuthenticatedState(tab1, true /* mixed-content */, false); |
| 352 } |
| 353 |
| 354 // Visits a page with an image over http. Visits another page over https |
| 355 // referencing that same image over http (hoping it is coming from the webcore |
| 356 // memory cache). |
| 357 IN_PROC_BROWSER_TEST_F(SSLUITest, TestCachedMixedContents) { |
| 358 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 359 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 360 |
| 361 ui_test_utils::NavigateToURL(browser(), http_server->TestServerPageW( |
| 362 L"files/ssl/page_with_mixed_contents.html")); |
| 363 TabContents* tab = browser()->GetSelectedTabContents(); |
| 364 CheckUnauthenticatedState(tab); |
| 365 |
| 366 // Load again but over SSL. It should have mixed-contents (even though the |
| 367 // image comes from the WebCore memory cache). |
| 368 ui_test_utils::NavigateToURL(browser(), https_server->TestServerPageW( |
| 369 L"files/ssl/page_with_mixed_contents.html")); |
| 370 CheckAuthenticatedState(tab, true /* mixed-content */, false); |
| 371 } |
| 372 |
| 373 // This test ensures the CN invalid status does not 'stick' to a certificate |
| 374 // (see bug #1044942) and that it depends on the host-name. |
| 375 IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) { |
| 376 const std::string kLocalHost = "localhost"; |
| 377 scoped_refptr<HTTPSTestServer> https_server = |
| 378 HTTPSTestServer::CreateMismatchedServer(kDocRoot); |
| 379 ASSERT_TRUE(NULL != https_server.get()); |
| 380 |
| 381 // First we hit the server with hostname, this generates an invalid policy |
| 382 // error. |
| 383 ui_test_utils::NavigateToURL(browser(), |
| 384 https_server->TestServerPageW(L"files/ssl/google.html")); |
| 385 |
| 386 // We get an interstitial page as a result. |
| 387 TabContents* tab = browser()->GetSelectedTabContents(); |
| 388 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, |
| 389 true); // Interstitial showing. |
| 390 |
| 391 // We proceed through the interstitial page. |
| 392 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 393 ASSERT_TRUE(interstitial_page); |
| 394 interstitial_page->Proceed(); |
| 395 // Wait for the navigation to be done. |
| 396 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 397 |
| 398 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, |
| 399 false); // No interstitial showing. |
| 400 |
| 401 // Now we try again with the right host name this time. |
| 402 |
| 403 // Let's change the host-name in the url. |
| 404 GURL url = https_server->TestServerPageW(L"files/ssl/google.html"); |
| 405 std::string::size_type hostname_index = url.spec().find(kLocalHost); |
| 406 ASSERT_TRUE(hostname_index != std::string::npos); // Test sanity check. |
| 407 std::string new_url; |
| 408 new_url.append(url.spec().substr(0, hostname_index)); |
| 409 new_url.append(net::TestServerLauncher::kHostName); |
| 410 new_url.append(url.spec().substr(hostname_index + kLocalHost.size())); |
| 411 |
| 412 ui_test_utils::NavigateToURL(browser(), GURL(new_url)); |
| 413 |
| 414 // Security state should be OK. |
| 415 CheckAuthenticatedState(tab, false, false); |
| 416 |
| 417 // Now try again the broken one to make sure it is still broken. |
| 418 ui_test_utils::NavigateToURL(browser(), |
| 419 https_server->TestServerPageW(L"files/ssl/google.html")); |
| 420 |
| 421 // Since we OKed the interstitial last time, we get right to the page. |
| 422 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, |
| 423 false); // No interstitial showing. |
| 424 } |
| 425 |
| 426 // Test that navigating to a #ref does not change a bad security state. |
| 427 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) { |
| 428 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 429 |
| 430 ui_test_utils::NavigateToURL(browser(), |
| 431 bad_https_server->TestServerPageW(L"files/ssl/page_with_refs.html")); |
| 432 |
| 433 TabContents* tab = browser()->GetSelectedTabContents(); |
| 434 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 435 true); // Interstitial showing. |
| 436 |
| 437 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 438 ASSERT_TRUE(interstitial_page); |
| 439 interstitial_page->Proceed(); |
| 440 // Wait for the navigation to be done. |
| 441 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 442 |
| 443 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 444 false); // No interstitial showing. |
| 445 |
| 446 // Now navigate to a ref in the page, the security state should not have |
| 447 // changed. |
| 448 ui_test_utils::NavigateToURL(browser(), |
| 449 bad_https_server->TestServerPageW(L"files/ssl/page_with_refs.html#jp")); |
| 450 |
| 451 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 452 false); // No interstitial showing. |
| 453 } |
| 454 |
| 455 // Tests that closing a page that has a unsafe pop-up does not crash the browser |
| 456 // (bug #1966). |
| 457 IN_PROC_BROWSER_TEST_F(SSLUITest, TestCloseTabWithUnsafePopup) { |
| 458 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 459 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 460 |
| 461 ui_test_utils::NavigateToURL(browser(), http_server->TestServerPageW( |
| 462 L"files/ssl/page_with_unsafe_popup.html")); |
| 463 |
| 464 TabContents* tab1 = browser()->GetSelectedTabContents(); |
| 465 // It is probably overkill to add a notification for a popup-opening, let's |
| 466 // just poll. |
| 467 for (int i = 0; i < 10; i++) { |
| 468 if (tab1->constrained_window_count() > 0) |
| 469 break; |
| 470 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 471 new MessageLoop::QuitTask(), 1000); |
| 472 ui_test_utils::RunMessageLoop(); |
| 473 } |
| 474 ASSERT_EQ(1, tab1->constrained_window_count()); |
| 475 |
| 476 // Let's add another tab to make sure the browser does not exit when we close |
| 477 // the first tab. |
| 478 GURL url = http_server->TestServerPageW(L"files/ssl/google.html"); |
| 479 TabContents* tab2 = browser()->AddTabWithURL(url, |
| 480 GURL(), |
| 481 PageTransition::TYPED, |
| 482 true, 0, NULL); |
| 483 ui_test_utils::WaitForNavigation(&(tab2->controller())); |
| 484 |
| 485 // Close the first tab. |
| 486 browser()->CloseTabContents(tab1); |
| 487 } |
| 488 |
| 489 // Visit a page over bad https that is a redirect to a page with good https. |
| 490 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) { |
| 491 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 492 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 493 |
| 494 GURL url1 = bad_https_server->TestServerPageW(L"server-redirect?"); |
| 495 GURL url2 = good_https_server->TestServerPageW(L"files/ssl/google.html"); |
| 496 |
| 497 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); |
| 498 |
| 499 TabContents* tab = browser()->GetSelectedTabContents(); |
| 500 |
| 501 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 502 true); // Interstitial showing. |
| 503 |
| 504 // We proceed through the interstitial page. |
| 505 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 506 ASSERT_TRUE(interstitial_page); |
| 507 interstitial_page->Proceed(); |
| 508 // Wait for the navigation to be done. |
| 509 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 510 |
| 511 // We have been redirected to the good page. |
| 512 CheckAuthenticatedState(tab, false, false); // No mixed/unsafe content. |
| 513 } |
| 514 |
| 515 // Visit a page over good https that is a redirect to a page with bad https. |
| 516 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) { |
| 517 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 518 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 519 |
| 520 GURL url1 = good_https_server->TestServerPageW(L"server-redirect?"); |
| 521 GURL url2 = bad_https_server->TestServerPageW(L"files/ssl/google.html"); |
| 522 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); |
| 523 |
| 524 TabContents* tab = browser()->GetSelectedTabContents(); |
| 525 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 526 true); // Interstitial showing. |
| 527 |
| 528 // We proceed through the interstitial page. |
| 529 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 530 ASSERT_TRUE(interstitial_page); |
| 531 interstitial_page->Proceed(); |
| 532 // Wait for the navigation to be done. |
| 533 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 534 |
| 535 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 536 false); // No interstitial showing. |
| 537 } |
| 538 |
| 539 // Visit a page over http that is a redirect to a page with good HTTPS. |
| 540 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) { |
| 541 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 542 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 543 |
| 544 TabContents* tab = browser()->GetSelectedTabContents(); |
| 545 |
| 546 // HTTP redirects to good HTTPS. |
| 547 GURL http_url = http_server->TestServerPageW(L"server-redirect?"); |
| 548 GURL good_https_url = |
| 549 good_https_server->TestServerPageW(L"files/ssl/google.html"); |
| 550 |
| 551 ui_test_utils::NavigateToURL(browser(), |
| 552 GURL(http_url.spec() + good_https_url.spec())); |
| 553 CheckAuthenticatedState(tab, false, false); // No mixed/unsafe content. |
| 554 } |
| 555 |
| 556 // Visit a page over http that is a redirect to a page with bad HTTPS. |
| 557 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToBadHTTPS) { |
| 558 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 559 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 560 |
| 561 TabContents* tab = browser()->GetSelectedTabContents(); |
| 562 |
| 563 GURL http_url = http_server->TestServerPageW(L"server-redirect?"); |
| 564 GURL bad_https_url = |
| 565 bad_https_server->TestServerPageW(L"files/ssl/google.html"); |
| 566 ui_test_utils::NavigateToURL(browser(), |
| 567 GURL(http_url.spec() + bad_https_url.spec())); |
| 568 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 569 true); // Interstitial showing. |
| 570 |
| 571 // Continue on the interstitial. |
| 572 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 573 ASSERT_TRUE(interstitial_page); |
| 574 interstitial_page->Proceed(); |
| 575 // Wait for the navigation to be done. |
| 576 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 577 |
| 578 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 579 false); // No interstitial showing. |
| 580 } |
| 581 |
| 582 // Visit a page over https that is a redirect to a page with http (to make sure |
| 583 // we don't keep the secure state). |
| 584 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) { |
| 585 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 586 scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); |
| 587 |
| 588 GURL https_url = https_server->TestServerPageW(L"server-redirect?"); |
| 589 GURL http_url = http_server->TestServerPageW(L"files/ssl/google.html"); |
| 590 |
| 591 ui_test_utils::NavigateToURL(browser(), |
| 592 GURL(https_url.spec() + http_url.spec())); |
| 593 CheckUnauthenticatedState(browser()->GetSelectedTabContents()); |
| 594 } |
| 595 |
| 596 // Visits a page to which we could not connect (bad port) over http and https |
| 597 // and make sure the security style is correct. |
| 598 IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) { |
| 599 ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17")); |
| 600 CheckUnauthenticatedState(browser()->GetSelectedTabContents()); |
| 601 |
| 602 // Same thing over HTTPS. |
| 603 ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17")); |
| 604 CheckUnauthenticatedState(browser()->GetSelectedTabContents()); |
| 605 } |
| 606 |
| 607 // |
| 608 // Frame navigation |
| 609 // |
| 610 |
| 611 // From a good HTTPS top frame: |
| 612 // - navigate to an OK HTTPS frame |
| 613 // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then |
| 614 // back |
| 615 // - navigate to HTTP (expect mixed content), then back |
| 616 IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) { |
| 617 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 618 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 619 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 620 |
| 621 TabContents* tab = browser()->GetSelectedTabContents(); |
| 622 ui_test_utils::NavigateToURL( |
| 623 browser(), |
| 624 good_https_server->TestServerPageW(L"files/ssl/top_frame.html")); |
| 625 |
| 626 CheckAuthenticatedState(tab, false, false); |
| 627 |
| 628 bool success = false; |
| 629 // Now navigate inside the frame. |
| 630 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 631 L"", |
| 632 L"window.domAutomationController.send(clickLink('goodHTTPSLink'));", |
| 633 &success)); |
| 634 EXPECT_TRUE(success); |
| 635 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 636 |
| 637 // We should still be fine. |
| 638 CheckAuthenticatedState(tab, false, false); |
| 639 |
| 640 // Now let's hit a bad page. |
| 641 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 642 L"", |
| 643 L"window.domAutomationController.send(clickLink('badHTTPSLink'));", |
| 644 &success)); |
| 645 EXPECT_TRUE(success); |
| 646 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 647 |
| 648 // The security style should still be secure. |
| 649 CheckAuthenticatedState(tab, false, false); |
| 650 |
| 651 // And the frame should be blocked. |
| 652 bool is_content_evil = true; |
| 653 std::wstring content_frame_xpath(L"html/frameset/frame[2]"); |
| 654 std::wstring is_frame_evil_js( |
| 655 L"window.domAutomationController" |
| 656 L".send(document.getElementById('evilDiv') != null);"); |
| 657 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 658 content_frame_xpath, |
| 659 is_frame_evil_js, |
| 660 &is_content_evil)); |
| 661 EXPECT_FALSE(is_content_evil); |
| 662 |
| 663 // Now go back, our state should still be OK. |
| 664 tab->controller().GoBack(); |
| 665 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 666 CheckAuthenticatedState(tab, false, false); |
| 667 |
| 668 // Navigate to a page served over HTTP. |
| 669 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 670 L"", |
| 671 L"window.domAutomationController.send(clickLink('HTTPLink'));", |
| 672 &success)); |
| 673 EXPECT_TRUE(success); |
| 674 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 675 |
| 676 // Our state should be mixed-content. |
| 677 CheckAuthenticatedState(tab, true, false); |
| 678 |
| 679 // Go back, our state should be unchanged. |
| 680 tab->controller().GoBack(); |
| 681 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 682 CheckAuthenticatedState(tab, true, false); |
| 683 } |
| 684 |
| 685 // From a bad HTTPS top frame: |
| 686 // - navigate to an OK HTTPS frame (expected to be still authentication broken). |
| 687 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) { |
| 688 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 689 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 690 |
| 691 TabContents* tab = browser()->GetSelectedTabContents(); |
| 692 ui_test_utils::NavigateToURL( |
| 693 browser(), |
| 694 bad_https_server->TestServerPageW(L"files/ssl/top_frame.html")); |
| 695 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, |
| 696 true); // Interstitial showing |
| 697 |
| 698 // Continue on the interstitial. |
| 699 InterstitialPage* interstitial_page = tab->interstitial_page(); |
| 700 ASSERT_TRUE(interstitial_page); |
| 701 interstitial_page->Proceed(); |
| 702 // Wait for the navigation to be done. |
| 703 ui_test_utils::WaitForNavigation(&(tab->controller())); |
| 704 |
| 705 // Navigate to a good frame. |
| 706 bool success = false; |
| 707 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 708 L"", |
| 709 L"window.domAutomationController.send(clickLink('goodHTTPSLink'));", |
| 710 &success)); |
| 711 EXPECT_TRUE(success); |
| 712 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 713 |
| 714 // We should still be authentication broken. |
| 715 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); |
| 716 } |
| 717 |
| 718 // From an HTTP top frame, navigate to good and bad HTTPS (security state should |
| 719 // stay unauthenticated). |
| 720 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnauthenticatedFrameNavigation) { |
| 721 scoped_refptr<HTTPTestServer> http_server = PlainServer(); |
| 722 scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); |
| 723 scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); |
| 724 |
| 725 TabContents* tab = browser()->GetSelectedTabContents(); |
| 726 ui_test_utils::NavigateToURL( |
| 727 browser(), |
| 728 http_server->TestServerPageW(L"files/ssl/top_frame.html")); |
| 729 CheckUnauthenticatedState(tab); |
| 730 |
| 731 // Now navigate inside the frame to a secure HTTPS frame. |
| 732 bool success = false; |
| 733 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 734 L"", |
| 735 L"window.domAutomationController.send(clickLink('goodHTTPSLink'));", |
| 736 &success)); |
| 737 EXPECT_TRUE(success); |
| 738 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 739 |
| 740 // We should still be unauthenticated. |
| 741 CheckUnauthenticatedState(tab); |
| 742 |
| 743 // Now navigate to a bad HTTPS frame. |
| 744 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 745 L"", |
| 746 L"window.domAutomationController.send(clickLink('badHTTPSLink'));", |
| 747 &success)); |
| 748 EXPECT_TRUE(success); |
| 749 ui_test_utils::WaitForNavigation(&tab->controller()); |
| 750 |
| 751 // State should not have changed. |
| 752 CheckUnauthenticatedState(tab); |
| 753 |
| 754 // And the frame should have been blocked (see bug #2316). |
| 755 bool is_content_evil = true; |
| 756 std::wstring content_frame_xpath(L"html/frameset/frame[2]"); |
| 757 std::wstring is_frame_evil_js( |
| 758 L"window.domAutomationController" |
| 759 L".send(document.getElementById('evilDiv') != null);"); |
| 760 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(tab, |
| 761 content_frame_xpath, is_frame_evil_js, &is_content_evil)); |
| 762 EXPECT_FALSE(is_content_evil); |
| 763 } |
| 764 |
| 765 // TODO(jcampan): more tests to do below. |
| 766 |
| 767 // Visit a page over https that contains a frame with a redirect. |
| 768 |
| 769 // XMLHttpRequest mixed in synchronous mode. |
| 770 |
| 771 // XMLHttpRequest mixed in asynchronous mode. |
| 772 |
| 773 // XMLHttpRequest over bad ssl in synchronous mode. |
| 774 |
| 775 // XMLHttpRequest over OK ssl in synchronous mode. |
OLD | NEW |