OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/ssl/chrome_security_state_model_client.h" | 5 #include "chrome/browser/ssl/chrome_security_state_model_client.h" |
6 | 6 |
7 #include <openssl/ssl.h> | 7 #include <openssl/ssl.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "chrome/browser/ssl/cert_verifier_browser_test.h" | 14 #include "chrome/browser/ssl/cert_verifier_browser_test.h" |
15 #include "chrome/browser/ssl/chrome_security_state_model_client.h" | 15 #include "chrome/browser/ssl/chrome_security_state_model_client.h" |
16 #include "chrome/browser/ssl/ssl_blocking_page.h" | 16 #include "chrome/browser/ssl/ssl_blocking_page.h" |
17 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
18 #include "chrome/browser/ui/browser_commands.h" | 18 #include "chrome/browser/ui/browser_commands.h" |
19 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 19 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
20 #include "chrome/common/chrome_paths.h" | 20 #include "chrome/common/chrome_paths.h" |
21 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
23 #include "chrome/grit/generated_resources.h" | 23 #include "chrome/grit/generated_resources.h" |
24 #include "chrome/test/base/in_process_browser_test.h" | 24 #include "chrome/test/base/in_process_browser_test.h" |
25 #include "chrome/test/base/ui_test_utils.h" | 25 #include "chrome/test/base/ui_test_utils.h" |
26 #include "components/prefs/pref_service.h" | 26 #include "components/prefs/pref_service.h" |
| 27 #include "components/security_state/switches.h" |
27 #include "content/public/browser/interstitial_page.h" | 28 #include "content/public/browser/interstitial_page.h" |
28 #include "content/public/browser/navigation_controller.h" | 29 #include "content/public/browser/navigation_controller.h" |
29 #include "content/public/browser/navigation_entry.h" | 30 #include "content/public/browser/navigation_entry.h" |
30 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
31 #include "content/public/browser/notification_types.h" | 32 #include "content/public/browser/notification_types.h" |
32 #include "content/public/browser/security_style_explanation.h" | 33 #include "content/public/browser/security_style_explanation.h" |
33 #include "content/public/browser/security_style_explanations.h" | 34 #include "content/public/browser/security_style_explanations.h" |
34 #include "content/public/browser/ssl_status.h" | 35 #include "content/public/browser/ssl_status.h" |
35 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
36 #include "content/public/common/referrer.h" | 37 #include "content/public/common/referrer.h" |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 | 296 |
296 mock_cert_verifier()->AddResultForCert(cert, verify_result, net_result); | 297 mock_cert_verifier()->AddResultForCert(cert, verify_result, net_result); |
297 } | 298 } |
298 | 299 |
299 net::EmbeddedTestServer https_server_; | 300 net::EmbeddedTestServer https_server_; |
300 | 301 |
301 private: | 302 private: |
302 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest); | 303 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest); |
303 }; | 304 }; |
304 | 305 |
| 306 GURL GetURLWithNonLocalHostname(net::EmbeddedTestServer* server, |
| 307 const std::string& path) { |
| 308 GURL::Replacements replace_host; |
| 309 replace_host.SetHostStr("example.test"); |
| 310 return server->GetURL(path).ReplaceComponents(replace_host); |
| 311 } |
| 312 |
| 313 class ChromeSecurityStateModelClientTestWithPasswordCcSwitch |
| 314 : public ChromeSecurityStateModelClientTest { |
| 315 public: |
| 316 ChromeSecurityStateModelClientTestWithPasswordCcSwitch() |
| 317 : ChromeSecurityStateModelClientTest() {} |
| 318 |
| 319 void SetUpOnMainThread() override { |
| 320 ASSERT_TRUE(embedded_test_server()->Start()); |
| 321 ASSERT_TRUE(https_server_.Start()); |
| 322 host_resolver()->AddRule("*", embedded_test_server()->GetURL("/").host()); |
| 323 SetUpMockCertVerifierForHttpsServer(0, net::OK); |
| 324 } |
| 325 |
| 326 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 327 ChromeSecurityStateModelClientTest::SetUpCommandLine(command_line); |
| 328 command_line->AppendSwitchASCII( |
| 329 security_state::switches::kMarkHttpAs, |
| 330 security_state::switches::kMarkHttpWithPasswordsOrCcWithChip); |
| 331 } |
| 332 |
| 333 private: |
| 334 DISALLOW_COPY_AND_ASSIGN( |
| 335 ChromeSecurityStateModelClientTestWithPasswordCcSwitch); |
| 336 }; |
| 337 |
305 class SecurityStyleChangedTest : public InProcessBrowserTest { | 338 class SecurityStyleChangedTest : public InProcessBrowserTest { |
306 public: | 339 public: |
307 SecurityStyleChangedTest() | 340 SecurityStyleChangedTest() |
308 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { | 341 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { |
309 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); | 342 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); |
310 } | 343 } |
311 | 344 |
312 void SetUpCommandLine(base::CommandLine* command_line) override { | 345 void SetUpCommandLine(base::CommandLine* command_line) override { |
313 // Browser will both run and display insecure content. | 346 // Browser will both run and display insecure content. |
314 command_line->AppendSwitch(switches::kAllowRunningInsecureContent); | 347 command_line->AppendSwitch(switches::kAllowRunningInsecureContent); |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 SecurityStateModel::VisibleSecurityState | 930 SecurityStateModel::VisibleSecurityState |
898 visible_security_state_sensitive_inputs; | 931 visible_security_state_sensitive_inputs; |
899 model_client->GetVisibleSecurityState( | 932 model_client->GetVisibleSecurityState( |
900 &visible_security_state_sensitive_inputs); | 933 &visible_security_state_sensitive_inputs); |
901 EXPECT_TRUE( | 934 EXPECT_TRUE( |
902 visible_security_state_sensitive_inputs.displayed_password_field_on_http); | 935 visible_security_state_sensitive_inputs.displayed_password_field_on_http); |
903 EXPECT_TRUE(visible_security_state_sensitive_inputs | 936 EXPECT_TRUE(visible_security_state_sensitive_inputs |
904 .displayed_credit_card_field_on_http); | 937 .displayed_credit_card_field_on_http); |
905 } | 938 } |
906 | 939 |
| 940 // Tests that when a visible password field is detected on an HTTP page |
| 941 // load, and when the command-line flag is set, the security level is |
| 942 // downgraded to HTTP_SHOW_WARNING. |
| 943 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 944 PasswordSecurityLevelDowngraded) { |
| 945 content::WebContents* contents = |
| 946 browser()->tab_strip_model()->GetActiveWebContents(); |
| 947 ASSERT_TRUE(contents); |
| 948 |
| 949 ChromeSecurityStateModelClient* model_client = |
| 950 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 951 ASSERT_TRUE(model_client); |
| 952 |
| 953 ui_test_utils::NavigateToURL( |
| 954 browser(), GetURLWithNonLocalHostname(embedded_test_server(), |
| 955 "/password/simple_password.html")); |
| 956 security_state::SecurityStateModel::SecurityInfo security_info; |
| 957 model_client->GetSecurityInfo(&security_info); |
| 958 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 959 security_info.security_level); |
| 960 |
| 961 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 962 ASSERT_TRUE(entry); |
| 963 EXPECT_TRUE(entry->GetSSL().content_status & |
| 964 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 965 } |
| 966 |
| 967 // Tests that when an invisible password field is present on an HTTP page |
| 968 // load, and when the command-line flag is set, the security level is |
| 969 // downgraded to HTTP_SHOW_WARNING. |
| 970 // |
| 971 // TODO(estark): this will eventually be refined so that the warning |
| 972 // will not show up for invisible password |
| 973 // inputs. https://codereview.chromium.org/2378503002/ |
| 974 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 975 PasswordSecurityLevelDowngradedForInvisibleInput) { |
| 976 content::WebContents* contents = |
| 977 browser()->tab_strip_model()->GetActiveWebContents(); |
| 978 ASSERT_TRUE(contents); |
| 979 |
| 980 ChromeSecurityStateModelClient* model_client = |
| 981 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 982 ASSERT_TRUE(model_client); |
| 983 |
| 984 ui_test_utils::NavigateToURL( |
| 985 browser(), |
| 986 GetURLWithNonLocalHostname(embedded_test_server(), |
| 987 "/password/invisible_password.html")); |
| 988 security_state::SecurityStateModel::SecurityInfo security_info; |
| 989 model_client->GetSecurityInfo(&security_info); |
| 990 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 991 security_info.security_level); |
| 992 |
| 993 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 994 ASSERT_TRUE(entry); |
| 995 EXPECT_TRUE(entry->GetSSL().content_status & |
| 996 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 997 } |
| 998 |
| 999 // Tests that when a visible password field is detected inside an iframe |
| 1000 // on an HTTP page load, and when the command-line flag is set, the |
| 1001 // security level is downgraded to HTTP_SHOW_WARNING. |
| 1002 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 1003 PasswordSecurityLevelDowngradedFromIframe) { |
| 1004 content::WebContents* contents = |
| 1005 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1006 ASSERT_TRUE(contents); |
| 1007 |
| 1008 ChromeSecurityStateModelClient* model_client = |
| 1009 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1010 ASSERT_TRUE(model_client); |
| 1011 |
| 1012 ui_test_utils::NavigateToURL( |
| 1013 browser(), |
| 1014 GetURLWithNonLocalHostname(embedded_test_server(), |
| 1015 "/password/simple_password_in_iframe.html")); |
| 1016 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1017 model_client->GetSecurityInfo(&security_info); |
| 1018 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1019 security_info.security_level); |
| 1020 |
| 1021 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1022 ASSERT_TRUE(entry); |
| 1023 EXPECT_TRUE(entry->GetSSL().content_status & |
| 1024 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 1025 } |
| 1026 |
| 1027 // Tests that when a visible password field is detected inside an iframe |
| 1028 // on an HTTP page load, and when the command-line flag is set, the |
| 1029 // security level is downgraded to HTTP_SHOW_WARNING, even if the iframe |
| 1030 // itself was loaded over HTTPS. |
| 1031 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 1032 PasswordSecurityLevelDowngradedFromHttpsIframe) { |
| 1033 content::WebContents* contents = |
| 1034 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1035 ASSERT_TRUE(contents); |
| 1036 |
| 1037 ChromeSecurityStateModelClient* model_client = |
| 1038 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1039 ASSERT_TRUE(model_client); |
| 1040 |
| 1041 // Navigate to an HTTP URL, which loads an iframe using the host and port of |
| 1042 // |https_server_|. |
| 1043 std::string replacement_path; |
| 1044 GetFilePathWithHostAndPortReplacement( |
| 1045 "/password/simple_password_in_https_iframe.html", |
| 1046 https_server_.host_port_pair(), &replacement_path); |
| 1047 ui_test_utils::NavigateToURL( |
| 1048 browser(), |
| 1049 GetURLWithNonLocalHostname(embedded_test_server(), replacement_path)); |
| 1050 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1051 model_client->GetSecurityInfo(&security_info); |
| 1052 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1053 security_info.security_level); |
| 1054 |
| 1055 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1056 ASSERT_TRUE(entry); |
| 1057 EXPECT_TRUE(entry->GetSSL().content_status & |
| 1058 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 1059 } |
| 1060 |
| 1061 // Tests that when a visible password field is detected on an HTTP page |
| 1062 // load, and when the command-line flag is *not* set, the security level is |
| 1063 // *not* downgraded to HTTP_SHOW_WARNING. |
| 1064 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
| 1065 PasswordSecurityLevelNotDowngradedWithoutSwitch) { |
| 1066 ASSERT_TRUE(embedded_test_server()->Start()); |
| 1067 host_resolver()->AddRule("*", embedded_test_server()->GetURL("/").host()); |
| 1068 |
| 1069 content::WebContents* contents = |
| 1070 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1071 ASSERT_TRUE(contents); |
| 1072 |
| 1073 ChromeSecurityStateModelClient* model_client = |
| 1074 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1075 ASSERT_TRUE(model_client); |
| 1076 |
| 1077 ui_test_utils::NavigateToURL( |
| 1078 browser(), GetURLWithNonLocalHostname(embedded_test_server(), |
| 1079 "/password/simple_password.html")); |
| 1080 // The security level should not be HTTP_SHOW_WARNING, because the |
| 1081 // command-line switch was not set. |
| 1082 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1083 model_client->GetSecurityInfo(&security_info); |
| 1084 EXPECT_EQ(security_state::SecurityStateModel::NONE, |
| 1085 security_info.security_level); |
| 1086 |
| 1087 // The appropriate SSLStatus flags should be set, however. |
| 1088 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1089 ASSERT_TRUE(entry); |
| 1090 EXPECT_TRUE(entry->GetSSL().content_status & |
| 1091 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 1092 } |
| 1093 |
| 1094 // Tests that when a visible password field is detected on an HTTPS page |
| 1095 // load, and when the command-line flag is set, the security level is |
| 1096 // *not* downgraded to HTTP_SHOW_WARNING. |
| 1097 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 1098 PasswordSecurityLevelNotDowngradedOnHttps) { |
| 1099 content::WebContents* contents = |
| 1100 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1101 ASSERT_TRUE(contents); |
| 1102 |
| 1103 ChromeSecurityStateModelClient* model_client = |
| 1104 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1105 ASSERT_TRUE(model_client); |
| 1106 |
| 1107 GURL url = GetURLWithNonLocalHostname(&https_server_, |
| 1108 "/password/simple_password.html"); |
| 1109 ui_test_utils::NavigateToURL(browser(), url); |
| 1110 // The security level should not be HTTP_SHOW_WARNING, because the page was |
| 1111 // HTTPS instead of HTTP. |
| 1112 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1113 model_client->GetSecurityInfo(&security_info); |
| 1114 EXPECT_EQ(security_state::SecurityStateModel::SECURE, |
| 1115 security_info.security_level); |
| 1116 |
| 1117 // The SSLStatus flags should only be set if the top-level page load was HTTP, |
| 1118 // which it was not in this case. |
| 1119 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1120 ASSERT_TRUE(entry); |
| 1121 EXPECT_FALSE(entry->GetSSL().content_status & |
| 1122 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 1123 } |
| 1124 |
907 // Tests that the SecurityStateModel for a WebContents is up to date | 1125 // Tests that the SecurityStateModel for a WebContents is up to date |
908 // when the WebContents is inserted into a Browser's TabStripModel. | 1126 // when the WebContents is inserted into a Browser's TabStripModel. |
909 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { | 1127 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { |
910 ASSERT_TRUE(https_server_.Start()); | 1128 ASSERT_TRUE(https_server_.Start()); |
911 SetUpMockCertVerifierForHttpsServer(0, net::OK); | 1129 SetUpMockCertVerifierForHttpsServer(0, net::OK); |
912 | 1130 |
913 content::WebContents* tab = | 1131 content::WebContents* tab = |
914 browser()->tab_strip_model()->GetActiveWebContents(); | 1132 browser()->tab_strip_model()->GetActiveWebContents(); |
915 ASSERT_TRUE(tab); | 1133 ASSERT_TRUE(tab); |
916 | 1134 |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 ChromeSecurityStateModelClient* model_client = | 1672 ChromeSecurityStateModelClient* model_client = |
1455 ChromeSecurityStateModelClient::FromWebContents(web_contents); | 1673 ChromeSecurityStateModelClient::FromWebContents(web_contents); |
1456 ASSERT_TRUE(model_client); | 1674 ASSERT_TRUE(model_client); |
1457 SecurityStateModel::SecurityInfo security_info; | 1675 SecurityStateModel::SecurityInfo security_info; |
1458 model_client->GetSecurityInfo(&security_info); | 1676 model_client->GetSecurityInfo(&security_info); |
1459 EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); | 1677 EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); |
1460 EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); | 1678 EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); |
1461 } | 1679 } |
1462 | 1680 |
1463 } // namespace | 1681 } // namespace |
OLD | NEW |