ssl_browser_tests.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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/time.h"
6#include "chrome/app/chrome_dll_resource.h"
7#include "chrome/browser/browser.h"
8#include "chrome/browser/prefs/pref_service.h"
9#include "chrome/browser/profile.h"
10#include "chrome/browser/tab_contents/interstitial_page.h"
11#include "chrome/browser/tab_contents/navigation_entry.h"
12#include "chrome/browser/tab_contents/tab_contents.h"
13#include "chrome/browser/tabs/tab_strip_model.h"
14#include "chrome/common/pref_names.h"
15#include "chrome/test/in_process_browser_test.h"
16#include "chrome/test/ui_test_utils.h"
17#include "net/base/cert_status_flags.h"
18#include "net/test/test_server.h"
19
20const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");
21
22class SSLUITest : public InProcessBrowserTest {
23 public:
24  SSLUITest()
25      : https_server_(net::TestServer::TYPE_HTTPS, FilePath(kDocRoot)),
26        https_server_expired_(net::TestServer::TYPE_HTTPS_EXPIRED_CERTIFICATE,
27                              FilePath(kDocRoot)),
28        https_server_mismatched_(
29            net::TestServer::TYPE_HTTPS_MISMATCHED_HOSTNAME,
30            FilePath(kDocRoot)) {
31    EnableDOMAutomation();
32  }
33
34  void CheckAuthenticatedState(TabContents* tab,
35                               bool displayed_insecure_content) {
36    NavigationEntry* entry = tab->controller().GetActiveEntry();
37    ASSERT_TRUE(entry);
38    EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type());
39    EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, entry->ssl().security_style());
40    EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS);
41    EXPECT_EQ(displayed_insecure_content,
42              entry->ssl().displayed_insecure_content());
43    EXPECT_FALSE(entry->ssl().ran_insecure_content());
44  }
45
46  void CheckUnauthenticatedState(TabContents* tab) {
47    NavigationEntry* entry = tab->controller().GetActiveEntry();
48    ASSERT_TRUE(entry);
49    EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type());
50    EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, entry->ssl().security_style());
51    EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS);
52    EXPECT_FALSE(entry->ssl().displayed_insecure_content());
53    EXPECT_FALSE(entry->ssl().ran_insecure_content());
54  }
55
56  void CheckAuthenticationBrokenState(TabContents* tab,
57                                      int error,
58                                      bool ran_insecure_content,
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    // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION doesn't lower the security style
68    // to SECURITY_STYLE_AUTHENTICATION_BROKEN.
69    ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error);
70    EXPECT_EQ(error, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS);
71    EXPECT_FALSE(entry->ssl().displayed_insecure_content());
72    EXPECT_EQ(ran_insecure_content, entry->ssl().ran_insecure_content());
73  }
74
75  void CheckWorkerLoadResult(TabContents* tab, bool expectLoaded) {
76    // Workers are async and we don't have notifications for them passing
77    // messages since they do it between renderer and worker processes.
78    // So have a polling loop, check every 200ms, timeout at 30s.
79    const int timeout_ms = 200;
80    base::Time timeToQuit = base::Time::Now() +
81        base::TimeDelta::FromMilliseconds(30000);
82
83    while (base::Time::Now() < timeToQuit) {
84      bool workerFinished = false;
85      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
86          tab->render_view_host(), std::wstring(),
87          L"window.domAutomationController.send(IsWorkerFinished());",
88          &workerFinished));
89
90      if (workerFinished)
91        break;
92
93      // Wait a bit.
94      MessageLoop::current()->PostDelayedTask(
95          FROM_HERE, new MessageLoop::QuitTask, timeout_ms);
96      ui_test_utils::RunMessageLoop();
97    }
98
99    bool actuallyLoadedContent = false;
100    ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
101        tab->render_view_host(), std::wstring(),
102        L"window.domAutomationController.send(IsContentLoaded());",
103        &actuallyLoadedContent));
104    EXPECT_EQ(expectLoaded, actuallyLoadedContent);
105  }
106
107  void ProceedThroughInterstitial(TabContents* tab) {
108    InterstitialPage* interstitial_page = tab->interstitial_page();
109    ASSERT_TRUE(interstitial_page);
110    interstitial_page->Proceed();
111    // Wait for the navigation to be done.
112    ui_test_utils::WaitForNavigation(&(tab->controller()));
113  }
114
115  net::TestServer https_server_;
116  net::TestServer https_server_expired_;
117  net::TestServer https_server_mismatched_;
118
119 private:
120  DISALLOW_COPY_AND_ASSIGN(SSLUITest);
121};
122
123// Visits a regular page over http.
124IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) {
125  ASSERT_TRUE(test_server()->Start());
126
127  ui_test_utils::NavigateToURL(browser(),
128                               test_server()->GetURL("files/ssl/google.html"));
129
130  CheckUnauthenticatedState(browser()->GetSelectedTabContents());
131}
132
133// Visits a page over http which includes broken https resources (status should
134// be OK).
135// TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give
136//                the secure cookies away!).
137IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) {
138  ASSERT_TRUE(test_server()->Start());
139  ASSERT_TRUE(https_server_expired_.Start());
140
141  ui_test_utils::NavigateToURL(browser(),
142      test_server()->GetURL("files/ssl/page_with_unsafe_contents.html"));
143
144  CheckUnauthenticatedState(browser()->GetSelectedTabContents());
145}
146
147// Visits a page over OK https:
148IN_PROC_BROWSER_TEST_F(SSLUITest, TestOKHTTPS) {
149  ASSERT_TRUE(https_server_.Start());
150
151  ui_test_utils::NavigateToURL(browser(),
152                               https_server_.GetURL("files/ssl/google.html"));
153
154  CheckAuthenticatedState(browser()->GetSelectedTabContents(), false);
155}
156
157// Visits a page with https error and proceed:
158IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) {
159  ASSERT_TRUE(https_server_expired_.Start());
160
161  ui_test_utils::NavigateToURL(browser(),
162      https_server_expired_.GetURL("files/ssl/google.html"));
163
164  TabContents* tab = browser()->GetSelectedTabContents();
165  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
166                                 true);  // Interstitial showing
167
168  ProceedThroughInterstitial(tab);
169
170  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
171                                 false);  // No interstitial showing
172}
173
174// Visits a page with https error and don't proceed (and ensure we can still
175// navigate at that point):
176#if defined(OS_WIN)
177// Disabled, flakily exceeds test timeout, http://crbug.com/43575.
178#define MAYBE_TestHTTPSExpiredCertAndDontProceed \
179    DISABLED_TestHTTPSExpiredCertAndDontProceed
180#else
181// Marked as flaky, see bug 40932.
182#define MAYBE_TestHTTPSExpiredCertAndDontProceed \
183    FLAKY_TestHTTPSExpiredCertAndDontProceed
184#endif
185IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) {
186  ASSERT_TRUE(test_server()->Start());
187  ASSERT_TRUE(https_server_.Start());
188  ASSERT_TRUE(https_server_expired_.Start());
189
190  // First navigate to an OK page.
191  ui_test_utils::NavigateToURL(browser(),
192                               https_server_.GetURL("files/ssl/google.html"));
193
194  TabContents* tab = browser()->GetSelectedTabContents();
195  NavigationEntry* entry = tab->controller().GetActiveEntry();
196  ASSERT_TRUE(entry);
197
198  GURL cross_site_url =
199      https_server_expired_.GetURL("files/ssl/google.html");
200  // Change the host name from 127.0.0.1 to localhost so it triggers a
201  // cross-site navigation so we can test http://crbug.com/5800 is gone.
202  ASSERT_EQ("127.0.0.1", cross_site_url.host());
203  GURL::Replacements replacements;
204  std::string new_host("localhost");
205  replacements.SetHostStr(new_host);
206  cross_site_url = cross_site_url.ReplaceComponents(replacements);
207
208  // Now go to a bad HTTPS page.
209  ui_test_utils::NavigateToURL(browser(), cross_site_url);
210
211  // An interstitial should be showing.
212  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
213                                 false, true);
214
215  // Simulate user clicking "Take me back".
216  InterstitialPage* interstitial_page = tab->interstitial_page();
217  ASSERT_TRUE(interstitial_page);
218  interstitial_page->DontProceed();
219
220  // We should be back to the original good page.
221  CheckAuthenticatedState(tab, false);
222
223  // Try to navigate to a new page. (to make sure bug 5800 is fixed).
224  ui_test_utils::NavigateToURL(browser(),
225                               test_server()->GetURL("files/ssl/google.html"));
226  CheckUnauthenticatedState(tab);
227}
228
229// Visits a page with https error and then goes back using Browser::GoBack.
230IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoBackViaButton) {
231  ASSERT_TRUE(test_server()->Start());
232  ASSERT_TRUE(https_server_expired_.Start());
233
234  // First navigate to an HTTP page.
235  ui_test_utils::NavigateToURL(browser(),
236      test_server()->GetURL("files/ssl/google.html"));
237  TabContents* tab = browser()->GetSelectedTabContents();
238  NavigationEntry* entry = tab->controller().GetActiveEntry();
239  ASSERT_TRUE(entry);
240
241  // Now go to a bad HTTPS page that shows an interstitial.
242  ui_test_utils::NavigateToURL(browser(),
243      https_server_expired_.GetURL("files/ssl/google.html"));
244  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
245                                 true);  // Interstitial showing
246
247  // Simulate user clicking on back button (crbug.com/39248).
248  browser()->GoBack(CURRENT_TAB);
249
250  // We should be back at the original good page.
251  EXPECT_FALSE(browser()->GetSelectedTabContents()->interstitial_page());
252  CheckUnauthenticatedState(tab);
253}
254
255// Visits a page with https error and then goes back using GoToOffset.
256// Marked as flaky, see bug 40932.
257IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestHTTPSExpiredCertAndGoBackViaMenu) {
258  ASSERT_TRUE(test_server()->Start());
259  ASSERT_TRUE(https_server_expired_.Start());
260
261  // First navigate to an HTTP page.
262  ui_test_utils::NavigateToURL(browser(),
263      test_server()->GetURL("files/ssl/google.html"));
264  TabContents* tab = browser()->GetSelectedTabContents();
265  NavigationEntry* entry = tab->controller().GetActiveEntry();
266  ASSERT_TRUE(entry);
267
268  // Now go to a bad HTTPS page that shows an interstitial.
269  ui_test_utils::NavigateToURL(browser(),
270      https_server_expired_.GetURL("files/ssl/google.html"));
271  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
272                                 true);  // Interstitial showing
273
274  // Simulate user clicking and holding on back button (crbug.com/37215).
275  tab->controller().GoToOffset(-1);
276
277  // We should be back at the original good page.
278  EXPECT_FALSE(browser()->GetSelectedTabContents()->interstitial_page());
279  CheckUnauthenticatedState(tab);
280}
281
282// Visits a page with https error and then goes forward using GoToOffset.
283// Marked as flaky, see bug 40932.
284IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestHTTPSExpiredCertAndGoForward) {
285  ASSERT_TRUE(test_server()->Start());
286  ASSERT_TRUE(https_server_expired_.Start());
287
288  // First navigate to two HTTP pages.
289  ui_test_utils::NavigateToURL(browser(),
290      test_server()->GetURL("files/ssl/google.html"));
291  TabContents* tab = browser()->GetSelectedTabContents();
292  NavigationEntry* entry1 = tab->controller().GetActiveEntry();
293  ASSERT_TRUE(entry1);
294  ui_test_utils::NavigateToURL(browser(),
295      test_server()->GetURL("files/ssl/blank_page.html"));
296  NavigationEntry* entry2 = tab->controller().GetActiveEntry();
297  ASSERT_TRUE(entry2);
298
299  // Now go back so that a page is in the forward history.
300  tab->controller().GoBack();
301  ui_test_utils::WaitForNavigation(&(tab->controller()));
302  ASSERT_TRUE(tab->controller().CanGoForward());
303  NavigationEntry* entry3 = tab->controller().GetActiveEntry();
304  ASSERT_TRUE(entry1 == entry3);
305
306  // Now go to a bad HTTPS page that shows an interstitial.
307  ui_test_utils::NavigateToURL(browser(),
308      https_server_expired_.GetURL("files/ssl/google.html"));
309  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
310                                 true);  // Interstitial showing
311
312  // Simulate user clicking and holding on forward button.
313  tab->controller().GoToOffset(1);
314  ui_test_utils::WaitForNavigation(&(tab->controller()));
315
316  // We should be showing the second good page.
317  EXPECT_FALSE(browser()->GetSelectedTabContents()->interstitial_page());
318  CheckUnauthenticatedState(tab);
319  EXPECT_FALSE(tab->controller().CanGoForward());
320  NavigationEntry* entry4 = tab->controller().GetActiveEntry();
321  EXPECT_TRUE(entry2 == entry4);
322}
323
324// Open a page with a HTTPS error in a tab with no prior navigation (through a
325// link with a blank target).  This is to test that the lack of navigation entry
326// does not cause any problems (it was causing a crasher, see
327// http://crbug.com/19941).
328IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSErrorWithNoNavEntry) {
329  ASSERT_TRUE(https_server_expired_.Start());
330
331  GURL url = https_server_expired_.GetURL("files/ssl/google.htm");
332  TabContents* tab2 = browser()->AddTabWithURL(
333      url, GURL(), PageTransition::TYPED, -1, TabStripModel::ADD_SELECTED, NULL,
334      std::string(), NULL);
335  ui_test_utils::WaitForLoadStop(&(tab2->controller()));
336
337  // Verify our assumption that there was no prior navigation.
338  EXPECT_FALSE(browser()->command_updater()->IsCommandEnabled(IDC_BACK));
339
340  // We should have an interstitial page showing.
341  ASSERT_TRUE(tab2->interstitial_page());
342}
343
344//
345// Insecure content
346//
347
348// Visits a page that displays insecure content.
349IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContent) {
350  ASSERT_TRUE(test_server()->Start());
351  ASSERT_TRUE(https_server_.Start());
352
353  // Load a page that displays insecure content.
354  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
355      "files/ssl/page_displays_insecure_content.html"));
356
357  CheckAuthenticatedState(browser()->GetSelectedTabContents(), true);
358}
359
360// Visits a page that runs insecure content and tries to suppress the insecure
361// content warnings by randomizing location.hash.
362// Based on http://crbug.com/8706
363IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecuredContentRandomizeHash) {
364  ASSERT_TRUE(test_server()->Start());
365  ASSERT_TRUE(https_server_.Start());
366
367  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
368      "files/ssl/page_runs_insecure_content.html"));
369
370  CheckAuthenticationBrokenState(browser()->GetSelectedTabContents(), 0, true,
371                                 false);
372}
373
374// Visits a page with unsafe content and make sure that:
375// - frames content is replaced with warning
376// - images and scripts are filtered out entirely
377// Marked as flaky, see bug 40932.
378IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestUnsafeContents) {
379  ASSERT_TRUE(https_server_.Start());
380  ASSERT_TRUE(https_server_expired_.Start());
381
382  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
383      "files/ssl/page_with_unsafe_contents.html"));
384
385  TabContents* tab = browser()->GetSelectedTabContents();
386  // When the bad content is filtered, the state is expected to be
387  // authenticated.
388  CheckAuthenticatedState(tab, false);
389
390  // Because of cross-frame scripting restrictions, we cannot access the iframe
391  // content.  So to know if the frame was loaded, we just check if a popup was
392  // opened (the iframe content opens one).
393  // Note: because of bug 1115868, no constrained window is opened right now.
394  //       Once the bug is fixed, this will do the real check.
395  EXPECT_EQ(0, static_cast<int>(tab->constrained_window_count()));
396
397  int img_width;
398  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt(
399      tab->render_view_host(), std::wstring(),
400      L"window.domAutomationController.send(ImageWidth());", &img_width));
401  // In order to check that the image was not loaded, we check its width.
402  // The actual image (Google logo) is 114 pixels wide, we assume the broken
403  // image is less than 100.
404  EXPECT_LT(img_width, 100);
405
406  bool js_result = false;
407  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
408      tab->render_view_host(), std::wstring(),
409      L"window.domAutomationController.send(IsFooSet());", &js_result));
410  EXPECT_FALSE(js_result);
411}
412
413// Visits a page with insecure content loaded by JS (after the initial page
414// load).
415IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentLoadedFromJS) {
416  ASSERT_TRUE(test_server()->Start());
417  ASSERT_TRUE(https_server_.Start());
418
419  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
420      "files/ssl/page_with_dynamic_insecure_content.html"));
421
422  TabContents* tab = browser()->GetSelectedTabContents();
423  CheckAuthenticatedState(tab, false);
424
425  // Load the insecure image.
426  bool js_result = false;
427  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
428      tab->render_view_host(), std::wstring(), L"loadBadImage();", &js_result));
429  EXPECT_TRUE(js_result);
430
431  // We should now have insecure content.
432  CheckAuthenticatedState(tab, true);
433}
434
435// Visits two pages from the same origin: one that displays insecure content and
436// one that doesn't.  The test checks that we do not propagate the insecure
437// content state from one to the other.
438IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) {
439  ASSERT_TRUE(test_server()->Start());
440  ASSERT_TRUE(https_server_.Start());
441
442  ui_test_utils::NavigateToURL(browser(),
443      https_server_.GetURL("files/ssl/blank_page.html"));
444
445  TabContents* tab1 = browser()->GetSelectedTabContents();
446
447  // This tab should be fine.
448  CheckAuthenticatedState(tab1, false);
449
450  // Create a new tab.
451  GURL url = https_server_.GetURL(
452      "files/ssl/page_displays_insecure_content.html");
453  TabContents* tab2 = browser()->AddTabWithURL(url, GURL(),
454      PageTransition::TYPED, 0, TabStripModel::ADD_SELECTED,
455      tab1->GetSiteInstance(), std::string(), NULL);
456  ui_test_utils::WaitForNavigation(&(tab2->controller()));
457
458  // The new tab has insecure content.
459  CheckAuthenticatedState(tab2, true);
460
461  // The original tab should not be contaminated.
462  CheckAuthenticatedState(tab1, false);
463}
464
465// Visits two pages from the same origin: one that runs insecure content and one
466// that doesn't.  The test checks that we propagate the insecure content state
467// from one to the other.
468IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) {
469  ASSERT_TRUE(test_server()->Start());
470  ASSERT_TRUE(https_server_.Start());
471
472  ui_test_utils::NavigateToURL(browser(),
473      https_server_.GetURL("files/ssl/blank_page.html"));
474
475  TabContents* tab1 = browser()->GetSelectedTabContents();
476
477  // This tab should be fine.
478  CheckAuthenticatedState(tab1, false);
479
480  // Create a new tab.
481  GURL url =
482      https_server_.GetURL("files/ssl/page_runs_insecure_content.html");
483  TabContents* tab2 = browser()->AddTabWithURL(url, GURL(),
484      PageTransition::TYPED, 0, TabStripModel::ADD_SELECTED,
485      tab1->GetSiteInstance(), std::string(), NULL);
486  ui_test_utils::WaitForNavigation(&(tab2->controller()));
487
488  // The new tab has insecure content.
489  CheckAuthenticationBrokenState(tab2, 0, true, false);
490
491  // Which means the origin for the first tab has also been contaminated with
492  // insecure content.
493  CheckAuthenticationBrokenState(tab1, 0, true, false);
494}
495
496// Visits a page with an image over http.  Visits another page over https
497// referencing that same image over http (hoping it is coming from the webcore
498// memory cache).
499IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) {
500  ASSERT_TRUE(test_server()->Start());
501  ASSERT_TRUE(https_server_.Start());
502
503  ui_test_utils::NavigateToURL(browser(), test_server()->GetURL(
504      "files/ssl/page_displays_insecure_content.html"));
505  TabContents* tab = browser()->GetSelectedTabContents();
506  CheckUnauthenticatedState(tab);
507
508  // Load again but over SSL.  It should be marked as displaying insecure
509  // content (even though the image comes from the WebCore memory cache).
510  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
511      "files/ssl/page_displays_insecure_content.html"));
512  CheckAuthenticatedState(tab, true);
513}
514
515// Visits a page with script over http.  Visits another page over https
516// referencing that same script over http (hoping it is coming from the webcore
517// memory cache).
518IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsCachedInsecureContent) {
519  ASSERT_TRUE(test_server()->Start());
520  ASSERT_TRUE(https_server_.Start());
521
522  ui_test_utils::NavigateToURL(browser(),
523      test_server()->GetURL("files/ssl/page_runs_insecure_content.html"));
524  TabContents* tab = browser()->GetSelectedTabContents();
525  CheckUnauthenticatedState(tab);
526
527  // Load again but over SSL.  It should be marked as displaying insecure
528  // content (even though the image comes from the WebCore memory cache).
529  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
530      "files/ssl/page_runs_insecure_content.html"));
531  CheckAuthenticationBrokenState(tab, 0, true, false);
532}
533
534#if defined(OS_WIN)
535// See http://crbug.com/47170
536#define MAYBE_TestCNInvalidStickiness FLAKY_TestCNInvalidStickiness
537#else
538#define MAYBE_TestCNInvalidStickiness TestCNInvalidStickiness
539#endif
540
541// This test ensures the CN invalid status does not 'stick' to a certificate
542// (see bug #1044942) and that it depends on the host-name.
543IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestCNInvalidStickiness) {
544  ASSERT_TRUE(https_server_.Start());
545  ASSERT_TRUE(https_server_mismatched_.Start());
546
547  // First we hit the server with hostname, this generates an invalid policy
548  // error.
549  ui_test_utils::NavigateToURL(browser(),
550      https_server_mismatched_.GetURL("files/ssl/google.html"));
551
552  // We get an interstitial page as a result.
553  TabContents* tab = browser()->GetSelectedTabContents();
554  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
555                                 false, true);  // Interstitial showing.
556  ProceedThroughInterstitial(tab);
557  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
558                                 false, false);  // No interstitial showing.
559
560  // Now we try again with the right host name this time.
561  GURL url(https_server_.GetURL("files/ssl/google.html"));
562  ui_test_utils::NavigateToURL(browser(), url);
563
564  // Security state should be OK.
565  CheckAuthenticatedState(tab, false);
566
567  // Now try again the broken one to make sure it is still broken.
568  ui_test_utils::NavigateToURL(browser(),
569      https_server_mismatched_.GetURL("files/ssl/google.html"));
570
571  // Since we OKed the interstitial last time, we get right to the page.
572  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
573                                 false, false);  // No interstitial showing.
574}
575
576// Test that navigating to a #ref does not change a bad security state.
577IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
578  ASSERT_TRUE(https_server_expired_.Start());
579
580  ui_test_utils::NavigateToURL(browser(),
581      https_server_expired_.GetURL("files/ssl/page_with_refs.html"));
582
583  TabContents* tab = browser()->GetSelectedTabContents();
584  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
585                                 true);  // Interstitial showing.
586
587  ProceedThroughInterstitial(tab);
588
589  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
590                                 false);  // No interstitial showing.
591
592  // Now navigate to a ref in the page, the security state should not have
593  // changed.
594  ui_test_utils::NavigateToURL(browser(),
595      https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp"));
596
597  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
598                                 false);  // No interstitial showing.
599}
600
601// Tests that closing a page that has a unsafe pop-up does not crash the
602// browser (bug #1966).
603// TODO(jcampan): http://crbug.com/2136 disabled because the popup is not
604//                opened as it is not initiated by a user gesture.
605IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
606  ASSERT_TRUE(test_server()->Start());
607  ASSERT_TRUE(https_server_expired_.Start());
608
609  ui_test_utils::NavigateToURL(browser(),
610      test_server()->GetURL("files/ssl/page_with_unsafe_popup.html"));
611
612  TabContents* tab1 = browser()->GetSelectedTabContents();
613  // It is probably overkill to add a notification for a popup-opening, let's
614  // just poll.
615  for (int i = 0; i < 10; i++) {
616    if (static_cast<int>(tab1->constrained_window_count()) > 0)
617      break;
618    MessageLoop::current()->PostDelayedTask(FROM_HERE,
619                                            new MessageLoop::QuitTask(), 1000);
620    ui_test_utils::RunMessageLoop();
621  }
622  ASSERT_EQ(1, static_cast<int>(tab1->constrained_window_count()));
623
624  // Let's add another tab to make sure the browser does not exit when we close
625  // the first tab.
626  Browser* browser_used = NULL;
627  GURL url = test_server()->GetURL("files/ssl/google.html");
628  TabContents* tab2 = browser()->AddTabWithURL(
629      url, GURL(), PageTransition::TYPED, 0, TabStripModel::ADD_SELECTED, NULL,
630      std::string(), &browser_used);
631  ui_test_utils::WaitForNavigation(&(tab2->controller()));
632
633  // Ensure that the tab was created in the correct browser.
634  EXPECT_EQ(browser(), browser_used);
635
636  // Close the first tab.
637  browser()->CloseTabContents(tab1);
638}
639
640// Visit a page over bad https that is a redirect to a page with good https.
641// Marked as flaky, see bug 40932.
642IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectBadToGoodHTTPS) {
643  ASSERT_TRUE(https_server_.Start());
644  ASSERT_TRUE(https_server_expired_.Start());
645
646  GURL url1 = https_server_expired_.GetURL("server-redirect?");
647  GURL url2 = https_server_.GetURL("files/ssl/google.html");
648
649  ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
650
651  TabContents* tab = browser()->GetSelectedTabContents();
652
653  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
654                                 true);  // Interstitial showing.
655
656  ProceedThroughInterstitial(tab);
657
658  // We have been redirected to the good page.
659  CheckAuthenticatedState(tab, false);
660}
661
662// Visit a page over good https that is a redirect to a page with bad https.
663// Marked as flaky, see bug 40932.
664IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectGoodToBadHTTPS) {
665  ASSERT_TRUE(https_server_.Start());
666  ASSERT_TRUE(https_server_expired_.Start());
667
668  GURL url1 = https_server_.GetURL("server-redirect?");
669  GURL url2 = https_server_expired_.GetURL("files/ssl/google.html");
670  ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
671
672  TabContents* tab = browser()->GetSelectedTabContents();
673  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
674                                 true);  // Interstitial showing.
675
676  ProceedThroughInterstitial(tab);
677
678  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
679                                 false);  // No interstitial showing.
680}
681
682// Visit a page over http that is a redirect to a page with good HTTPS.
683IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
684  ASSERT_TRUE(test_server()->Start());
685  ASSERT_TRUE(https_server_.Start());
686
687  TabContents* tab = browser()->GetSelectedTabContents();
688
689  // HTTP redirects to good HTTPS.
690  GURL http_url = test_server()->GetURL("server-redirect?");
691  GURL good_https_url =
692      https_server_.GetURL("files/ssl/google.html");
693
694  ui_test_utils::NavigateToURL(browser(),
695                               GURL(http_url.spec() + good_https_url.spec()));
696  CheckAuthenticatedState(tab, false);
697}
698
699// Visit a page over http that is a redirect to a page with bad HTTPS.
700IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectHTTPToBadHTTPS) {
701  ASSERT_TRUE(test_server()->Start());
702  ASSERT_TRUE(https_server_expired_.Start());
703
704  TabContents* tab = browser()->GetSelectedTabContents();
705
706  GURL http_url = test_server()->GetURL("server-redirect?");
707  GURL bad_https_url =
708      https_server_expired_.GetURL("files/ssl/google.html");
709  ui_test_utils::NavigateToURL(browser(),
710                               GURL(http_url.spec() + bad_https_url.spec()));
711  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
712                                 true);  // Interstitial showing.
713
714  ProceedThroughInterstitial(tab);
715
716  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
717                                 false);  // No interstitial showing.
718}
719
720// Visit a page over https that is a redirect to a page with http (to make sure
721// we don't keep the secure state).
722// Marked as flaky, see bug 40932.
723IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectHTTPSToHTTP) {
724  ASSERT_TRUE(test_server()->Start());
725  ASSERT_TRUE(https_server_.Start());
726
727  GURL https_url = https_server_.GetURL("server-redirect?");
728  GURL http_url = test_server()->GetURL("files/ssl/google.html");
729
730  ui_test_utils::NavigateToURL(browser(),
731                               GURL(https_url.spec() + http_url.spec()));
732  CheckUnauthenticatedState(browser()->GetSelectedTabContents());
733}
734
735// Visits a page to which we could not connect (bad port) over http and https
736// and make sure the security style is correct.
737IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) {
738  ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17"));
739  CheckUnauthenticatedState(browser()->GetSelectedTabContents());
740
741  // Same thing over HTTPS.
742  ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17"));
743  CheckUnauthenticatedState(browser()->GetSelectedTabContents());
744}
745
746//
747// Frame navigation
748//
749
750// From a good HTTPS top frame:
751// - navigate to an OK HTTPS frame
752// - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
753//   back
754// - navigate to HTTP (expect insecure content), then back
755// Disabled, http://crbug.com/18626.
756IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestGoodFrameNavigation) {
757  ASSERT_TRUE(test_server()->Start());
758  ASSERT_TRUE(https_server_.Start());
759  ASSERT_TRUE(https_server_expired_.Start());
760
761  TabContents* tab = browser()->GetSelectedTabContents();
762  ui_test_utils::NavigateToURL(browser(),
763      https_server_.GetURL("files/ssl/top_frame.html"));
764
765  CheckAuthenticatedState(tab, false);
766
767  bool success = false;
768  // Now navigate inside the frame.
769  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
770      tab->render_view_host(), std::wstring(),
771      L"window.domAutomationController.send(clickLink('goodHTTPSLink'));",
772      &success));
773  EXPECT_TRUE(success);
774  ui_test_utils::WaitForNavigation(&tab->controller());
775
776  // We should still be fine.
777  CheckAuthenticatedState(tab, false);
778
779  // Now let's hit a bad page.
780  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
781      tab->render_view_host(), std::wstring(),
782      L"window.domAutomationController.send(clickLink('badHTTPSLink'));",
783      &success));
784  EXPECT_TRUE(success);
785  ui_test_utils::WaitForNavigation(&tab->controller());
786
787  // The security style should still be secure.
788  CheckAuthenticatedState(tab, false);
789
790  // And the frame should be blocked.
791  bool is_content_evil = true;
792  std::wstring content_frame_xpath(L"html/frameset/frame[2]");
793  std::wstring is_evil_js(L"window.domAutomationController.send("
794                          L"document.getElementById('evilDiv') != null);");
795  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
796      tab->render_view_host(), content_frame_xpath, is_evil_js,
797      &is_content_evil));
798  EXPECT_FALSE(is_content_evil);
799
800  // Now go back, our state should still be OK.
801  tab->controller().GoBack();
802  ui_test_utils::WaitForNavigation(&tab->controller());
803  CheckAuthenticatedState(tab, false);
804
805  // Navigate to a page served over HTTP.
806  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
807      tab->render_view_host(), std::wstring(),
808      L"window.domAutomationController.send(clickLink('HTTPLink'));",
809      &success));
810  EXPECT_TRUE(success);
811  ui_test_utils::WaitForNavigation(&tab->controller());
812
813  // Our state should be insecure.
814  CheckAuthenticatedState(tab, true);
815
816  // Go back, our state should be unchanged.
817  tab->controller().GoBack();
818  ui_test_utils::WaitForNavigation(&tab->controller());
819  CheckAuthenticatedState(tab, true);
820}
821
822// From a bad HTTPS top frame:
823// - navigate to an OK HTTPS frame (expected to be still authentication broken).
824// Marked as flaky, see bug 40932.
825IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestBadFrameNavigation) {
826  ASSERT_TRUE(https_server_.Start());
827  ASSERT_TRUE(https_server_expired_.Start());
828
829  TabContents* tab = browser()->GetSelectedTabContents();
830  ui_test_utils::NavigateToURL(browser(),
831      https_server_expired_.GetURL("files/ssl/top_frame.html"));
832  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
833                                 true);  // Interstitial showing
834
835  ProceedThroughInterstitial(tab);
836
837  // Navigate to a good frame.
838  bool success = false;
839  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
840      tab->render_view_host(), std::wstring(),
841      L"window.domAutomationController.send(clickLink('goodHTTPSLink'));",
842      &success));
843  EXPECT_TRUE(success);
844  ui_test_utils::WaitForNavigation(&tab->controller());
845
846  // We should still be authentication broken.
847  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
848                                 false);
849}
850
851// From an HTTP top frame, navigate to good and bad HTTPS (security state should
852// stay unauthenticated).
853#if defined(OS_WIN)
854// Disabled, flakily exceeds test timeout, http://crbug.com/43437.
855#define MAYBE_TestUnauthenticatedFrameNavigation \
856      DISABLED_TestUnauthenticatedFrameNavigation
857#else
858// Marked as flaky, see bug 40932.
859#define MAYBE_TestUnauthenticatedFrameNavigation \
860      FLAKY_TestUnauthenticatedFrameNavigation
861#endif
862IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestUnauthenticatedFrameNavigation) {
863  ASSERT_TRUE(test_server()->Start());
864  ASSERT_TRUE(https_server_.Start());
865  ASSERT_TRUE(https_server_expired_.Start());
866
867  TabContents* tab = browser()->GetSelectedTabContents();
868  ui_test_utils::NavigateToURL(browser(),
869      test_server()->GetURL("files/ssl/top_frame.html"));
870  CheckUnauthenticatedState(tab);
871
872  // Now navigate inside the frame to a secure HTTPS frame.
873  bool success = false;
874  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
875      tab->render_view_host(), std::wstring(),
876      L"window.domAutomationController.send(clickLink('goodHTTPSLink'));",
877      &success));
878  EXPECT_TRUE(success);
879  ui_test_utils::WaitForNavigation(&tab->controller());
880
881  // We should still be unauthenticated.
882  CheckUnauthenticatedState(tab);
883
884  // Now navigate to a bad HTTPS frame.
885  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
886      tab->render_view_host(), std::wstring(),
887      L"window.domAutomationController.send(clickLink('badHTTPSLink'));",
888      &success));
889  EXPECT_TRUE(success);
890  ui_test_utils::WaitForNavigation(&tab->controller());
891
892  // State should not have changed.
893  CheckUnauthenticatedState(tab);
894
895  // And the frame should have been blocked (see bug #2316).
896  bool is_content_evil = true;
897  std::wstring content_frame_xpath(L"html/frameset/frame[2]");
898  std::wstring is_evil_js(L"window.domAutomationController.send("
899                          L"document.getElementById('evilDiv') != null);");
900  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
901      tab->render_view_host(), content_frame_xpath, is_evil_js,
902      &is_content_evil));
903  EXPECT_FALSE(is_content_evil);
904}
905
906// Marked as flaky, see bug 40932.
907IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestUnsafeContentsInWorkerFiltered) {
908  ASSERT_TRUE(https_server_.Start());
909  ASSERT_TRUE(https_server_expired_.Start());
910
911  // This page will spawn a Worker which will try to load content from
912  // BadCertServer.
913  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
914      "files/ssl/page_with_unsafe_worker.html"));
915  TabContents* tab = browser()->GetSelectedTabContents();
916  // Expect Worker not to load insecure content.
917  CheckWorkerLoadResult(tab, false);
918  // The bad content is filtered, expect the state to be authenticated.
919  CheckAuthenticatedState(tab, false);
920}
921
922// Marked as flaky, see bug 40932.
923IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestUnsafeContentsInWorker) {
924  ASSERT_TRUE(https_server_.Start());
925  ASSERT_TRUE(https_server_expired_.Start());
926
927  // Navigate to an unsafe site. Proceed with interstitial page to indicate
928  // the user approves the bad certificate.
929  ui_test_utils::NavigateToURL(browser(),
930      https_server_expired_.GetURL("files/ssl/blank_page.html"));
931  TabContents* tab = browser()->GetSelectedTabContents();
932  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
933                                 true);  // Interstitial showing
934  ProceedThroughInterstitial(tab);
935  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
936                                 false);  // No Interstitial
937
938  // Navigate to safe page that has Worker loading unsafe content.
939  // Expect content to load but be marked as auth broken due to running insecure
940  // content.
941  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
942      "files/ssl/page_with_unsafe_worker.html"));
943  CheckWorkerLoadResult(tab, true);  // Worker loads insecure content
944  CheckAuthenticationBrokenState(tab, 0, true, false);
945}
946
947// TODO(jcampan): more tests to do below.
948
949// Visit a page over https that contains a frame with a redirect.
950
951// XMLHttpRequest insecure content in synchronous mode.
952
953// XMLHttpRequest insecure content in asynchronous mode.
954
955// XMLHttpRequest over bad ssl in synchronous mode.
956
957// XMLHttpRequest over OK ssl in synchronous mode.
958