| 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" |
| (...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 security_info.security_level); | 1112 security_info.security_level); |
| 1113 | 1113 |
| 1114 // The SSLStatus flags should only be set if the top-level page load was HTTP, | 1114 // The SSLStatus flags should only be set if the top-level page load was HTTP, |
| 1115 // which it was not in this case. | 1115 // which it was not in this case. |
| 1116 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); | 1116 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1117 ASSERT_TRUE(entry); | 1117 ASSERT_TRUE(entry); |
| 1118 EXPECT_FALSE(entry->GetSSL().content_status & | 1118 EXPECT_FALSE(entry->GetSSL().content_status & |
| 1119 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); | 1119 content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| 1120 } | 1120 } |
| 1121 | 1121 |
| 1122 // A Browser subclass that keeps track of messages that have been |
| 1123 // added to the console. Messages can be retrieved or cleared with |
| 1124 // console_messages() and ClearConsoleMessages(). The user of this class |
| 1125 // can set a callback to run when the next console message notification |
| 1126 // arrives. |
| 1127 class ConsoleWebContentsDelegate : public Browser { |
| 1128 public: |
| 1129 explicit ConsoleWebContentsDelegate(const Browser::CreateParams& params) |
| 1130 : Browser(params) {} |
| 1131 ~ConsoleWebContentsDelegate() override {} |
| 1132 |
| 1133 const std::vector<base::string16>& console_messages() const { |
| 1134 return console_messages_; |
| 1135 } |
| 1136 |
| 1137 void set_console_message_callback(const base::Closure& callback) { |
| 1138 console_message_callback_ = callback; |
| 1139 } |
| 1140 |
| 1141 void ClearConsoleMessages() { console_messages_.clear(); } |
| 1142 |
| 1143 // content::WebContentsDelegate |
| 1144 bool AddMessageToConsole(content::WebContents* source, |
| 1145 int32_t level, |
| 1146 const base::string16& message, |
| 1147 int32_t line_no, |
| 1148 const base::string16& source_id) override { |
| 1149 console_messages_.push_back(message); |
| 1150 if (!console_message_callback_.is_null()) { |
| 1151 console_message_callback_.Run(); |
| 1152 console_message_callback_.Reset(); |
| 1153 } |
| 1154 return true; |
| 1155 } |
| 1156 |
| 1157 private: |
| 1158 std::vector<base::string16> console_messages_; |
| 1159 base::Closure console_message_callback_; |
| 1160 |
| 1161 DISALLOW_COPY_AND_ASSIGN(ConsoleWebContentsDelegate); |
| 1162 }; |
| 1163 |
| 1164 // Checks that |delegate| has observed exactly one console message for |
| 1165 // HTTP_SHOW_WARNING. This does not check for the exact string (for fear |
| 1166 // of being too brittle) but rather just a keyword ("not secure"). |
| 1167 void CheckForOneHttpWarningConsoleMessage( |
| 1168 ConsoleWebContentsDelegate* delegate) { |
| 1169 const std::vector<base::string16>& messages = delegate->console_messages(); |
| 1170 ASSERT_EQ(1u, messages.size()); |
| 1171 EXPECT_NE(base::string16::npos, |
| 1172 messages[0].find(base::ASCIIToUTF16("not secure"))); |
| 1173 } |
| 1174 |
| 1175 // Tests that console messages are printed upon a call to |
| 1176 // GetSecurityInfo() on an HTTP_SHOW_WARNING page, exactly once per |
| 1177 // main-frame navigation. |
| 1178 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 1179 ConsoleMessage) { |
| 1180 ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
| 1181 Browser::CreateParams(browser()->profile())); |
| 1182 content::WebContents* original_contents = |
| 1183 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1184 content::WebContents* contents = |
| 1185 content::WebContents::Create(content::WebContents::CreateParams( |
| 1186 original_contents->GetBrowserContext())); |
| 1187 ASSERT_TRUE(contents); |
| 1188 contents->SetDelegate(delegate); |
| 1189 delegate->tab_strip_model()->AppendWebContents(contents, true); |
| 1190 int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
| 1191 delegate->tab_strip_model()->ActivateTabAt(index, true); |
| 1192 ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
| 1193 |
| 1194 // Navigate to an HTTP page. Use a non-local hostname so that is it |
| 1195 // not considered secure. |
| 1196 GURL http_url = |
| 1197 GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); |
| 1198 ui_test_utils::NavigateToURL(delegate, http_url); |
| 1199 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1200 ASSERT_TRUE(entry); |
| 1201 EXPECT_EQ(http_url, entry->GetURL()); |
| 1202 EXPECT_TRUE(delegate->console_messages().empty()); |
| 1203 |
| 1204 // Trigger the HTTP_SHOW_WARNING state. |
| 1205 base::RunLoop first_message; |
| 1206 delegate->set_console_message_callback(first_message.QuitClosure()); |
| 1207 contents->OnPasswordInputShownOnHttp(); |
| 1208 first_message.Run(); |
| 1209 |
| 1210 // Check that the HTTP_SHOW_WARNING state was actually triggered. |
| 1211 ChromeSecurityStateModelClient* client = |
| 1212 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1213 ASSERT_TRUE(client); |
| 1214 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1215 client->GetSecurityInfo(&security_info); |
| 1216 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1217 security_info.security_level); |
| 1218 |
| 1219 // Check that the expected console message is present. |
| 1220 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| 1221 delegate->ClearConsoleMessages(); |
| 1222 |
| 1223 // Two subsequent triggers of VisibleSSLStateChanged -- one on the |
| 1224 // same navigation and one on another navigation -- should only result |
| 1225 // in one additional console message. |
| 1226 contents->OnCreditCardInputShownOnHttp(); |
| 1227 GURL second_http_url = |
| 1228 GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
| 1229 ui_test_utils::NavigateToURL(delegate, second_http_url); |
| 1230 entry = contents->GetController().GetVisibleEntry(); |
| 1231 ASSERT_TRUE(entry); |
| 1232 EXPECT_EQ(second_http_url, entry->GetURL()); |
| 1233 |
| 1234 base::RunLoop second_message; |
| 1235 delegate->set_console_message_callback(second_message.QuitClosure()); |
| 1236 contents->OnPasswordInputShownOnHttp(); |
| 1237 second_message.Run(); |
| 1238 |
| 1239 client->GetSecurityInfo(&security_info); |
| 1240 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1241 security_info.security_level); |
| 1242 |
| 1243 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| 1244 } |
| 1245 |
| 1246 // Tests that additional HTTP_SHOW_WARNING console messages are not |
| 1247 // printed after subframe navigations. |
| 1248 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 1249 ConsoleMessageNotPrintedForFrameNavigation) { |
| 1250 ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
| 1251 Browser::CreateParams(browser()->profile())); |
| 1252 content::WebContents* original_contents = |
| 1253 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1254 content::WebContents* contents = |
| 1255 content::WebContents::Create(content::WebContents::CreateParams( |
| 1256 original_contents->GetBrowserContext())); |
| 1257 ASSERT_TRUE(contents); |
| 1258 contents->SetDelegate(delegate); |
| 1259 delegate->tab_strip_model()->AppendWebContents(contents, true); |
| 1260 int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
| 1261 delegate->tab_strip_model()->ActivateTabAt(index, true); |
| 1262 ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
| 1263 |
| 1264 // Navigate to an HTTP page. Use a non-local hostname so that is it |
| 1265 // not considered secure. |
| 1266 GURL http_url = GetURLWithNonLocalHostname(embedded_test_server(), |
| 1267 "/ssl/page_with_frame.html"); |
| 1268 ui_test_utils::NavigateToURL(delegate, http_url); |
| 1269 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1270 ASSERT_TRUE(entry); |
| 1271 EXPECT_EQ(http_url, entry->GetURL()); |
| 1272 EXPECT_TRUE(delegate->console_messages().empty()); |
| 1273 |
| 1274 // Trigger the HTTP_SHOW_WARNING state. |
| 1275 base::RunLoop first_message; |
| 1276 delegate->set_console_message_callback(first_message.QuitClosure()); |
| 1277 contents->OnPasswordInputShownOnHttp(); |
| 1278 first_message.Run(); |
| 1279 |
| 1280 // Check that the HTTP_SHOW_WARNING state was actually triggered. |
| 1281 ChromeSecurityStateModelClient* client = |
| 1282 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1283 ASSERT_TRUE(client); |
| 1284 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1285 client->GetSecurityInfo(&security_info); |
| 1286 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1287 security_info.security_level); |
| 1288 |
| 1289 // Check that the expected console message is present. |
| 1290 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| 1291 delegate->ClearConsoleMessages(); |
| 1292 |
| 1293 // Navigate the subframe and trigger VisibleSSLStateChanged |
| 1294 // again. While the security level is still HTTP_SHOW_WARNING, an |
| 1295 // additional console message should not be logged because there was |
| 1296 // already a console message logged for the current main-frame |
| 1297 // navigation. |
| 1298 content::WindowedNotificationObserver subframe_observer( |
| 1299 content::NOTIFICATION_LOAD_STOP, |
| 1300 content::Source<content::NavigationController>( |
| 1301 &contents->GetController())); |
| 1302 EXPECT_TRUE(content::ExecuteScript( |
| 1303 contents, "document.getElementById('navFrame').src = '/title2.html';")); |
| 1304 subframe_observer.Wait(); |
| 1305 contents->OnCreditCardInputShownOnHttp(); |
| 1306 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1307 security_info.security_level); |
| 1308 |
| 1309 // Do a main frame navigation and then trigger HTTP_SHOW_WARNING |
| 1310 // again. From the above subframe navigation and this main-frame |
| 1311 // navigation, exactly one console message is expected. |
| 1312 GURL second_http_url = |
| 1313 GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
| 1314 ui_test_utils::NavigateToURL(delegate, second_http_url); |
| 1315 entry = contents->GetController().GetVisibleEntry(); |
| 1316 ASSERT_TRUE(entry); |
| 1317 EXPECT_EQ(second_http_url, entry->GetURL()); |
| 1318 |
| 1319 base::RunLoop second_message; |
| 1320 delegate->set_console_message_callback(second_message.QuitClosure()); |
| 1321 contents->OnPasswordInputShownOnHttp(); |
| 1322 second_message.Run(); |
| 1323 |
| 1324 client->GetSecurityInfo(&security_info); |
| 1325 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1326 security_info.security_level); |
| 1327 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| 1328 } |
| 1329 |
| 1330 // Tests that additional HTTP_SHOW_WARNING console messages are not |
| 1331 // printed after pushState navigations. |
| 1332 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| 1333 ConsoleMessageNotPrintedForPushStateNavigation) { |
| 1334 ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
| 1335 Browser::CreateParams(browser()->profile())); |
| 1336 content::WebContents* original_contents = |
| 1337 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1338 content::WebContents* contents = |
| 1339 content::WebContents::Create(content::WebContents::CreateParams( |
| 1340 original_contents->GetBrowserContext())); |
| 1341 ASSERT_TRUE(contents); |
| 1342 contents->SetDelegate(delegate); |
| 1343 delegate->tab_strip_model()->AppendWebContents(contents, true); |
| 1344 int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
| 1345 delegate->tab_strip_model()->ActivateTabAt(index, true); |
| 1346 ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
| 1347 |
| 1348 // Navigate to an HTTP page. Use a non-local hostname so that is it |
| 1349 // not considered secure. |
| 1350 GURL http_url = |
| 1351 GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); |
| 1352 ui_test_utils::NavigateToURL(delegate, http_url); |
| 1353 content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| 1354 ASSERT_TRUE(entry); |
| 1355 EXPECT_EQ(http_url, entry->GetURL()); |
| 1356 EXPECT_TRUE(delegate->console_messages().empty()); |
| 1357 |
| 1358 // Trigger the HTTP_SHOW_WARNING state. |
| 1359 base::RunLoop first_message; |
| 1360 delegate->set_console_message_callback(first_message.QuitClosure()); |
| 1361 contents->OnPasswordInputShownOnHttp(); |
| 1362 first_message.Run(); |
| 1363 |
| 1364 // Check that the HTTP_SHOW_WARNING state was actually triggered. |
| 1365 ChromeSecurityStateModelClient* client = |
| 1366 ChromeSecurityStateModelClient::FromWebContents(contents); |
| 1367 ASSERT_TRUE(client); |
| 1368 security_state::SecurityStateModel::SecurityInfo security_info; |
| 1369 client->GetSecurityInfo(&security_info); |
| 1370 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1371 security_info.security_level); |
| 1372 |
| 1373 // Check that the expected console message is present. |
| 1374 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| 1375 delegate->ClearConsoleMessages(); |
| 1376 |
| 1377 // Navigate with pushState and trigger VisibleSSLStateChanged |
| 1378 // again. While the security level is still HTTP_SHOW_WARNING, an |
| 1379 // additional console message should not be logged because there was |
| 1380 // already a console message logged for the current main-frame |
| 1381 // navigation. |
| 1382 EXPECT_TRUE(content::ExecuteScript( |
| 1383 contents, "history.pushState({ foo: 'bar' }, 'foo', 'bar');")); |
| 1384 contents->OnCreditCardInputShownOnHttp(); |
| 1385 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1386 security_info.security_level); |
| 1387 |
| 1388 // Do a main frame navigation and then trigger HTTP_SHOW_WARNING |
| 1389 // again. From the above pushState navigation and this main-frame |
| 1390 // navigation, exactly one console message is expected. |
| 1391 GURL second_http_url = |
| 1392 GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
| 1393 ui_test_utils::NavigateToURL(delegate, second_http_url); |
| 1394 entry = contents->GetController().GetVisibleEntry(); |
| 1395 ASSERT_TRUE(entry); |
| 1396 EXPECT_EQ(second_http_url, entry->GetURL()); |
| 1397 |
| 1398 base::RunLoop second_message; |
| 1399 delegate->set_console_message_callback(second_message.QuitClosure()); |
| 1400 contents->OnPasswordInputShownOnHttp(); |
| 1401 second_message.Run(); |
| 1402 |
| 1403 client->GetSecurityInfo(&security_info); |
| 1404 EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| 1405 security_info.security_level); |
| 1406 ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| 1407 } |
| 1408 |
| 1122 // Tests that the SecurityStateModel for a WebContents is up to date | 1409 // Tests that the SecurityStateModel for a WebContents is up to date |
| 1123 // when the WebContents is inserted into a Browser's TabStripModel. | 1410 // when the WebContents is inserted into a Browser's TabStripModel. |
| 1124 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { | 1411 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { |
| 1125 ASSERT_TRUE(https_server_.Start()); | 1412 ASSERT_TRUE(https_server_.Start()); |
| 1126 SetUpMockCertVerifierForHttpsServer(0, net::OK); | 1413 SetUpMockCertVerifierForHttpsServer(0, net::OK); |
| 1127 | 1414 |
| 1128 content::WebContents* tab = | 1415 content::WebContents* tab = |
| 1129 browser()->tab_strip_model()->GetActiveWebContents(); | 1416 browser()->tab_strip_model()->GetActiveWebContents(); |
| 1130 ASSERT_TRUE(tab); | 1417 ASSERT_TRUE(tab); |
| 1131 | 1418 |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 ChromeSecurityStateModelClient* model_client = | 1956 ChromeSecurityStateModelClient* model_client = |
| 1670 ChromeSecurityStateModelClient::FromWebContents(web_contents); | 1957 ChromeSecurityStateModelClient::FromWebContents(web_contents); |
| 1671 ASSERT_TRUE(model_client); | 1958 ASSERT_TRUE(model_client); |
| 1672 SecurityStateModel::SecurityInfo security_info; | 1959 SecurityStateModel::SecurityInfo security_info; |
| 1673 model_client->GetSecurityInfo(&security_info); | 1960 model_client->GetSecurityInfo(&security_info); |
| 1674 EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); | 1961 EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); |
| 1675 EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); | 1962 EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); |
| 1676 } | 1963 } |
| 1677 | 1964 |
| 1678 } // namespace | 1965 } // namespace |
| OLD | NEW |