1 // Copyright 2012 The Chromium Authors
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 "net/http/http_security_headers.h"
6
7 #include <stdint.h>
8
9 #include <iterator>
10
11 #include "base/base64.h"
12 #include "base/stl_util.h"
13 #include "crypto/sha2.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/http/http_util.h"
17 #include "net/http/transport_security_state.h"
18 #include "net/ssl/ssl_info.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace net {
22
23 namespace {
24
25 namespace test_default {
26 #include "base/time/time.h"
27 #include "net/http/transport_security_state_static_unittest_default.h"
28 }
29
30 } // anonymous namespace
31
32 class HttpSecurityHeadersTest : public testing::Test {
33 public:
~HttpSecurityHeadersTest()34 ~HttpSecurityHeadersTest() override {
35 SetTransportSecurityStateSourceForTesting(nullptr);
36 }
37 };
38
TEST_F(HttpSecurityHeadersTest,LeadingTrailingSemicolons)39 TEST_F(HttpSecurityHeadersTest, LeadingTrailingSemicolons) {
40 base::TimeDelta max_age;
41 bool include_subdomains = false;
42
43 const char* test_cases[] = {
44 "max-age=123", ";max-age=123", ";;max-age=123",
45 ";;;;max-age=123", "; ;max-age=123", "; ; max-age=123",
46 ";max-age=123;", ";;max-age=123;;", ";;;;max-age=123;;;;",
47 "; ;max-age=123; ;", "; ; max-age=123; ; ", "max-age=123;",
48 "max-age=123;;", "max-age=123;;;;", "max-age=123; ;",
49 "max-age=123; ; ",
50 };
51 for (const char* value : test_cases) {
52 SCOPED_TRACE(value);
53 EXPECT_TRUE(ParseHSTSHeader(value, &max_age, &include_subdomains));
54 EXPECT_EQ(base::Seconds(123), max_age);
55 EXPECT_FALSE(include_subdomains);
56 }
57 }
58
TEST_F(HttpSecurityHeadersTest,InvalidDirectiveNames)59 TEST_F(HttpSecurityHeadersTest, InvalidDirectiveNames) {
60 base::TimeDelta max_age;
61 bool include_subdomains = false;
62
63 const char* test_cases[] = {
64 "'max-age'=1",
65 "\"max-age\"=1",
66 "max-age=1; max-age=2",
67 "max-age=1; MaX-AgE=2",
68 "max-age=1; includeSubDomains; iNcLUdEsUbDoMaInS",
69 "max-age=1; \"",
70 "max-age=1; \"includeSubdomains",
71 "max-age=1; in\"cludeSubdomains",
72 "max-age=1; includeSubdomains\"",
73 "max-age=1; \"includeSubdomains\"",
74 "max-age=1; includeSubdomains; non\"token",
75 "max-age=1; includeSubdomains; non@token",
76 "max-age=1; includeSubdomains; non,token",
77 "max-age=1; =2",
78 "max-age=1; =2; unknownDirective",
79 };
80
81 for (const char* value : test_cases) {
82 SCOPED_TRACE(value);
83 EXPECT_FALSE(ParseHSTSHeader(value, &max_age, &include_subdomains));
84 }
85 }
86
TEST_F(HttpSecurityHeadersTest,InvalidDirectiveValues)87 TEST_F(HttpSecurityHeadersTest, InvalidDirectiveValues) {
88 base::TimeDelta max_age;
89 bool include_subdomains = false;
90
91 const char* test_cases[] = {
92 "max-age=",
93 "max-age=@",
94 "max-age=1a;",
95 "max-age=1a2;",
96 "max-age=1##;",
97 "max-age=12\";",
98 "max-age=-1;",
99 "max-age=+1;",
100 "max-age='1';",
101 "max-age=1abc;",
102 "max-age=1 abc;",
103 "max-age=1.5;",
104 "max-age=1; includeSubDomains=true",
105 "max-age=1; includeSubDomains=false",
106 "max-age=1; includeSubDomains=\"\"",
107 "max-age=1; includeSubDomains=''",
108 "max-age=1; includeSubDomains=\"true\"",
109 "max-age=1; includeSubDomains=\"false\"",
110 "max-age=1; unknownDirective=non\"token",
111 "max-age=1; unknownDirective=non@token",
112 "max-age=1; unknownDirective=non,token",
113 "max-age=1; unknownDirective=",
114 };
115
116 for (const char* value : test_cases) {
117 SCOPED_TRACE(value);
118 EXPECT_FALSE(ParseHSTSHeader(value, &max_age, &include_subdomains));
119 }
120 }
121
TEST_F(HttpSecurityHeadersTest,BogusHeaders)122 TEST_F(HttpSecurityHeadersTest, BogusHeaders) {
123 base::TimeDelta max_age;
124 bool include_subdomains = false;
125
126 EXPECT_FALSE(
127 ParseHSTSHeader(std::string(), &max_age, &include_subdomains));
128 EXPECT_FALSE(ParseHSTSHeader(" ", &max_age, &include_subdomains));
129 EXPECT_FALSE(ParseHSTSHeader("abc", &max_age, &include_subdomains));
130 EXPECT_FALSE(ParseHSTSHeader(" abc", &max_age, &include_subdomains));
131 EXPECT_FALSE(ParseHSTSHeader(" abc ", &max_age, &include_subdomains));
132 EXPECT_FALSE(ParseHSTSHeader("max-age", &max_age, &include_subdomains));
133 EXPECT_FALSE(ParseHSTSHeader(" max-age", &max_age,
134 &include_subdomains));
135 EXPECT_FALSE(ParseHSTSHeader(" max-age ", &max_age,
136 &include_subdomains));
137 EXPECT_FALSE(ParseHSTSHeader("max-age=", &max_age, &include_subdomains));
138 EXPECT_FALSE(ParseHSTSHeader(" max-age=", &max_age,
139 &include_subdomains));
140 EXPECT_FALSE(ParseHSTSHeader(" max-age =", &max_age,
141 &include_subdomains));
142 EXPECT_FALSE(ParseHSTSHeader(" max-age= ", &max_age,
143 &include_subdomains));
144 EXPECT_FALSE(ParseHSTSHeader(" max-age = ", &max_age,
145 &include_subdomains));
146 EXPECT_FALSE(ParseHSTSHeader(" max-age = xy", &max_age,
147 &include_subdomains));
148 EXPECT_FALSE(ParseHSTSHeader(" max-age = 3488a923", &max_age,
149 &include_subdomains));
150 EXPECT_FALSE(ParseHSTSHeader("max-age=3488a923 ", &max_age,
151 &include_subdomains));
152 EXPECT_FALSE(ParseHSTSHeader("max-ag=3488923", &max_age,
153 &include_subdomains));
154 EXPECT_FALSE(ParseHSTSHeader("max-aged=3488923", &max_age,
155 &include_subdomains));
156 EXPECT_FALSE(ParseHSTSHeader("max-age==3488923", &max_age,
157 &include_subdomains));
158 EXPECT_FALSE(ParseHSTSHeader("amax-age=3488923", &max_age,
159 &include_subdomains));
160 EXPECT_FALSE(ParseHSTSHeader("max-age=-3488923", &max_age,
161 &include_subdomains));
162 EXPECT_FALSE(
163 ParseHSTSHeader("max-age=+3488923", &max_age, &include_subdomains));
164 EXPECT_FALSE(
165 ParseHSTSHeader("max-age=13####", &max_age, &include_subdomains));
166 EXPECT_FALSE(ParseHSTSHeader("max-age=9223372036854775807#####", &max_age,
167 &include_subdomains));
168 EXPECT_FALSE(ParseHSTSHeader("max-age=18446744073709551615####", &max_age,
169 &include_subdomains));
170 EXPECT_FALSE(ParseHSTSHeader("max-age=999999999999999999999999$.&#!",
171 &max_age, &include_subdomains));
172 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 e", &max_age,
173 &include_subdomains));
174 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain",
175 &max_age, &include_subdomains));
176 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923includesubdomains",
177 &max_age, &include_subdomains));
178 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923=includesubdomains",
179 &max_age, &include_subdomains));
180 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainx",
181 &max_age, &include_subdomains));
182 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=",
183 &max_age, &include_subdomains));
184 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=true",
185 &max_age, &include_subdomains));
186 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainsx",
187 &max_age, &include_subdomains));
188 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomains x",
189 &max_age, &include_subdomains));
190 EXPECT_FALSE(ParseHSTSHeader("max-age=34889.23 includesubdomains",
191 &max_age, &include_subdomains));
192 EXPECT_FALSE(ParseHSTSHeader("max-age=34889 includesubdomains",
193 &max_age, &include_subdomains));
194 EXPECT_FALSE(ParseHSTSHeader(";;;; ;;;",
195 &max_age, &include_subdomains));
196 EXPECT_FALSE(ParseHSTSHeader(";;;; includeSubDomains;;;",
197 &max_age, &include_subdomains));
198 EXPECT_FALSE(ParseHSTSHeader(" includeSubDomains; ",
199 &max_age, &include_subdomains));
200 EXPECT_FALSE(ParseHSTSHeader(";",
201 &max_age, &include_subdomains));
202 EXPECT_FALSE(ParseHSTSHeader("max-age; ;",
203 &max_age, &include_subdomains));
204
205 // Check the out args were not updated by checking the default
206 // values for its predictable fields.
207 EXPECT_EQ(0, max_age.InSeconds());
208 EXPECT_FALSE(include_subdomains);
209 }
210
TEST_F(HttpSecurityHeadersTest,ValidSTSHeaders)211 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
212 base::TimeDelta max_age;
213 base::TimeDelta expect_max_age;
214 bool include_subdomains = false;
215
216 EXPECT_TRUE(ParseHSTSHeader("max-age=243", &max_age,
217 &include_subdomains));
218 expect_max_age = base::Seconds(243);
219 EXPECT_EQ(expect_max_age, max_age);
220 EXPECT_FALSE(include_subdomains);
221
222 EXPECT_TRUE(ParseHSTSHeader("max-age=3488923;", &max_age,
223 &include_subdomains));
224
225 EXPECT_TRUE(ParseHSTSHeader(" Max-agE = 567", &max_age,
226 &include_subdomains));
227 expect_max_age = base::Seconds(567);
228 EXPECT_EQ(expect_max_age, max_age);
229 EXPECT_FALSE(include_subdomains);
230
231 EXPECT_TRUE(ParseHSTSHeader(" mAx-aGe = 890 ", &max_age,
232 &include_subdomains));
233 expect_max_age = base::Seconds(890);
234 EXPECT_EQ(expect_max_age, max_age);
235 EXPECT_FALSE(include_subdomains);
236
237 EXPECT_TRUE(ParseHSTSHeader("max-age=123;incLudesUbdOmains", &max_age,
238 &include_subdomains));
239 expect_max_age = base::Seconds(123);
240 EXPECT_EQ(expect_max_age, max_age);
241 EXPECT_TRUE(include_subdomains);
242
243 EXPECT_TRUE(ParseHSTSHeader("incLudesUbdOmains; max-age=123", &max_age,
244 &include_subdomains));
245 expect_max_age = base::Seconds(123);
246 EXPECT_EQ(expect_max_age, max_age);
247 EXPECT_TRUE(include_subdomains);
248
249 EXPECT_TRUE(ParseHSTSHeader(" incLudesUbdOmains; max-age=123",
250 &max_age, &include_subdomains));
251 expect_max_age = base::Seconds(123);
252 EXPECT_EQ(expect_max_age, max_age);
253 EXPECT_TRUE(include_subdomains);
254
255 EXPECT_TRUE(ParseHSTSHeader(
256 " incLudesUbdOmains; max-age=123; pumpkin=kitten", &max_age,
257 &include_subdomains));
258 expect_max_age = base::Seconds(123);
259 EXPECT_EQ(expect_max_age, max_age);
260 EXPECT_TRUE(include_subdomains);
261
262 EXPECT_TRUE(ParseHSTSHeader(
263 " pumpkin=894; incLudesUbdOmains; max-age=123 ", &max_age,
264 &include_subdomains));
265 expect_max_age = base::Seconds(123);
266 EXPECT_EQ(expect_max_age, max_age);
267 EXPECT_TRUE(include_subdomains);
268
269 EXPECT_TRUE(ParseHSTSHeader(
270 " pumpkin; incLudesUbdOmains; max-age=123 ", &max_age,
271 &include_subdomains));
272 expect_max_age = base::Seconds(123);
273 EXPECT_EQ(expect_max_age, max_age);
274 EXPECT_TRUE(include_subdomains);
275
276 EXPECT_TRUE(ParseHSTSHeader(
277 " pumpkin; incLudesUbdOmains; max-age=\"123\" ", &max_age,
278 &include_subdomains));
279 expect_max_age = base::Seconds(123);
280 EXPECT_EQ(expect_max_age, max_age);
281 EXPECT_TRUE(include_subdomains);
282
283 EXPECT_TRUE(ParseHSTSHeader(
284 "animal=\"squirrel; distinguished\"; incLudesUbdOmains; max-age=123",
285 &max_age, &include_subdomains));
286 expect_max_age = base::Seconds(123);
287 EXPECT_EQ(expect_max_age, max_age);
288 EXPECT_TRUE(include_subdomains);
289
290 EXPECT_TRUE(ParseHSTSHeader("max-age=394082; incLudesUbdOmains",
291 &max_age, &include_subdomains));
292 expect_max_age = base::Seconds(394082);
293 EXPECT_EQ(expect_max_age, max_age);
294 EXPECT_TRUE(include_subdomains);
295
296 EXPECT_TRUE(ParseHSTSHeader(
297 "max-age=39408299 ;incLudesUbdOmains", &max_age,
298 &include_subdomains));
299 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 39408299u));
300 EXPECT_EQ(expect_max_age, max_age);
301 EXPECT_TRUE(include_subdomains);
302
303 EXPECT_TRUE(ParseHSTSHeader(
304 "max-age=394082038 ; incLudesUbdOmains", &max_age,
305 &include_subdomains));
306 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 394082038u));
307 EXPECT_EQ(expect_max_age, max_age);
308 EXPECT_TRUE(include_subdomains);
309
310 EXPECT_TRUE(ParseHSTSHeader(
311 "max-age=394082038 ; incLudesUbdOmains;", &max_age,
312 &include_subdomains));
313 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 394082038u));
314 EXPECT_EQ(expect_max_age, max_age);
315 EXPECT_TRUE(include_subdomains);
316
317 EXPECT_TRUE(ParseHSTSHeader(
318 ";; max-age=394082038 ; incLudesUbdOmains; ;", &max_age,
319 &include_subdomains));
320 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 394082038u));
321 EXPECT_EQ(expect_max_age, max_age);
322 EXPECT_TRUE(include_subdomains);
323
324 EXPECT_TRUE(ParseHSTSHeader(
325 ";; max-age=394082038 ;", &max_age,
326 &include_subdomains));
327 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 394082038u));
328 EXPECT_EQ(expect_max_age, max_age);
329 EXPECT_FALSE(include_subdomains);
330
331 EXPECT_TRUE(ParseHSTSHeader(
332 ";; ; ; max-age=394082038;;; includeSubdomains ;; ;", &max_age,
333 &include_subdomains));
334 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 394082038u));
335 EXPECT_EQ(expect_max_age, max_age);
336 EXPECT_TRUE(include_subdomains);
337
338 EXPECT_TRUE(ParseHSTSHeader(
339 "incLudesUbdOmains ; max-age=394082038 ;;", &max_age,
340 &include_subdomains));
341 expect_max_age = base::Seconds(std::min(kMaxHSTSAgeSecs, 394082038u));
342 EXPECT_EQ(expect_max_age, max_age);
343 EXPECT_TRUE(include_subdomains);
344
345 EXPECT_TRUE(ParseHSTSHeader(
346 " max-age=0 ; incLudesUbdOmains ", &max_age,
347 &include_subdomains));
348 expect_max_age = base::Seconds(0);
349 EXPECT_EQ(expect_max_age, max_age);
350 EXPECT_TRUE(include_subdomains);
351
352 EXPECT_TRUE(ParseHSTSHeader(
353 " max-age=999999999999999999999999999999999999999999999 ;"
354 " incLudesUbdOmains ", &max_age, &include_subdomains));
355 expect_max_age = base::Seconds(kMaxHSTSAgeSecs);
356 EXPECT_EQ(expect_max_age, max_age);
357 EXPECT_TRUE(include_subdomains);
358 }
359
360 } // namespace net
361