Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: chrome/browser/ssl/chrome_security_state_model_client_unittest.cc

Issue 2448943002: Refactor SecurityStateModel/Clients for simplicity and reusability. (Closed)
Patch Set: refactor -> SecurityStateTabHelper. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "chrome/browser/ssl/chrome_security_state_model_client.h"
6
7 #include "base/command_line.h"
8 #include "base/test/histogram_tester.h"
9 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
10 #include "components/security_state/security_state_model.h"
11 #include "components/security_state/switches.h"
12 #include "content/public/browser/security_style_explanation.h"
13 #include "content/public/browser/security_style_explanations.h"
14 #include "net/cert/cert_status_flags.h"
15 #include "net/ssl/ssl_cipher_suite_names.h"
16 #include "net/ssl/ssl_connection_status_flags.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace {
20
21 const char kHTTPBadHistogram[] =
22 "Security.HTTPBad.UserWarnedAboutSensitiveInput";
23
24 // Tests that SecurityInfo flags for subresources with certificate
25 // errors are reflected in the SecurityStyleExplanations produced by
26 // ChromeSecurityStateModelClient.
27 TEST(ChromeSecurityStateModelClientTest,
28 GetSecurityStyleForContentWithCertErrors) {
29 content::SecurityStyleExplanations explanations;
30 security_state::SecurityStateModel::SecurityInfo security_info;
31 security_info.cert_status = 0;
32 security_info.scheme_is_cryptographic = true;
33
34 security_info.content_with_cert_errors_status =
35 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN;
36 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
37 &explanations);
38 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
39 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
40
41 security_info.content_with_cert_errors_status =
42 security_state::SecurityStateModel::CONTENT_STATUS_RAN;
43 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
44 &explanations);
45 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
46 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
47
48 security_info.content_with_cert_errors_status =
49 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED;
50 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
51 &explanations);
52 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
53 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
54
55 security_info.content_with_cert_errors_status =
56 security_state::SecurityStateModel::CONTENT_STATUS_NONE;
57 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
58 &explanations);
59 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
60 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
61 }
62
63 // Tests that SecurityStyleExplanations for subresources with cert
64 // errors are *not* set when the main resource has major certificate
65 // errors. If the main resource has certificate errors, it would be
66 // duplicative/confusing to also report subresources with cert errors.
67 TEST(ChromeSecurityStateModelClientTest,
68 SubresourcesAndMainResourceWithMajorCertErrors) {
69 content::SecurityStyleExplanations explanations;
70 security_state::SecurityStateModel::SecurityInfo security_info;
71 security_info.cert_status = net::CERT_STATUS_DATE_INVALID;
72 security_info.scheme_is_cryptographic = true;
73
74 security_info.content_with_cert_errors_status =
75 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN;
76 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
77 &explanations);
78 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
79 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
80
81 security_info.content_with_cert_errors_status =
82 security_state::SecurityStateModel::CONTENT_STATUS_RAN;
83 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
84 &explanations);
85 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
86 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
87
88 security_info.content_with_cert_errors_status =
89 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED;
90 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
91 &explanations);
92 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
93 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
94
95 security_info.content_with_cert_errors_status =
96 security_state::SecurityStateModel::CONTENT_STATUS_NONE;
97 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
98 &explanations);
99 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
100 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
101 }
102
103 // Tests that SecurityStyleExplanations for subresources with cert
104 // errors are set when the main resource has only minor certificate
105 // errors. Minor errors on the main resource should not hide major
106 // errors on subresources.
107 TEST(ChromeSecurityStateModelClientTest,
108 SubresourcesAndMainResourceWithMinorCertErrors) {
109 content::SecurityStyleExplanations explanations;
110 security_state::SecurityStateModel::SecurityInfo security_info;
111 security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
112 security_info.scheme_is_cryptographic = true;
113
114 security_info.content_with_cert_errors_status =
115 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN;
116 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
117 &explanations);
118 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
119 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
120
121 security_info.content_with_cert_errors_status =
122 security_state::SecurityStateModel::CONTENT_STATUS_RAN;
123 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
124 &explanations);
125 EXPECT_TRUE(explanations.ran_content_with_cert_errors);
126 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
127
128 security_info.content_with_cert_errors_status =
129 security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED;
130 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
131 &explanations);
132 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
133 EXPECT_TRUE(explanations.displayed_content_with_cert_errors);
134
135 security_info.content_with_cert_errors_status =
136 security_state::SecurityStateModel::CONTENT_STATUS_NONE;
137 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
138 &explanations);
139 EXPECT_FALSE(explanations.ran_content_with_cert_errors);
140 EXPECT_FALSE(explanations.displayed_content_with_cert_errors);
141 }
142
143 bool FindSecurityStyleExplanation(
144 const std::vector<content::SecurityStyleExplanation>& explanations,
145 const char* summary,
146 content::SecurityStyleExplanation* explanation) {
147 for (const auto& entry : explanations) {
148 if (entry.summary == summary) {
149 *explanation = entry;
150 return true;
151 }
152 }
153
154 return false;
155 }
156
157 // Test that connection explanations are formated as expected. Note the strings
158 // are not translated and so will be the same in any locale.
159 TEST(ChromeSecurityStateModelClientTest, ConnectionExplanation) {
160 // Test a modern configuration with a key exchange group.
161 security_state::SecurityStateModel::SecurityInfo security_info;
162 security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
163 security_info.scheme_is_cryptographic = true;
164 net::SSLConnectionStatusSetCipherSuite(
165 0xcca8 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */,
166 &security_info.connection_status);
167 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
168 &security_info.connection_status);
169 security_info.key_exchange_group = 29; // X25519
170
171 {
172 content::SecurityStyleExplanations explanations;
173 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
174 &explanations);
175 content::SecurityStyleExplanation explanation;
176 ASSERT_TRUE(FindSecurityStyleExplanation(
177 explanations.secure_explanations, "Secure Connection", &explanation));
178 EXPECT_EQ(
179 "The connection to this site is encrypted and authenticated using a "
180 "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with "
181 "X25519), and a strong cipher (CHACHA20_POLY1305).",
182 explanation.description);
183 }
184
185 // Some older cache entries may be missing the key exchange group, despite
186 // having a cipher which should supply one.
187 security_info.key_exchange_group = 0;
188 {
189 content::SecurityStyleExplanations explanations;
190 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
191 &explanations);
192 content::SecurityStyleExplanation explanation;
193 ASSERT_TRUE(FindSecurityStyleExplanation(
194 explanations.secure_explanations, "Secure Connection", &explanation));
195 EXPECT_EQ(
196 "The connection to this site is encrypted and authenticated using a "
197 "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA), and a "
198 "strong cipher (CHACHA20_POLY1305).",
199 explanation.description);
200 }
201
202 // TLS 1.3 ciphers use the key exchange group exclusively.
203 net::SSLConnectionStatusSetCipherSuite(0x1301 /* TLS_AES_128_GCM_SHA256 */,
204 &security_info.connection_status);
205 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_3,
206 &security_info.connection_status);
207 security_info.key_exchange_group = 29; // X25519
208 {
209 content::SecurityStyleExplanations explanations;
210 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
211 &explanations);
212 content::SecurityStyleExplanation explanation;
213 ASSERT_TRUE(FindSecurityStyleExplanation(
214 explanations.secure_explanations, "Secure Connection", &explanation));
215 EXPECT_EQ(
216 "The connection to this site is encrypted and authenticated using a "
217 "strong protocol (TLS 1.3), a strong key exchange (X25519), and a "
218 "strong cipher (AES_128_GCM).",
219 explanation.description);
220 }
221 }
222
223 // Tests that a security level of HTTP_SHOW_WARNING produces a
224 // content::SecurityStyle of UNAUTHENTICATED, with an explanation.
225 TEST(ChromeSecurityStateModelClientTest, HTTPWarning) {
226 security_state::SecurityStateModel::SecurityInfo security_info;
227 content::SecurityStyleExplanations explanations;
228 security_info.security_level =
229 security_state::SecurityStateModel::HTTP_SHOW_WARNING;
230 blink::WebSecurityStyle security_style =
231 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
232 &explanations);
233 EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, security_style);
234 EXPECT_EQ(1u, explanations.unauthenticated_explanations.size());
235 }
236
237 // Tests that a security level of NONE when there is a password or
238 // credit card field on HTTP produces a content::SecurityStyle of
239 // UNAUTHENTICATED, with an info explanation.
240 TEST(ChromeSecurityStateModelClientTest, HTTPWarningInFuture) {
241 security_state::SecurityStateModel::SecurityInfo security_info;
242 content::SecurityStyleExplanations explanations;
243 security_info.security_level = security_state::SecurityStateModel::NONE;
244 security_info.displayed_private_user_data_input_on_http = true;
245 blink::WebSecurityStyle security_style =
246 ChromeSecurityStateModelClient::GetSecurityStyle(security_info,
247 &explanations);
248 EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, security_style);
249 EXPECT_EQ(1u, explanations.info_explanations.size());
250 }
251
252 class ChromeSecurityStateModelClientHistogramTest
253 : public ChromeRenderViewHostTestHarness {
254 public:
255 ChromeSecurityStateModelClientHistogramTest() {}
256 ~ChromeSecurityStateModelClientHistogramTest() override {}
257
258 void SetUp() override {
259 ChromeRenderViewHostTestHarness::SetUp();
260
261 ChromeSecurityStateModelClient::CreateForWebContents(web_contents());
262 client_ = ChromeSecurityStateModelClient::FromWebContents(web_contents());
263 navigate_to_http();
264 }
265
266 protected:
267 ChromeSecurityStateModelClient* client() { return client_; }
268
269 void signal_password() {
270 web_contents()->OnPasswordInputShownOnHttp();
271 client_->VisibleSecurityStateChanged();
272 }
273
274 void navigate_to_http() { NavigateAndCommit(GURL("http://example.test")); }
275
276 private:
277 ChromeSecurityStateModelClient* client_;
278 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientHistogramTest);
279 };
280
281 // Tests that UMA logs the omnibox warning when security level is
282 // HTTP_SHOW_WARNING.
283 TEST_F(ChromeSecurityStateModelClientHistogramTest,
284 HTTPOmniboxWarningHistogram) {
285 // Show Warning Chip.
286 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
287 security_state::switches::kMarkHttpAs,
288 security_state::switches::kMarkHttpWithPasswordsOrCcWithChip);
289
290 base::HistogramTester histograms;
291 signal_password();
292 histograms.ExpectUniqueSample(kHTTPBadHistogram, true, 1);
293
294 // Fire again and ensure no sample is recorded.
295 signal_password();
296 histograms.ExpectUniqueSample(kHTTPBadHistogram, true, 1);
297
298 // Navigate to a new page and ensure a sample is recorded.
299 navigate_to_http();
300 histograms.ExpectUniqueSample(kHTTPBadHistogram, true, 1);
301 signal_password();
302 histograms.ExpectUniqueSample(kHTTPBadHistogram, true, 2);
303 }
304
305 // Tests that UMA logs the console warning when security level is NONE.
306 TEST_F(ChromeSecurityStateModelClientHistogramTest,
307 HTTPConsoleWarningHistogram) {
308 // Show Neutral for HTTP
309 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
310 security_state::switches::kMarkHttpAs,
311 security_state::switches::kMarkHttpAsNeutral);
312
313 base::HistogramTester histograms;
314 signal_password();
315 histograms.ExpectUniqueSample(kHTTPBadHistogram, false, 1);
316
317 // Fire again and ensure no sample is recorded.
318 signal_password();
319 histograms.ExpectUniqueSample(kHTTPBadHistogram, false, 1);
320
321 // Navigate to a new page and ensure a sample is recorded.
322 navigate_to_http();
323 histograms.ExpectUniqueSample(kHTTPBadHistogram, false, 1);
324 signal_password();
325 histograms.ExpectUniqueSample(kHTTPBadHistogram, false, 2);
326 }
327
328 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698