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/cookies/cookie_util.h"
6
7 #include <memory>
8 #include <optional>
9 #include <string>
10 #include <tuple>
11 #include <utility>
12 #include <vector>
13
14 #include "base/containers/contains.h"
15 #include "base/functional/callback.h"
16 #include "base/strings/strcat.h"
17 #include "base/strings/string_split.h"
18 #include "base/test/bind.h"
19 #include "base/test/scoped_feature_list.h"
20 #include "base/time/time.h"
21 #include "net/base/features.h"
22 #include "net/cookies/cookie_constants.h"
23 #include "net/cookies/cookie_options.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "url/origin.h"
27
28 namespace net {
29
30 namespace {
31
32 struct RequestCookieParsingTest {
33 std::string str;
34 base::StringPairs parsed;
35 // Used for malformed cookies where the parsed-then-serialized string does not
36 // match the original string.
37 std::string serialized;
38 };
39
CheckParse(const std::string & str,const base::StringPairs & parsed_expected)40 void CheckParse(const std::string& str,
41 const base::StringPairs& parsed_expected) {
42 cookie_util::ParsedRequestCookies parsed;
43 cookie_util::ParseRequestCookieLine(str, &parsed);
44 EXPECT_EQ(parsed_expected, parsed);
45 }
46
CheckSerialize(const base::StringPairs & parsed,const std::string & str_expected)47 void CheckSerialize(const base::StringPairs& parsed,
48 const std::string& str_expected) {
49 EXPECT_EQ(str_expected, cookie_util::SerializeRequestCookieLine(parsed));
50 }
51
TEST(CookieUtilTest,TestDomainIsHostOnly)52 TEST(CookieUtilTest, TestDomainIsHostOnly) {
53 const struct {
54 const char* str;
55 const bool is_host_only;
56 } tests[] = {{"", true}, {"www.foo.com", true}, {".foo.com", false}};
57
58 for (const auto& test : tests) {
59 EXPECT_EQ(test.is_host_only, cookie_util::DomainIsHostOnly(test.str));
60 }
61 }
62
63 // A cookie domain containing non-ASCII characters is not allowed, even if it
64 // matches the domain from the URL.
TEST(CookieUtilTest,GetCookieDomainWithString_NonASCII)65 TEST(CookieUtilTest, GetCookieDomainWithString_NonASCII) {
66 base::test::ScopedFeatureList feature_list;
67 feature_list.InitAndEnableFeature(features::kCookieDomainRejectNonASCII);
68
69 CookieInclusionStatus status;
70 std::string result;
71 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
72 GURL("http://éxample.com"), "éxample.com", status, &result));
73 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
74 {CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII}));
75 }
76
77 // An empty domain string results in the domain from the URL.
TEST(CookieUtilTest,GetCookieDomainWithString_Empty)78 TEST(CookieUtilTest, GetCookieDomainWithString_Empty) {
79 CookieInclusionStatus status;
80 std::string result;
81 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(GURL("http://example.com"),
82 "", status, &result));
83 EXPECT_TRUE(status.IsInclude());
84 EXPECT_EQ(result, "example.com");
85 }
86
87 // A cookie domain string equal to the URL host, when that is an IP, results in
88 // the IP.
TEST(CookieUtilTest,GetCookieDomainWithString_IP)89 TEST(CookieUtilTest, GetCookieDomainWithString_IP) {
90 CookieInclusionStatus status;
91 std::string result;
92 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
93 GURL("http://192.0.2.3"), "192.0.2.3", status, &result));
94 EXPECT_TRUE(status.IsInclude());
95 EXPECT_EQ(result, "192.0.2.3");
96 }
97
98 // A cookie domain string equal to a dot prefixed to the URL host, when that is
99 // an IP, results in the IP, without the dot.
TEST(CookieUtilTest,GetCookieDomainWithString_DotIP)100 TEST(CookieUtilTest, GetCookieDomainWithString_DotIP) {
101 CookieInclusionStatus status;
102 std::string result;
103 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
104 GURL("http://192.0.2.3"), ".192.0.2.3", status, &result));
105 EXPECT_TRUE(status.IsInclude());
106 EXPECT_EQ(result, "192.0.2.3");
107 }
108
109 // A cookie domain string containing %-encoding is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_PercentEncoded)110 TEST(CookieUtilTest, GetCookieDomainWithString_PercentEncoded) {
111 CookieInclusionStatus status;
112 std::string result;
113 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
114 GURL("http://a.test"), "a%2Etest", status, &result));
115 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
116 }
117
118 // A cookie domain string that cannot be canonicalized is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_UnCanonicalizable)119 TEST(CookieUtilTest, GetCookieDomainWithString_UnCanonicalizable) {
120 CookieInclusionStatus status;
121 std::string result;
122 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
123 GURL("http://a.test"), "a^test", status, &result));
124 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
125 }
126
127 // A cookie domain that is an eTLD but matches the URL results in a host cookie
128 // domain.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldMatchesUrl)129 TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl) {
130 CookieInclusionStatus status;
131 std::string result;
132 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
133 GURL("http://gov.uk"), "gov.uk", status, &result));
134 EXPECT_TRUE(status.IsInclude());
135 EXPECT_EQ(result, "gov.uk");
136 }
137
138 // A cookie domain that is an eTLD but matches the URL results in a host cookie
139 // domain, even if it is given with a dot prefix.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldMatchesUrl_DotPrefix)140 TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl_DotPrefix) {
141 CookieInclusionStatus status;
142 std::string result;
143 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
144 GURL("http://gov.uk"), ".gov.uk", status, &result));
145 EXPECT_TRUE(status.IsInclude());
146 EXPECT_EQ(result, "gov.uk");
147 }
148
149 // A cookie domain that is an eTLD but matches the URL results in a host cookie
150 // domain, even if its capitalization is non-canonical.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldMatchesUrl_NonCanonical)151 TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl_NonCanonical) {
152 CookieInclusionStatus status;
153 std::string result;
154 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
155 GURL("http://gov.uk"), "GoV.Uk", status, &result));
156 EXPECT_TRUE(status.IsInclude());
157 EXPECT_EQ(result, "gov.uk");
158 }
159
160 // A cookie domain that is an eTLD but does not match the URL is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldDifferentUrl)161 TEST(CookieUtilTest, GetCookieDomainWithString_ETldDifferentUrl) {
162 CookieInclusionStatus status;
163 std::string result;
164 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
165 GURL("http://nhs.gov.uk"), "gov.uk", status, &result));
166 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
167 }
168
169 // A cookie domain with a different eTLD+1 ("organization-identifying host")
170 // from the URL is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_DifferentOrgHost)171 TEST(CookieUtilTest, GetCookieDomainWithString_DifferentOrgHost) {
172 CookieInclusionStatus status;
173 std::string result;
174 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
175 GURL("http://portal.globex.com"), "portal.initech.com", status, &result));
176 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
177 }
178
179 // A cookie domain that matches the URL results in a domain cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_MatchesUrl)180 TEST(CookieUtilTest, GetCookieDomainWithString_MatchesUrl) {
181 CookieInclusionStatus status;
182 std::string result;
183 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
184 GURL("http://globex.com"), "globex.com", status, &result));
185 EXPECT_TRUE(status.IsInclude());
186 EXPECT_EQ(result, ".globex.com");
187 }
188
189 // A cookie domain that matches the URL but has a `.` prefix results in a domain
190 // cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_MatchesUrlWithDot)191 TEST(CookieUtilTest, GetCookieDomainWithString_MatchesUrlWithDot) {
192 CookieInclusionStatus status;
193 std::string result;
194 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
195 GURL("http://globex.com"), ".globex.com", status, &result));
196 EXPECT_TRUE(status.IsInclude());
197 EXPECT_EQ(result, ".globex.com");
198 }
199
200 // A cookie domain that is a subdomain of the URL host is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_Subdomain)201 TEST(CookieUtilTest, GetCookieDomainWithString_Subdomain) {
202 CookieInclusionStatus status;
203 std::string result;
204 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
205 GURL("http://globex.com"), "mail.globex.com", status, &result));
206 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
207 }
208
209 // A URL that is a subdomain of the cookie domain results in a domain cookie.
TEST(CookieUtilTest,GetCookieDomainWithString_UrlSubdomain)210 TEST(CookieUtilTest, GetCookieDomainWithString_UrlSubdomain) {
211 CookieInclusionStatus status;
212 std::string result;
213 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
214 GURL("http://mail.globex.com"), "globex.com", status, &result));
215 EXPECT_TRUE(status.IsInclude());
216 EXPECT_EQ(result, ".globex.com");
217 }
218
219 // A URL of which the cookie domain is a substring, but not a dotted suffix,
220 // is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_SubstringButUrlNotSubdomain)221 TEST(CookieUtilTest, GetCookieDomainWithString_SubstringButUrlNotSubdomain) {
222 CookieInclusionStatus status;
223 std::string result;
224 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
225 GURL("http://myglobex.com"), "globex.com", status, &result));
226 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
227 }
228
229 // A URL which has a different subdomain of the eTLD+1 than the cookie domain is
230 // not allowed, regardless of which hostname is longer.
TEST(CookieUtilTest,GetCookieDomainWithString_DifferentSubdomain)231 TEST(CookieUtilTest, GetCookieDomainWithString_DifferentSubdomain) {
232 CookieInclusionStatus status;
233 std::string result;
234 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
235 GURL("http://l.globex.com"), "portal.globex.com", status, &result));
236 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
237 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
238 GURL("http://portal.globex.com"), "l.globex.com", status, &result));
239 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
240 }
241
242 // A URL without a host can set a "host" cookie with no cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_NoUrlHost)243 TEST(CookieUtilTest, GetCookieDomainWithString_NoUrlHost) {
244 CookieInclusionStatus status;
245 std::string result;
246 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
247 GURL("file:///C:/bar.html"), "", status, &result));
248 EXPECT_EQ(result, "");
249 }
250
251 // A URL with two trailing dots (which is an invalid hostname per
252 // rfc6265bis-11#5.1.2 and will cause GetDomainAndRegistry to return an empty
253 // string) is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_TrailingDots)254 TEST(CookieUtilTest, GetCookieDomainWithString_TrailingDots) {
255 CookieInclusionStatus status;
256 std::string result;
257 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
258 GURL("http://foo.com../"), "foo.com..", status, &result));
259 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
260 }
261
262 // A "normal" URL does not match with a cookie containing two trailing dots (or
263 // just one).
TEST(CookieUtilTest,GetCookieDomainWithString_TrailingDots_NotMatchingUrlHost)264 TEST(CookieUtilTest,
265 GetCookieDomainWithString_TrailingDots_NotMatchingUrlHost) {
266 CookieInclusionStatus status;
267 std::string result;
268 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
269 GURL("http://foo.com/"), ".foo.com..", status, &result));
270 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
271 EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
272 GURL("http://foo.com/"), ".foo.com.", status, &result));
273 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
274 }
275
276 // A URL containing an IP address is allowed, if that IP matches the cookie
277 // domain.
TEST(CookieUtilTest,GetCookieDomainWithString_UrlHostIP)278 TEST(CookieUtilTest, GetCookieDomainWithString_UrlHostIP) {
279 CookieInclusionStatus status;
280 std::string result;
281 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
282 GURL("http://192.0.2.3/"), "192.0.2.3", status, &result));
283 EXPECT_EQ(result, "192.0.2.3");
284 }
285
286 // A cookie domain with a dot-prefixed IP is allowed, if the IP matches
287 // the URL, but is transformed to a host cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_UrlHostIP_DomainCookie)288 TEST(CookieUtilTest, GetCookieDomainWithString_UrlHostIP_DomainCookie) {
289 CookieInclusionStatus status;
290 std::string result;
291 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
292 GURL("http://192.0.2.3/"), ".192.0.2.3", status, &result));
293 EXPECT_EQ(result, "192.0.2.3"); // No dot.
294 }
295
296 // A URL containing a TLD that is unknown as a registry is allowed, if it
297 // matches the cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_UnknownRegistry)298 TEST(CookieUtilTest, GetCookieDomainWithString_UnknownRegistry) {
299 CookieInclusionStatus status;
300 std::string result;
301 EXPECT_TRUE(cookie_util::GetCookieDomainWithString(GURL("http://bar/"), "bar",
302 status, &result));
303 EXPECT_EQ(result, "bar");
304 }
305
TEST(CookieUtilTest,TestCookieDateParsing)306 TEST(CookieUtilTest, TestCookieDateParsing) {
307 const struct {
308 const char* str;
309 const bool valid;
310 const double epoch;
311 } tests[] = {
312 {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
313 {"Thu, 19-Apr-2007 16:00:00 GMT", true, 1176998400},
314 {"Wed, 25 Apr 2007 21:02:13 GMT", true, 1177534933},
315 {"Thu, 19/Apr\\2007 16:00:00 GMT", true, 1176998400},
316 {"Fri, 1 Jan 2010 01:01:50 GMT", true, 1262307710},
317 {"Wednesday, 1-Jan-2003 00:00:00 GMT", true, 1041379200},
318 {", 1-Jan-2003 00:00:00 GMT", true, 1041379200},
319 {" 1-Jan-2003 00:00:00 GMT", true, 1041379200},
320 {"1-Jan-2003 00:00:00 GMT", true, 1041379200},
321 {"Wed,18-Apr-07 22:50:12 GMT", true, 1176936612},
322 {"WillyWonka , 18-Apr-07 22:50:12 GMT", true, 1176936612},
323 {"WillyWonka , 18-Apr-07 22:50:12", true, 1176936612},
324 {"WillyWonka , 18-apr-07 22:50:12", true, 1176936612},
325 {"Mon, 18-Apr-1977 22:50:13 GMT", true, 230251813},
326 {"Mon, 18-Apr-77 22:50:13 GMT", true, 230251813},
327 // If the cookie came in with the expiration quoted (which in terms of
328 // the RFC you shouldn't do), we will get string quoted. Bug 1261605.
329 {"\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082},
330 // Test with full month names and partial names.
331 {"Partyday, 18- April-07 22:50:12", true, 1176936612},
332 {"Partyday, 18 - Apri-07 22:50:12", true, 1176936612},
333 {"Wednes, 1-Januar-2003 00:00:00 GMT", true, 1041379200},
334 // Test that we always take GMT even with other time zones or bogus
335 // values. The RFC says everything should be GMT, and in the worst case
336 // we are 24 hours off because of zone issues.
337 {"Sat, 15-Apr-17 21:01:22", true, 1492290082},
338 {"Sat, 15-Apr-17 21:01:22 GMT-2", true, 1492290082},
339 {"Sat, 15-Apr-17 21:01:22 GMT BLAH", true, 1492290082},
340 {"Sat, 15-Apr-17 21:01:22 GMT-0400", true, 1492290082},
341 {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", true, 1492290082},
342 {"Sat, 15-Apr-17 21:01:22 DST", true, 1492290082},
343 {"Sat, 15-Apr-17 21:01:22 -0400", true, 1492290082},
344 {"Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082},
345 // Test that if we encounter multiple : fields, that we take the first
346 // that correctly parses.
347 {"Sat, 15-Apr-17 21:01:22 11:22:33", true, 1492290082},
348 {"Sat, 15-Apr-17 ::00 21:01:22", true, 1492290082},
349 {"Sat, 15-Apr-17 boink:z 21:01:22", true, 1492290082},
350 // We take the first, which in this case is invalid.
351 {"Sat, 15-Apr-17 91:22:33 21:01:22", false, 0},
352 // amazon.com formats their cookie expiration like this.
353 {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
354 // Test that hh:mm:ss can occur anywhere.
355 {"22:50:12 Thu Apr 18 2007 GMT", true, 1176936612},
356 {"Thu 22:50:12 Apr 18 2007 GMT", true, 1176936612},
357 {"Thu Apr 22:50:12 18 2007 GMT", true, 1176936612},
358 {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
359 {"Thu Apr 18 2007 22:50:12 GMT", true, 1176936612},
360 {"Thu Apr 18 2007 GMT 22:50:12", true, 1176936612},
361 // Test that the day and year can be anywhere if they are unambigious.
362 {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
363 {"15-Sat, Apr-17 21:01:22 GMT", true, 1492290082},
364 {"15-Sat, Apr 21:01:22 GMT 17", true, 1492290082},
365 {"15-Sat, Apr 21:01:22 GMT 2017", true, 1492290082},
366 {"15 Apr 21:01:22 2017", true, 1492290082},
367 {"15 17 Apr 21:01:22", true, 1492290082},
368 {"Apr 15 17 21:01:22", true, 1492290082},
369 {"Apr 15 21:01:22 17", true, 1492290082},
370 {"2017 April 15 21:01:22", true, 1492290082},
371 {"15 April 2017 21:01:22", true, 1492290082},
372 // Test two-digit abbreviated year numbers.
373 {"1-Jan-71 00:00:00 GMT" /* 1971 */, true, 31536000},
374 {"1-Jan-70 00:00:00 GMT" /* 1970 */, true, 0},
375 {"1-Jan-69 00:00:00 GMT" /* 2069 */, true, 3124224000},
376 {"1-Jan-68 00:00:00 GMT" /* 2068 */, true, 3092601600},
377 // Some invalid dates
378 {"98 April 17 21:01:22", false, 0},
379 {"Thu, 012-Aug-2008 20:49:07 GMT", false, 0},
380 {"Thu, 12-Aug-9999999999 20:49:07 GMT", false, 0},
381 {"Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0},
382 {"Thu, 12-Aug-2007 20:61:99999999999 GMT", false, 0},
383 {"IAintNoDateFool", false, 0},
384 {"1600 April 33 21:01:22", false, 0},
385 {"1970 April 33 21:01:22", false, 0},
386 {"Thu, 33-Aug-31841 20:49:07 GMT", false, 0},
387 };
388
389 base::Time parsed_time;
390 for (const auto& test : tests) {
391 parsed_time = cookie_util::ParseCookieExpirationTime(test.str);
392 if (!test.valid) {
393 EXPECT_TRUE(parsed_time.is_null()) << test.str;
394 continue;
395 }
396 EXPECT_TRUE(!parsed_time.is_null()) << test.str;
397 EXPECT_EQ(test.epoch, parsed_time.InSecondsFSinceUnixEpoch()) << test.str;
398 }
399 }
400
401 // Tests parsing dates that are beyond 2038. 32-bit (non-Mac) POSIX systems are
402 // incapable of doing this, however the expectation is for cookie parsing to
403 // succeed anyway (and return the minimum value Time::FromUTCExploded() can
404 // parse on the current platform). Also checks a date outside the limit on
405 // Windows, which is year 30827.
TEST(CookieUtilTest,ParseCookieExpirationTimeBeyond2038)406 TEST(CookieUtilTest, ParseCookieExpirationTimeBeyond2038) {
407 const char* kTests[] = {
408 "Thu, 12-Aug-31841 20:49:07 GMT", "2039 April 15 21:01:22",
409 "2039 April 15 21:01:22", "2038 April 15 21:01:22",
410 "15 April 69 21:01:22", "15 April 68, 21:01:22",
411 };
412
413 for (auto* test : kTests) {
414 base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
415 EXPECT_FALSE(parsed_time.is_null());
416
417 // It should either have an exact value, or be base::Time::Max(). For
418 // simplicity just check that it is greater than an arbitray date.
419 base::Time almost_jan_2038 = base::Time::UnixEpoch() + base::Days(365 * 68);
420 EXPECT_LT(almost_jan_2038, parsed_time);
421 }
422 }
423
424 // Tests parsing dates that are prior to (or around) 1970. Non-Mac POSIX systems
425 // are incapable of doing this, however the expectation is for cookie parsing to
426 // succeed anyway (and return a minimal base::Time).
TEST(CookieUtilTest,ParseCookieExpirationTimeBefore1970)427 TEST(CookieUtilTest, ParseCookieExpirationTimeBefore1970) {
428 const char* kTests[] = {
429 // Times around the Unix epoch.
430 "1970 Jan 1 00:00:00",
431 "1969 March 3 21:01:22",
432 // Two digit year abbreviations.
433 "1-Jan-70 00:00:00",
434 "Jan 1, 70 00:00:00",
435 // Times around the Windows epoch.
436 "1601 Jan 1 00:00:00",
437 "1600 April 15 21:01:22",
438 // Times around kExplodedMinYear on Mac.
439 "1902 Jan 1 00:00:00",
440 "1901 Jan 1 00:00:00",
441 };
442
443 for (auto* test : kTests) {
444 base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
445 EXPECT_FALSE(parsed_time.is_null()) << test;
446
447 // It should either have an exact value, or should be base::Time(1)
448 // For simplicity just check that it is less than the unix epoch.
449 EXPECT_LE(parsed_time, base::Time::UnixEpoch()) << test;
450 }
451 }
452
TEST(CookieUtilTest,TestRequestCookieParsing)453 TEST(CookieUtilTest, TestRequestCookieParsing) {
454 std::vector<RequestCookieParsingTest> tests;
455
456 // Simple case.
457 tests.emplace_back();
458 tests.back().str = "key=value";
459 tests.back().parsed.emplace_back(std::string("key"), std::string("value"));
460 // Multiple key/value pairs.
461 tests.emplace_back();
462 tests.back().str = "key1=value1; key2=value2";
463 tests.back().parsed.emplace_back(std::string("key1"), std::string("value1"));
464 tests.back().parsed.emplace_back(std::string("key2"), std::string("value2"));
465 // Empty value.
466 tests.emplace_back();
467 tests.back().str = "key=; otherkey=1234";
468 tests.back().parsed.emplace_back(std::string("key"), std::string());
469 tests.back().parsed.emplace_back(std::string("otherkey"),
470 std::string("1234"));
471 // Special characters (including equals signs) in value.
472 tests.emplace_back();
473 tests.back().str = "key=; a2=s=(./&t=:&u=a#$; a3=+~";
474 tests.back().parsed.emplace_back(std::string("key"), std::string());
475 tests.back().parsed.emplace_back(std::string("a2"),
476 std::string("s=(./&t=:&u=a#$"));
477 tests.back().parsed.emplace_back(std::string("a3"), std::string("+~"));
478 // Quoted value.
479 tests.emplace_back();
480 tests.back().str = "key=\"abcdef\"; otherkey=1234";
481 tests.back().parsed.emplace_back(std::string("key"),
482 std::string("\"abcdef\""));
483 tests.back().parsed.emplace_back(std::string("otherkey"),
484 std::string("1234"));
485
486 for (size_t i = 0; i < tests.size(); i++) {
487 SCOPED_TRACE(testing::Message() << "Test " << i);
488 CheckParse(tests[i].str, tests[i].parsed);
489 CheckSerialize(tests[i].parsed, tests[i].str);
490 }
491 }
492
TEST(CookieUtilTest,TestRequestCookieParsing_Malformed)493 TEST(CookieUtilTest, TestRequestCookieParsing_Malformed) {
494 std::vector<RequestCookieParsingTest> tests;
495
496 // Missing equal sign.
497 tests.emplace_back();
498 tests.back().str = "key";
499 tests.back().parsed.emplace_back(std::string("key"), std::string());
500 tests.back().serialized = "key=";
501
502 // Quoted value with unclosed quote.
503 tests.emplace_back();
504 tests.back().str = "key=\"abcdef";
505
506 // Quoted value with unclosed quote followed by regular value.
507 tests.emplace_back();
508 tests.back().str = "key=\"abcdef; otherkey=1234";
509
510 // Quoted value with unclosed quote followed by another quoted value.
511 tests.emplace_back();
512 tests.back().str = "key=\"abcdef; otherkey=\"1234\"";
513 tests.back().parsed.emplace_back(std::string("key"),
514 std::string("\"abcdef; otherkey=\""));
515 tests.back().parsed.emplace_back(std::string("234\""), std::string());
516 tests.back().serialized = "key=\"abcdef; otherkey=\"; 234\"=";
517
518 // Regular value followed by quoted value with unclosed quote.
519 tests.emplace_back();
520 tests.back().str = "key=abcdef; otherkey=\"1234";
521 tests.back().parsed.emplace_back(std::string("key"), std::string("abcdef"));
522 tests.back().serialized = "key=abcdef";
523
524 for (size_t i = 0; i < tests.size(); i++) {
525 SCOPED_TRACE(testing::Message() << "Test " << i);
526 CheckParse(tests[i].str, tests[i].parsed);
527 CheckSerialize(tests[i].parsed, tests[i].serialized);
528 }
529 }
530
TEST(CookieUtilTest,CookieDomainAndPathToURL)531 TEST(CookieUtilTest, CookieDomainAndPathToURL) {
532 struct {
533 std::string domain;
534 std::string path;
535 bool is_https;
536 std::string expected_url;
537 } kTests[]{
538 {"a.com", "/", true, "https://a.com/"},
539 {"a.com", "/", false, "http://a.com/"},
540 {".a.com", "/", true, "https://a.com/"},
541 {".a.com", "/", false, "http://a.com/"},
542 {"b.a.com", "/", true, "https://b.a.com/"},
543 {"b.a.com", "/", false, "http://b.a.com/"},
544 {"a.com", "/example/path", true, "https://a.com/example/path"},
545 {".a.com", "/example/path", false, "http://a.com/example/path"},
546 {"b.a.com", "/example/path", true, "https://b.a.com/example/path"},
547 {".b.a.com", "/example/path", false, "http://b.a.com/example/path"},
548 };
549
550 for (auto& test : kTests) {
551 GURL url1 = cookie_util::CookieDomainAndPathToURL(test.domain, test.path,
552 test.is_https);
553 GURL url2 = cookie_util::CookieDomainAndPathToURL(
554 test.domain, test.path, std::string(test.is_https ? "https" : "http"));
555 // Test both overloads for equality.
556 EXPECT_EQ(url1, url2);
557 EXPECT_EQ(url1, GURL(test.expected_url));
558 }
559 }
560
TEST(CookieUtilTest,SimulatedCookieSource)561 TEST(CookieUtilTest, SimulatedCookieSource) {
562 GURL secure_url("https://b.a.com");
563 GURL insecure_url("http://b.a.com");
564
565 struct {
566 std::string cookie;
567 std::string source_scheme;
568 std::string expected_simulated_source;
569 } kTests[]{
570 {"cookie=foo", "http", "http://b.a.com/"},
571 {"cookie=foo", "https", "https://b.a.com/"},
572 {"cookie=foo", "wss", "wss://b.a.com/"},
573 {"cookie=foo", "file", "file://b.a.com/"},
574 {"cookie=foo; Domain=b.a.com", "https", "https://b.a.com/"},
575 {"cookie=foo; Domain=a.com", "https", "https://a.com/"},
576 {"cookie=foo; Domain=.b.a.com", "https", "https://b.a.com/"},
577 {"cookie=foo; Domain=.a.com", "https", "https://a.com/"},
578 {"cookie=foo; Path=/", "https", "https://b.a.com/"},
579 {"cookie=foo; Path=/bar", "https", "https://b.a.com/bar"},
580 {"cookie=foo; Domain=b.a.com; Path=/", "https", "https://b.a.com/"},
581 {"cookie=foo; Domain=b.a.com; Path=/bar", "https", "https://b.a.com/bar"},
582 {"cookie=foo; Domain=a.com; Path=/", "https", "https://a.com/"},
583 {"cookie=foo; Domain=a.com; Path=/bar", "https", "https://a.com/bar"},
584 };
585
586 for (const auto& test : kTests) {
587 std::vector<std::unique_ptr<CanonicalCookie>> cookies;
588 // It shouldn't depend on the cookie's secureness or actual source scheme.
589 cookies.push_back(CanonicalCookie::CreateForTesting(
590 insecure_url, test.cookie, base::Time::Now()));
591 cookies.push_back(CanonicalCookie::CreateForTesting(secure_url, test.cookie,
592 base::Time::Now()));
593 cookies.push_back(CanonicalCookie::CreateForTesting(
594 secure_url, test.cookie + "; Secure", base::Time::Now()));
595 for (const auto& cookie : cookies) {
596 GURL simulated_source =
597 cookie_util::SimulatedCookieSource(*cookie, test.source_scheme);
598 EXPECT_EQ(GURL(test.expected_simulated_source), simulated_source);
599 }
600 }
601 }
602
TEST(CookieUtilTest,TestGetEffectiveDomain)603 TEST(CookieUtilTest, TestGetEffectiveDomain) {
604 // Note: registry_controlled_domains::GetDomainAndRegistry is tested in its
605 // own unittests.
606 EXPECT_EQ("example.com",
607 cookie_util::GetEffectiveDomain("http", "www.example.com"));
608 EXPECT_EQ("example.com",
609 cookie_util::GetEffectiveDomain("https", "www.example.com"));
610 EXPECT_EQ("example.com",
611 cookie_util::GetEffectiveDomain("ws", "www.example.com"));
612 EXPECT_EQ("example.com",
613 cookie_util::GetEffectiveDomain("wss", "www.example.com"));
614 EXPECT_EQ("www.example.com",
615 cookie_util::GetEffectiveDomain("ftp", "www.example.com"));
616 }
617
TEST(CookieUtilTest,TestIsDomainMatch)618 TEST(CookieUtilTest, TestIsDomainMatch) {
619 EXPECT_TRUE(cookie_util::IsDomainMatch("example.com", "example.com"));
620 EXPECT_FALSE(cookie_util::IsDomainMatch("www.example.com", "example.com"));
621
622 EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "example.com"));
623 EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "www.example.com"));
624 EXPECT_FALSE(cookie_util::IsDomainMatch(".www.example.com", "example.com"));
625
626 EXPECT_FALSE(cookie_util::IsDomainMatch("example.com", "example.de"));
627 EXPECT_FALSE(cookie_util::IsDomainMatch(".example.com", "example.de"));
628 EXPECT_FALSE(cookie_util::IsDomainMatch(".example.de", "example.de.vu"));
629 }
630
TEST(CookieUtilTest,TestIsOnPath)631 TEST(CookieUtilTest, TestIsOnPath) {
632 EXPECT_TRUE(cookie_util::IsOnPath("/", "/"));
633 EXPECT_TRUE(cookie_util::IsOnPath("/", "/test"));
634 EXPECT_TRUE(cookie_util::IsOnPath("/", "/test/bar.html"));
635
636 // Test the empty string edge case.
637 EXPECT_FALSE(cookie_util::IsOnPath("/", std::string()));
638
639 EXPECT_FALSE(cookie_util::IsOnPath("/test", "/"));
640
641 EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test"));
642 EXPECT_FALSE(cookie_util::IsOnPath("/test", "/testtest/"));
643
644 EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test/bar.html"));
645 EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test/sample/bar.html"));
646 }
647
TEST(CookieUtilTest,TestIsOnPathCaseSensitive)648 TEST(CookieUtilTest, TestIsOnPathCaseSensitive) {
649 EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test"));
650 EXPECT_FALSE(cookie_util::IsOnPath("/test", "/TEST"));
651 EXPECT_FALSE(cookie_util::IsOnPath("/TEST", "/test"));
652 }
653
654 using ::testing::AllOf;
655 using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
656 using ContextType = CookieOptions::SameSiteCookieContext::ContextType;
657 using ContextRedirectTypeBug1221316 = CookieOptions::SameSiteCookieContext::
658 ContextMetadata::ContextRedirectTypeBug1221316;
659 using HttpMethod =
660 CookieOptions::SameSiteCookieContext::ContextMetadata::HttpMethod;
661
662 MATCHER_P2(ContextTypeIsWithSchemefulMode, context_type, schemeful, "") {
663 return context_type == (schemeful ? arg.schemeful_context() : arg.context());
664 }
665
666 // Checks for the expected metadata related to context downgrades from
667 // cross-site redirects.
668 MATCHER_P5(CrossSiteRedirectMetadataCorrectWithSchemefulMode,
669 method,
670 context_type_without_chain,
671 context_type_with_chain,
672 redirect_type_with_chain,
673 schemeful,
674 "") {
675 using ContextDowngradeType = CookieOptions::SameSiteCookieContext::
676 ContextMetadata::ContextDowngradeType;
677
678 const auto& metadata = schemeful ? arg.schemeful_metadata() : arg.metadata();
679
680 if (metadata.redirect_type_bug_1221316 != redirect_type_with_chain)
681 return false;
682
683 // http_method_bug_1221316 is only set when there is a context downgrade.
684 if (metadata.cross_site_redirect_downgrade !=
685 ContextDowngradeType::kNoDowngrade &&
686 metadata.http_method_bug_1221316 != method) {
687 return false;
688 }
689
690 switch (metadata.cross_site_redirect_downgrade) {
691 case ContextDowngradeType::kNoDowngrade:
692 return context_type_without_chain == context_type_with_chain;
693 case ContextDowngradeType::kStrictToLax:
694 return context_type_without_chain == ContextType::SAME_SITE_STRICT &&
695 (context_type_with_chain == ContextType::SAME_SITE_LAX ||
696 context_type_with_chain ==
697 ContextType::SAME_SITE_LAX_METHOD_UNSAFE);
698 case ContextDowngradeType::kStrictToCross:
699 return context_type_without_chain == ContextType::SAME_SITE_STRICT &&
700 context_type_with_chain == ContextType::CROSS_SITE;
701 case ContextDowngradeType::kLaxToCross:
702 return (context_type_without_chain == ContextType::SAME_SITE_LAX ||
703 context_type_without_chain ==
704 ContextType::SAME_SITE_LAX_METHOD_UNSAFE) &&
705 context_type_with_chain == ContextType::CROSS_SITE;
706 }
707 }
708
UrlChainToString(const std::vector<GURL> & url_chain)709 std::string UrlChainToString(const std::vector<GURL>& url_chain) {
710 std::string s;
711 for (const GURL& url : url_chain) {
712 base::StrAppend(&s, {" ", url.spec()});
713 }
714 return s;
715 }
716
717 // Tests for the various ComputeSameSiteContextFor*() functions. The first
718 // boolean test param is whether the results of the computations are evaluated
719 // schemefully. The second boolean param is whether SameSite considers redirect
720 // chains.
721 class CookieUtilComputeSameSiteContextTest
722 : public ::testing::TestWithParam<std::tuple<bool, bool>> {
723 public:
CookieUtilComputeSameSiteContextTest()724 CookieUtilComputeSameSiteContextTest() {
725 if (DoesSameSiteConsiderRedirectChain()) {
726 feature_list_.InitAndEnableFeature(
727 features::kCookieSameSiteConsidersRedirectChain);
728 } else {
729 // No need to explicitly disable the redirect chain feature because it
730 // is disabled by default.
731 feature_list_.Init();
732 }
733 }
734 ~CookieUtilComputeSameSiteContextTest() override = default;
735
IsSchemeful() const736 bool IsSchemeful() const { return std::get<0>(GetParam()); }
737
DoesSameSiteConsiderRedirectChain() const738 bool DoesSameSiteConsiderRedirectChain() const {
739 return std::get<1>(GetParam());
740 }
741
742 // Returns the proper gtest matcher to use for the schemeless/schemeful mode.
ContextTypeIs(ContextType context_type) const743 auto ContextTypeIs(ContextType context_type) const {
744 return ContextTypeIsWithSchemefulMode(context_type, IsSchemeful());
745 }
746
CrossSiteRedirectMetadataCorrect(HttpMethod method,ContextType context_type_without_chain,ContextType context_type_with_chain,ContextRedirectTypeBug1221316 redirect_type_with_chain) const747 auto CrossSiteRedirectMetadataCorrect(
748 HttpMethod method,
749 ContextType context_type_without_chain,
750 ContextType context_type_with_chain,
751 ContextRedirectTypeBug1221316 redirect_type_with_chain) const {
752 return CrossSiteRedirectMetadataCorrectWithSchemefulMode(
753 method, context_type_without_chain, context_type_with_chain,
754 redirect_type_with_chain, IsSchemeful());
755 }
756
757 // The following methods return the sets of URLs/SiteForCookies/initiators/URL
758 // chains that are same-site or cross-site with respect to kSiteUrl.
759
GetAllUrls() const760 std::vector<GURL> GetAllUrls() const {
761 return {kSiteUrl,
762 kSiteUrlWithPath,
763 kSecureSiteUrl,
764 kCrossSiteUrl,
765 kSecureCrossSiteUrl,
766 kSubdomainUrl,
767 kSecureSubdomainUrl,
768 kWsUrl,
769 kWssUrl};
770 }
771
GetSameSiteUrls() const772 std::vector<GURL> GetSameSiteUrls() const {
773 // Same-site-same-scheme URLs are always same-site. (ws counts as
774 // same-scheme with http.)
775 std::vector<GURL> same_site_urls{kSiteUrl, kSiteUrlWithPath, kSubdomainUrl,
776 kWsUrl};
777 // If schemeless, the cross-scheme URLs are also same-site.
778 if (!IsSchemeful()) {
779 same_site_urls.push_back(kSecureSiteUrl);
780 same_site_urls.push_back(kSecureSubdomainUrl);
781 same_site_urls.push_back(kWssUrl);
782 }
783 return same_site_urls;
784 }
785
GetCrossSiteUrls() const786 std::vector<GURL> GetCrossSiteUrls() const {
787 std::vector<GURL> cross_site_urls;
788 std::vector<GURL> same_site_urls = GetSameSiteUrls();
789 for (const GURL& url : GetAllUrls()) {
790 if (!base::Contains(same_site_urls, url))
791 cross_site_urls.push_back(url);
792 }
793 return cross_site_urls;
794 }
795
GetAllSitesForCookies() const796 std::vector<SiteForCookies> GetAllSitesForCookies() const {
797 return {kNullSiteForCookies, kSiteForCookies, kSecureSiteForCookies,
798 kCrossSiteForCookies, kSecureCrossSiteForCookies};
799 }
800
GetSameSiteSitesForCookies() const801 std::vector<SiteForCookies> GetSameSiteSitesForCookies() const {
802 std::vector<SiteForCookies> same_site_sfc = {kSiteForCookies};
803 // If schemeless, the cross-scheme SFC is also same-site.
804 if (!IsSchemeful())
805 same_site_sfc.push_back(kSecureSiteForCookies);
806 return same_site_sfc;
807 }
808
GetCrossSiteSitesForCookies() const809 std::vector<SiteForCookies> GetCrossSiteSitesForCookies() const {
810 std::vector<SiteForCookies> cross_site_sfc;
811 std::vector<SiteForCookies> same_site_sfc = GetSameSiteSitesForCookies();
812 for (const SiteForCookies& sfc : GetAllSitesForCookies()) {
813 if (!base::Contains(same_site_sfc, sfc.RepresentativeUrl(),
814 &SiteForCookies::RepresentativeUrl)) {
815 cross_site_sfc.push_back(sfc);
816 }
817 }
818 return cross_site_sfc;
819 }
820
GetAllInitiators() const821 std::vector<std::optional<url::Origin>> GetAllInitiators() const {
822 return {kBrowserInitiated, kOpaqueInitiator,
823 kSiteInitiator, kSecureSiteInitiator,
824 kCrossSiteInitiator, kSecureCrossSiteInitiator,
825 kSubdomainInitiator, kSecureSubdomainInitiator,
826 kUnrelatedInitiator};
827 }
828
GetSameSiteInitiators() const829 std::vector<std::optional<url::Origin>> GetSameSiteInitiators() const {
830 std::vector<std::optional<url::Origin>> same_site_initiators{
831 kBrowserInitiated, kSiteInitiator, kSubdomainInitiator};
832 // If schemeless, the cross-scheme origins are also same-site.
833 if (!IsSchemeful()) {
834 same_site_initiators.push_back(kSecureSiteInitiator);
835 same_site_initiators.push_back(kSecureSubdomainInitiator);
836 }
837 return same_site_initiators;
838 }
839
GetCrossSiteInitiators() const840 std::vector<std::optional<url::Origin>> GetCrossSiteInitiators() const {
841 std::vector<std::optional<url::Origin>> cross_site_initiators;
842 std::vector<std::optional<url::Origin>> same_site_initiators =
843 GetSameSiteInitiators();
844 for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
845 if (!base::Contains(same_site_initiators, initiator))
846 cross_site_initiators.push_back(initiator);
847 }
848 return cross_site_initiators;
849 }
850
851 // Returns an assortment of redirect chains that end in `url` as the
852 // current request URL, and are completely same-site. `url` is expected to be
853 // same-site to kSiteUrl.
GetSameSiteUrlChains(const GURL & url) const854 std::vector<std::vector<GURL>> GetSameSiteUrlChains(const GURL& url) const {
855 std::vector<std::vector<GURL>> same_site_url_chains;
856 for (const GURL& same_site_url : GetSameSiteUrls()) {
857 same_site_url_chains.push_back({same_site_url, url});
858 for (const GURL& other_same_site_url : GetSameSiteUrls()) {
859 same_site_url_chains.push_back(
860 {other_same_site_url, same_site_url, url});
861 }
862 }
863 return same_site_url_chains;
864 }
865
866 // Returns an assortment of redirect chains that end in `url` as the
867 // current request URL, and are cross-site. `url` is expected to be same-site
868 // to kSiteUrl.
GetCrossSiteUrlChains(const GURL & url) const869 std::vector<std::vector<GURL>> GetCrossSiteUrlChains(const GURL& url) const {
870 std::vector<std::vector<GURL>> cross_site_url_chains;
871 for (const GURL& cross_site_url : GetCrossSiteUrls()) {
872 cross_site_url_chains.push_back({cross_site_url, url});
873 for (const GURL& same_site_url : GetSameSiteUrls()) {
874 cross_site_url_chains.push_back({cross_site_url, same_site_url, url});
875 cross_site_url_chains.push_back({same_site_url, cross_site_url, url});
876 }
877 }
878 return cross_site_url_chains;
879 }
880
881 // Computes possible values of is_main_frame_navigation that are consistent
882 // with the DCHECKs.
CanBeMainFrameNavigation(const GURL & url,const SiteForCookies & site_for_cookies) const883 bool CanBeMainFrameNavigation(const GURL& url,
884 const SiteForCookies& site_for_cookies) const {
885 return (site_for_cookies.IsNull() ||
886 site_for_cookies.IsFirstPartyWithSchemefulMode(url, true)) &&
887 !url.SchemeIsWSOrWSS();
888 }
889
IsMainFrameNavigationPossibleValues(const GURL & url,const SiteForCookies & site_for_cookies) const890 std::vector<bool> IsMainFrameNavigationPossibleValues(
891 const GURL& url,
892 const SiteForCookies& site_for_cookies) const {
893 return CanBeMainFrameNavigation(url, site_for_cookies)
894 ? std::vector<bool>{false, true}
895 : std::vector<bool>{false};
896 }
897
898 // Request URL.
899 const GURL kSiteUrl{"http://example.test/"};
900 const GURL kSiteUrlWithPath{"http://example.test/path"};
901 const GURL kSecureSiteUrl{"https://example.test/"};
902 const GURL kCrossSiteUrl{"http://notexample.test/"};
903 const GURL kSecureCrossSiteUrl{"https://notexample.test/"};
904 const GURL kSubdomainUrl{"http://subdomain.example.test/"};
905 const GURL kSecureSubdomainUrl{"https://subdomain.example.test/"};
906 const GURL kWsUrl{"ws://example.test/"};
907 const GURL kWssUrl{"wss://example.test/"};
908 // Site for cookies.
909 const SiteForCookies kNullSiteForCookies;
910 const SiteForCookies kSiteForCookies = SiteForCookies::FromUrl(kSiteUrl);
911 const SiteForCookies kSecureSiteForCookies =
912 SiteForCookies::FromUrl(kSecureSiteUrl);
913 const SiteForCookies kCrossSiteForCookies =
914 SiteForCookies::FromUrl(kCrossSiteUrl);
915 const SiteForCookies kSecureCrossSiteForCookies =
916 SiteForCookies::FromUrl(kSecureCrossSiteUrl);
917 // Initiator origin.
918 const std::optional<url::Origin> kBrowserInitiated = std::nullopt;
919 const std::optional<url::Origin> kOpaqueInitiator =
920 std::make_optional(url::Origin());
921 const std::optional<url::Origin> kSiteInitiator =
922 std::make_optional(url::Origin::Create(kSiteUrl));
923 const std::optional<url::Origin> kSecureSiteInitiator =
924 std::make_optional(url::Origin::Create(kSecureSiteUrl));
925 const std::optional<url::Origin> kCrossSiteInitiator =
926 std::make_optional(url::Origin::Create(kCrossSiteUrl));
927 const std::optional<url::Origin> kSecureCrossSiteInitiator =
928 std::make_optional(url::Origin::Create(kSecureCrossSiteUrl));
929 const std::optional<url::Origin> kSubdomainInitiator =
930 std::make_optional(url::Origin::Create(kSubdomainUrl));
931 const std::optional<url::Origin> kSecureSubdomainInitiator =
932 std::make_optional(url::Origin::Create(kSecureSubdomainUrl));
933 const std::optional<url::Origin> kUnrelatedInitiator =
934 std::make_optional(url::Origin::Create(GURL("https://unrelated.test/")));
935
936 protected:
937 base::test::ScopedFeatureList feature_list_;
938 };
939
TEST_P(CookieUtilComputeSameSiteContextTest,UrlAndSiteForCookiesCrossSite)940 TEST_P(CookieUtilComputeSameSiteContextTest, UrlAndSiteForCookiesCrossSite) {
941 // If the SiteForCookies and URL are cross-site, then the context is always
942 // cross-site.
943 for (const GURL& url : GetSameSiteUrls()) {
944 for (const SiteForCookies& site_for_cookies :
945 GetCrossSiteSitesForCookies()) {
946 for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
947 for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
948 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
949 url, site_for_cookies, initiator,
950 false /* force_ignore_site_for_cookies */),
951 ContextTypeIs(ContextType::CROSS_SITE));
952 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
953 url, site_for_cookies,
954 false /* force_ignore_site_for_cookies */),
955 ContextTypeIs(ContextType::CROSS_SITE));
956 for (bool is_main_frame_navigation :
957 IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
958 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
959 method, {url}, site_for_cookies, initiator,
960 is_main_frame_navigation,
961 false /* force_ignore_site_for_cookies */),
962 ContextTypeIs(ContextType::CROSS_SITE));
963 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
964 {url}, site_for_cookies, initiator,
965 is_main_frame_navigation,
966 false /* force_ignore_site_for_cookies */),
967 ContextTypeIs(ContextType::CROSS_SITE));
968 // If the current request URL is cross-site to the site-for-cookies,
969 // the request context is always cross-site even if the URL chain
970 // contains members that are same-site to the site-for-cookies.
971 EXPECT_THAT(
972 cookie_util::ComputeSameSiteContextForRequest(
973 method, {site_for_cookies.RepresentativeUrl(), url},
974 site_for_cookies, initiator, is_main_frame_navigation,
975 false /* force_ignore_site_for_cookies */),
976 ContextTypeIs(ContextType::CROSS_SITE));
977 EXPECT_THAT(
978 cookie_util::ComputeSameSiteContextForResponse(
979 {site_for_cookies.RepresentativeUrl(), url},
980 site_for_cookies, initiator, is_main_frame_navigation,
981 false /* force_ignore_site_for_cookies */),
982 ContextTypeIs(ContextType::CROSS_SITE));
983 }
984 EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
985 url, site_for_cookies,
986 false /* force_ignore_site_for_cookies */),
987 ContextTypeIs(ContextType::CROSS_SITE));
988 }
989 }
990 }
991 }
992 }
993
TEST_P(CookieUtilComputeSameSiteContextTest,SiteForCookiesNotSchemefullySame)994 TEST_P(CookieUtilComputeSameSiteContextTest, SiteForCookiesNotSchemefullySame) {
995 // If the SiteForCookies is not schemefully_same, even if its value is
996 // schemefully same-site, the schemeful context type will be cross-site.
997 if (!IsSchemeful())
998 return;
999
1000 std::vector<SiteForCookies> sites_for_cookies = GetAllSitesForCookies();
1001 for (SiteForCookies& sfc : sites_for_cookies) {
1002 sfc.SetSchemefullySameForTesting(false);
1003 }
1004
1005 for (const GURL& url : GetSameSiteUrls()) {
1006 for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
1007 for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
1008 for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1009 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1010 url, site_for_cookies, initiator,
1011 false /* force_ignore_site_for_cookies */),
1012 ContextTypeIs(ContextType::CROSS_SITE));
1013 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
1014 url, site_for_cookies,
1015 false /* force_ignore_site_for_cookies */),
1016 ContextTypeIs(ContextType::CROSS_SITE));
1017
1018 // If the site-for-cookies isn't schemefully_same, this cannot be a
1019 // main frame navigation.
1020 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1021 method, {url}, site_for_cookies, initiator,
1022 false /* is_main_frame_navigation */,
1023 false /* force_ignore_site_for_cookies */),
1024 ContextTypeIs(ContextType::CROSS_SITE));
1025 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1026 {url}, site_for_cookies, initiator,
1027 false /* is_main_frame_navigation */,
1028 false /* force_ignore_site_for_cookies */),
1029 ContextTypeIs(ContextType::CROSS_SITE));
1030
1031 EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
1032 url, site_for_cookies,
1033 false /* force_ignore_site_for_cookies */),
1034 ContextTypeIs(ContextType::CROSS_SITE));
1035 }
1036 }
1037 }
1038 }
1039 }
1040
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptGet)1041 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet) {
1042 for (const GURL& url : GetSameSiteUrls()) {
1043 // Same-site site-for-cookies.
1044 // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1045 for (const SiteForCookies& site_for_cookies :
1046 GetSameSiteSitesForCookies()) {
1047 // Cross-site initiator -> it's same-site lax.
1048 for (const std::optional<url::Origin>& initiator :
1049 GetCrossSiteInitiators()) {
1050 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1051 url, site_for_cookies, initiator,
1052 false /* force_ignore_site_for_cookies */),
1053 ContextTypeIs(ContextType::SAME_SITE_LAX));
1054 }
1055
1056 // Same-site initiator -> it's same-site strict.
1057 for (const std::optional<url::Origin>& initiator :
1058 GetSameSiteInitiators()) {
1059 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1060 url, site_for_cookies, initiator,
1061 false /* force_ignore_site_for_cookies */),
1062 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1063 }
1064 }
1065 }
1066 }
1067
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptGet_SchemefulDowngrade)1068 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet_SchemefulDowngrade) {
1069 // Some test cases where the context is downgraded when computed schemefully.
1070 // (Should already be covered above, but just to be explicit.)
1071 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1072 ContextType::SAME_SITE_LAX),
1073 cookie_util::ComputeSameSiteContextForScriptGet(
1074 kSiteUrl, kSiteForCookies, kSecureSiteInitiator,
1075 false /* force_ignore_site_for_cookies */));
1076 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1077 ContextType::SAME_SITE_LAX),
1078 cookie_util::ComputeSameSiteContextForScriptGet(
1079 kSecureSiteUrl, kSecureSiteForCookies, kSiteInitiator,
1080 false /* force_ignore_site_for_cookies */));
1081 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1082 ContextType::CROSS_SITE),
1083 cookie_util::ComputeSameSiteContextForScriptGet(
1084 kSecureSiteUrl, kSiteForCookies, kCrossSiteInitiator,
1085 false /* force_ignore_site_for_cookies */));
1086 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1087 ContextType::CROSS_SITE),
1088 cookie_util::ComputeSameSiteContextForScriptGet(
1089 kSiteUrl, kSecureSiteForCookies, kCrossSiteInitiator,
1090 false /* force_ignore_site_for_cookies */));
1091 }
1092
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptGet_WebSocketSchemes)1093 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet_WebSocketSchemes) {
1094 // wss/https and http/ws are considered the same for schemeful purposes.
1095 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1096 kWssUrl, kSecureSiteForCookies, kSecureSiteInitiator,
1097 false /* force_ignore_site_for_cookies */),
1098 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1099 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1100 kWssUrl, kSecureSiteForCookies, kSecureCrossSiteInitiator,
1101 false /* force_ignore_site_for_cookies */),
1102 ContextTypeIs(ContextType::SAME_SITE_LAX));
1103
1104 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1105 kWsUrl, kSiteForCookies, kSiteInitiator,
1106 false /* force_ignore_site_for_cookies */),
1107 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1108 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1109 kWsUrl, kSiteForCookies, kCrossSiteInitiator,
1110 false /* force_ignore_site_for_cookies */),
1111 ContextTypeIs(ContextType::SAME_SITE_LAX));
1112 }
1113
1114 // Test cases where the URL chain has 1 member (i.e. no redirects).
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest)1115 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest) {
1116 for (const GURL& url : GetSameSiteUrls()) {
1117 // Same-site site-for-cookies.
1118 // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1119 for (const SiteForCookies& site_for_cookies :
1120 GetSameSiteSitesForCookies()) {
1121 // Same-Site initiator -> it's same-site strict.
1122 for (const std::optional<url::Origin>& initiator :
1123 GetSameSiteInitiators()) {
1124 for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1125 for (bool is_main_frame_navigation :
1126 IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
1127 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1128 method, {url}, site_for_cookies, initiator,
1129 is_main_frame_navigation,
1130 false /* force_ignore_site_for_cookies */),
1131 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1132 }
1133 }
1134 }
1135
1136 // Cross-Site initiator -> it's same-site lax iff the method is safe.
1137 for (const std::optional<url::Origin>& initiator :
1138 GetCrossSiteInitiators()) {
1139 // For main frame navigations, the context is Lax (or Lax-unsafe).
1140 for (const std::string& method : {"GET", "HEAD"}) {
1141 if (!CanBeMainFrameNavigation(url, site_for_cookies))
1142 break;
1143 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1144 method, {url}, site_for_cookies, initiator,
1145 true /* is_main_frame_navigation */,
1146 false /* force_ignore_site_for_cookies */),
1147 ContextTypeIs(ContextType::SAME_SITE_LAX));
1148 }
1149 for (const std::string& method : {"POST", "PUT"}) {
1150 if (!CanBeMainFrameNavigation(url, site_for_cookies))
1151 break;
1152 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1153 method, {url}, site_for_cookies, initiator,
1154 true /* is_main_frame_navigation */,
1155 false /* force_ignore_site_for_cookies */),
1156 ContextTypeIs(ContextType::SAME_SITE_LAX_METHOD_UNSAFE));
1157 }
1158
1159 // For non-main-frame-navigation requests, the context should be
1160 // cross-site.
1161 for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1162 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1163 method, {url}, site_for_cookies, initiator,
1164 false /* is_main_frame_navigation */,
1165 false /* force_ignore_site_for_cookies */),
1166 ContextTypeIs(ContextType::CROSS_SITE));
1167 }
1168 }
1169 }
1170 }
1171 }
1172
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest_SchemefulDowngrade)1173 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_SchemefulDowngrade) {
1174 // Some test cases where the context is downgraded when computed schemefully.
1175 // (Should already be covered above, but just to be explicit.)
1176
1177 // Cross-scheme URL and site-for-cookies with (schemelessly) same-site
1178 // initiator.
1179 // (The request cannot be a main frame navigation if the site-for-cookies is
1180 // not schemefully same-site).
1181 for (const std::string& method : {"GET", "POST"}) {
1182 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1183 ContextType::CROSS_SITE),
1184 cookie_util::ComputeSameSiteContextForRequest(
1185 method, {kSecureSiteUrl}, kSiteForCookies, kSiteInitiator,
1186 false /* is_main_frame_navigation */,
1187 false /* force_ignore_site_for_cookies */));
1188 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1189 ContextType::CROSS_SITE),
1190 cookie_util::ComputeSameSiteContextForRequest(
1191 method, {kSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1192 false /* is_main_frame_navigation */,
1193 false /* force_ignore_site_for_cookies */));
1194 }
1195
1196 // Schemefully same-site URL and site-for-cookies with cross-scheme
1197 // initiator.
1198 for (bool is_main_frame_navigation : {false, true}) {
1199 ContextType lax_if_main_frame = is_main_frame_navigation
1200 ? ContextType::SAME_SITE_LAX
1201 : ContextType::CROSS_SITE;
1202 ContextType lax_unsafe_if_main_frame =
1203 is_main_frame_navigation ? ContextType::SAME_SITE_LAX_METHOD_UNSAFE
1204 : ContextType::CROSS_SITE;
1205
1206 EXPECT_EQ(
1207 SameSiteCookieContext(ContextType::SAME_SITE_STRICT, lax_if_main_frame),
1208 cookie_util::ComputeSameSiteContextForRequest(
1209 "GET", {kSecureSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1210 is_main_frame_navigation,
1211 false /* force_ignore_site_for_cookies */));
1212 EXPECT_EQ(
1213 SameSiteCookieContext(ContextType::SAME_SITE_STRICT, lax_if_main_frame),
1214 cookie_util::ComputeSameSiteContextForRequest(
1215 "GET", {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1216 is_main_frame_navigation,
1217 false /* force_ignore_site_for_cookies */));
1218 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1219 lax_unsafe_if_main_frame),
1220 cookie_util::ComputeSameSiteContextForRequest(
1221 "POST", {kSecureSiteUrl}, kSecureSiteForCookies,
1222 kSiteInitiator, is_main_frame_navigation,
1223 false /* force_ignore_site_for_cookies */));
1224 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1225 lax_unsafe_if_main_frame),
1226 cookie_util::ComputeSameSiteContextForRequest(
1227 "POST", {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1228 is_main_frame_navigation,
1229 false /* force_ignore_site_for_cookies */));
1230 }
1231
1232 // Cross-scheme URL and site-for-cookies with cross-site initiator.
1233 // (The request cannot be a main frame navigation if the site-for-cookies is
1234 // not schemefully same-site).
1235 EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1236 cookie_util::ComputeSameSiteContextForRequest(
1237 "GET", {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
1238 false /* is_main_frame_navigation */,
1239 false /* force_ignore_site_for_cookies */));
1240 EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1241 cookie_util::ComputeSameSiteContextForRequest(
1242 "GET", {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
1243 false /* is_main_frame_navigation */,
1244 false /* force_ignore_site_for_cookies */));
1245 EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1246 cookie_util::ComputeSameSiteContextForRequest(
1247 "POST", {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
1248 false /* is_main_frame_navigation */,
1249 false /* force_ignore_site_for_cookies */));
1250 EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1251 cookie_util::ComputeSameSiteContextForRequest(
1252 "POST", {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
1253 false /* is_main_frame_navigation */,
1254 false /* force_ignore_site_for_cookies */));
1255 }
1256
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest_WebSocketSchemes)1257 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_WebSocketSchemes) {
1258 // wss/https and http/ws are considered the same for schemeful purposes.
1259 // (ws/wss requests cannot be main frame navigations.)
1260 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1261 "GET", {kWssUrl}, kSecureSiteForCookies, kSecureSiteInitiator,
1262 false /* is_main_frame_navigation */,
1263 false /* force_ignore_site_for_cookies */),
1264 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1265 EXPECT_THAT(
1266 cookie_util::ComputeSameSiteContextForRequest(
1267 "GET", {kWssUrl}, kSecureSiteForCookies, kSecureCrossSiteInitiator,
1268 false /* is_main_frame_navigation */,
1269 false /* force_ignore_site_for_cookies */),
1270 ContextTypeIs(ContextType::CROSS_SITE));
1271
1272 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1273 "GET", {kWsUrl}, kSiteForCookies, kSiteInitiator,
1274 false /* is_main_frame_navigation */,
1275 false /* force_ignore_site_for_cookies */),
1276 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1277 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1278 "GET", {kWsUrl}, kSiteForCookies, kCrossSiteInitiator,
1279 false /* is_main_frame_navigation */,
1280 false /* force_ignore_site_for_cookies */),
1281 ContextTypeIs(ContextType::CROSS_SITE));
1282 }
1283
1284 // Test cases where the URL chain contains multiple members, where the last
1285 // member (current request URL) is same-site to kSiteUrl. (Everything is listed
1286 // as same-site or cross-site relative to kSiteUrl.)
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest_Redirect)1287 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_Redirect) {
1288 struct {
1289 std::string method;
1290 bool url_chain_is_same_site;
1291 bool site_for_cookies_is_same_site;
1292 bool initiator_is_same_site;
1293 // These are the expected context types considering redirect chains:
1294 ContextType expected_context_type; // for non-main-frame-nav requests.
1295 ContextType expected_context_type_for_main_frame_navigation;
1296 // These are the expected context types not considering redirect chains:
1297 ContextType expected_context_type_without_chain;
1298 ContextType expected_context_type_for_main_frame_navigation_without_chain;
1299 // The expected redirect type (only applicable for chains):
1300 ContextRedirectTypeBug1221316 expected_redirect_type_with_chain;
1301 } kTestCases[] = {
1302 // If the url chain is same-site, then the result is the same with or
1303 // without considering the redirect chain.
1304 {"GET", true, true, true, ContextType::SAME_SITE_STRICT,
1305 ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_STRICT,
1306 ContextType::SAME_SITE_STRICT,
1307 ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
1308 {"GET", true, true, false, ContextType::CROSS_SITE,
1309 ContextType::SAME_SITE_LAX, ContextType::CROSS_SITE,
1310 ContextType::SAME_SITE_LAX,
1311 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1312 {"GET", true, false, true, ContextType::CROSS_SITE,
1313 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1314 ContextType::CROSS_SITE,
1315 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1316 {"GET", true, false, false, ContextType::CROSS_SITE,
1317 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1318 ContextType::CROSS_SITE,
1319 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1320 // If the url chain is cross-site, then the result will differ depending
1321 // on whether the redirect chain is considered, when the site-for-cookies
1322 // and initiator are both same-site.
1323 {"GET", false, true, true, ContextType::CROSS_SITE,
1324 ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_STRICT,
1325 ContextType::SAME_SITE_STRICT,
1326 ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
1327 {"GET", false, true, false, ContextType::CROSS_SITE,
1328 ContextType::SAME_SITE_LAX, ContextType::CROSS_SITE,
1329 ContextType::SAME_SITE_LAX,
1330 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1331 {"GET", false, false, true, ContextType::CROSS_SITE,
1332 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1333 ContextType::CROSS_SITE,
1334 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1335 {"GET", false, false, false, ContextType::CROSS_SITE,
1336 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1337 ContextType::CROSS_SITE,
1338 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1339 // If the url chain is same-site, then the result is the same with or
1340 // without considering the redirect chain.
1341 {"POST", true, true, true, ContextType::SAME_SITE_STRICT,
1342 ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_STRICT,
1343 ContextType::SAME_SITE_STRICT,
1344 ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
1345 {"POST", true, true, false, ContextType::CROSS_SITE,
1346 ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::CROSS_SITE,
1347 ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
1348 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1349 {"POST", true, false, true, ContextType::CROSS_SITE,
1350 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1351 ContextType::CROSS_SITE,
1352 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1353 {"POST", true, false, false, ContextType::CROSS_SITE,
1354 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1355 ContextType::CROSS_SITE,
1356 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1357 // If the url chain is cross-site, then the result will differ depending
1358 // on whether the redirect chain is considered, when the site-for-cookies
1359 // and initiator are both same-site.
1360 {"POST", false, true, true, ContextType::CROSS_SITE,
1361 ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::SAME_SITE_STRICT,
1362 ContextType::SAME_SITE_STRICT,
1363 ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
1364 {"POST", false, true, false, ContextType::CROSS_SITE,
1365 ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::CROSS_SITE,
1366 ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
1367 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1368 {"POST", false, false, true, ContextType::CROSS_SITE,
1369 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1370 ContextType::CROSS_SITE,
1371 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1372 {"POST", false, false, false, ContextType::CROSS_SITE,
1373 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1374 ContextType::CROSS_SITE,
1375 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1376 };
1377
1378 for (const auto& test_case : kTestCases) {
1379 std::vector<std::vector<GURL>> url_chains =
1380 test_case.url_chain_is_same_site ? GetSameSiteUrlChains(kSiteUrl)
1381 : GetCrossSiteUrlChains(kSiteUrl);
1382 std::vector<SiteForCookies> sites_for_cookies =
1383 test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
1384 : GetCrossSiteSitesForCookies();
1385 std::vector<std::optional<url::Origin>> initiators =
1386 test_case.initiator_is_same_site ? GetSameSiteInitiators()
1387 : GetCrossSiteInitiators();
1388 ContextType expected_context_type =
1389 DoesSameSiteConsiderRedirectChain()
1390 ? test_case.expected_context_type
1391 : test_case.expected_context_type_without_chain;
1392 ContextType expected_context_type_for_main_frame_navigation =
1393 DoesSameSiteConsiderRedirectChain()
1394 ? test_case.expected_context_type_for_main_frame_navigation
1395 : test_case
1396 .expected_context_type_for_main_frame_navigation_without_chain;
1397 for (const std::vector<GURL>& url_chain : url_chains) {
1398 for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
1399 for (const std::optional<url::Origin>& initiator : initiators) {
1400 EXPECT_THAT(
1401 cookie_util::ComputeSameSiteContextForRequest(
1402 test_case.method, url_chain, site_for_cookies, initiator,
1403 false /* is_main_frame_navigation */,
1404 false /* force_ignore_site_for_cookies */),
1405 AllOf(ContextTypeIs(expected_context_type),
1406 CrossSiteRedirectMetadataCorrect(
1407 cookie_util::HttpMethodStringToEnum(test_case.method),
1408 test_case.expected_context_type_without_chain,
1409 test_case.expected_context_type,
1410 test_case.expected_redirect_type_with_chain)))
1411 << UrlChainToString(url_chain) << " "
1412 << site_for_cookies.ToDebugString() << " "
1413 << (initiator ? initiator->Serialize() : "nullopt");
1414 if (!CanBeMainFrameNavigation(url_chain.back(), site_for_cookies))
1415 continue;
1416 EXPECT_THAT(
1417 cookie_util::ComputeSameSiteContextForRequest(
1418 test_case.method, url_chain, site_for_cookies, initiator,
1419 true /* is_main_frame_navigation */,
1420 false /* force_ignore_site_for_cookies */),
1421 AllOf(
1422 ContextTypeIs(
1423 expected_context_type_for_main_frame_navigation),
1424 CrossSiteRedirectMetadataCorrect(
1425 cookie_util::HttpMethodStringToEnum(test_case.method),
1426 test_case
1427 .expected_context_type_for_main_frame_navigation_without_chain,
1428 test_case.expected_context_type_for_main_frame_navigation,
1429 test_case.expected_redirect_type_with_chain)))
1430 << UrlChainToString(url_chain) << " "
1431 << site_for_cookies.ToDebugString() << " "
1432 << (initiator ? initiator->Serialize() : "nullopt");
1433 }
1434 }
1435 }
1436 }
1437 }
1438
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptSet)1439 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet) {
1440 for (const GURL& url : GetSameSiteUrls()) {
1441 for (const SiteForCookies& site_for_cookies :
1442 GetSameSiteSitesForCookies()) {
1443 // Same-site site-for-cookies -> it's same-site lax.
1444 // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1445 EXPECT_THAT(
1446 cookie_util::ComputeSameSiteContextForScriptSet(
1447 url, site_for_cookies, false /* force_ignore_site_for_cookies */),
1448 ContextTypeIs(ContextType::SAME_SITE_LAX));
1449 }
1450 }
1451 }
1452
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptSet_SchemefulDowngrade)1453 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet_SchemefulDowngrade) {
1454 // Some test cases where the context is downgraded when computed schemefully.
1455 // (Should already be covered above, but just to be explicit.)
1456 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1457 ContextType::CROSS_SITE),
1458 cookie_util::ComputeSameSiteContextForScriptSet(
1459 kSiteUrl, kSecureSiteForCookies,
1460 false /* force_ignore_site_for_cookies */));
1461 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1462 ContextType::CROSS_SITE),
1463 cookie_util::ComputeSameSiteContextForScriptSet(
1464 kSecureSiteUrl, kSiteForCookies,
1465 false /* force_ignore_site_for_cookies */));
1466 }
1467
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptSet_WebSocketSchemes)1468 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet_WebSocketSchemes) {
1469 // wss/https and http/ws are considered the same for schemeful purposes.
1470 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
1471 kWssUrl, kSecureSiteForCookies,
1472 false /* force_ignore_site_for_cookies */),
1473 ContextTypeIs(ContextType::SAME_SITE_LAX));
1474 EXPECT_THAT(
1475 cookie_util::ComputeSameSiteContextForScriptSet(
1476 kWsUrl, kSiteForCookies, false /* force_ignore_site_for_cookies */),
1477 ContextTypeIs(ContextType::SAME_SITE_LAX));
1478 }
1479
1480 // Test cases where the URL chain has 1 member (i.e. no redirects).
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse)1481 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse) {
1482 for (const GURL& url : GetSameSiteUrls()) {
1483 // Same-site site-for-cookies.
1484 // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1485 for (const SiteForCookies& site_for_cookies :
1486 GetSameSiteSitesForCookies()) {
1487 // For main frame navigations, setting all SameSite cookies is allowed
1488 // regardless of initiator.
1489 for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
1490 if (!CanBeMainFrameNavigation(url, site_for_cookies))
1491 break;
1492 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1493 {url}, site_for_cookies, initiator,
1494 true /* is_main_frame_navigation */,
1495 false /* force_ignore_site_for_cookies */),
1496 ContextTypeIs(ContextType::SAME_SITE_LAX));
1497 }
1498
1499 // For non-main-frame-navigation requests, the context should be lax iff
1500 // the initiator is same-site, and cross-site otherwise.
1501 for (const std::optional<url::Origin>& initiator :
1502 GetSameSiteInitiators()) {
1503 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1504 {url}, site_for_cookies, initiator,
1505 false /* is_main_frame_navigation */,
1506 false /* force_ignore_site_for_cookies */),
1507 ContextTypeIs(ContextType::SAME_SITE_LAX));
1508 }
1509 for (const std::optional<url::Origin>& initiator :
1510 GetCrossSiteInitiators()) {
1511 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1512 {url}, site_for_cookies, initiator,
1513 false /* is_main_frame_navigation */,
1514 false /* force_ignore_site_for_cookies */),
1515 ContextTypeIs(ContextType::CROSS_SITE));
1516 }
1517 }
1518 }
1519 }
1520
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse_SchemefulDowngrade)1521 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_SchemefulDowngrade) {
1522 // Some test cases where the context is downgraded when computed schemefully.
1523 // (Should already be covered above, but just to be explicit.)
1524
1525 // URL and site-for-cookies are cross-scheme.
1526 // (If the URL and site-for-cookies are not schemefully same-site, this cannot
1527 // be a main frame navigation.)
1528 // With same-site initiator:
1529 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1530 ContextType::CROSS_SITE),
1531 cookie_util::ComputeSameSiteContextForResponse(
1532 {kSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1533 false /* is_main_frame_navigation */,
1534 false /* force_ignore_site_for_cookies */));
1535 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1536 ContextType::CROSS_SITE),
1537 cookie_util::ComputeSameSiteContextForResponse(
1538 {kSecureSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1539 false /* is_main_frame_navigation */,
1540 false /* force_ignore_site_for_cookies */));
1541 // With cross-site initiator:
1542 EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1543 cookie_util::ComputeSameSiteContextForResponse(
1544 {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
1545 false /* is_main_frame_navigation */,
1546 false /* force_ignore_site_for_cookies */));
1547 EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1548 cookie_util::ComputeSameSiteContextForResponse(
1549 {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
1550 false /* is_main_frame_navigation */,
1551 false /* force_ignore_site_for_cookies */));
1552
1553 // Schemefully same-site URL and site-for-cookies with cross-scheme
1554 // initiator.
1555 for (bool is_main_frame_navigation : {false, true}) {
1556 ContextType lax_if_main_frame = is_main_frame_navigation
1557 ? ContextType::SAME_SITE_LAX
1558 : ContextType::CROSS_SITE;
1559 EXPECT_EQ(
1560 SameSiteCookieContext(ContextType::SAME_SITE_LAX, lax_if_main_frame),
1561 cookie_util::ComputeSameSiteContextForResponse(
1562 {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1563 is_main_frame_navigation,
1564 false /* force_ignore_site_for_cookies */));
1565 EXPECT_EQ(
1566 SameSiteCookieContext(ContextType::SAME_SITE_LAX, lax_if_main_frame),
1567 cookie_util::ComputeSameSiteContextForResponse(
1568 {kSecureSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1569 is_main_frame_navigation,
1570 false /* force_ignore_site_for_cookies */));
1571 }
1572 }
1573
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse_WebSocketSchemes)1574 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_WebSocketSchemes) {
1575 // wss/https and http/ws are considered the same for schemeful purposes.
1576 // (ws/wss requests cannot be main frame navigations.)
1577
1578 // Same-site initiators.
1579 for (const std::optional<url::Origin>& initiator : GetSameSiteInitiators()) {
1580 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1581 {kWsUrl}, kSiteForCookies, initiator,
1582 false /* is_main_frame_navigation */,
1583 false /* force_ignore_site_for_cookies */),
1584 ContextTypeIs(ContextType::SAME_SITE_LAX));
1585 }
1586 // Cross-site initiators.
1587 for (const std::optional<url::Origin>& initiator : GetCrossSiteInitiators()) {
1588 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1589 {kWsUrl}, kSiteForCookies, initiator,
1590 false /* is_main_frame_navigation */,
1591 false /* force_ignore_site_for_cookies */),
1592 ContextTypeIs(ContextType::CROSS_SITE));
1593 }
1594 }
1595
1596 // Test cases where the URL chain contains multiple members, where the last
1597 // member (current request URL) is same-site to kSiteUrl. (Everything is listed
1598 // as same-site or cross-site relative to kSiteUrl.)
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse_Redirect)1599 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_Redirect) {
1600 struct {
1601 bool url_chain_is_same_site;
1602 bool site_for_cookies_is_same_site;
1603 bool initiator_is_same_site;
1604 // These are the expected context types considering redirect chains:
1605 ContextType expected_context_type; // for non-main-frame-nav requests.
1606 ContextType expected_context_type_for_main_frame_navigation;
1607 // These are the expected context types not considering redirect chains:
1608 ContextType expected_context_type_without_chain;
1609 ContextType expected_context_type_for_main_frame_navigation_without_chain;
1610 // The expected redirect type (only applicable for chains):
1611 ContextRedirectTypeBug1221316 expected_redirect_type_with_chain;
1612 } kTestCases[] = {
1613 // If the url chain is same-site, then the result is the same with or
1614 // without considering the redirect chain.
1615 {true, true, true, ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
1616 ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
1617 ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
1618 {true, true, false, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1619 ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1620 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1621 {true, false, true, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1622 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1623 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1624 {true, false, false, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1625 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1626 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1627 // If the url chain is cross-site, then the result will differ depending
1628 // on whether the redirect chain is considered, when the site-for-cookies
1629 // and initiator are both same-site.
1630 {false, true, true, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1631 ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
1632 ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
1633 {false, true, false, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1634 ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1635 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1636 {false, false, true, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1637 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1638 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1639 {false, false, false, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1640 ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1641 ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1642 };
1643 for (const auto& test_case : kTestCases) {
1644 std::vector<std::vector<GURL>> url_chains =
1645 test_case.url_chain_is_same_site ? GetSameSiteUrlChains(kSiteUrl)
1646 : GetCrossSiteUrlChains(kSiteUrl);
1647 std::vector<SiteForCookies> sites_for_cookies =
1648 test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
1649 : GetCrossSiteSitesForCookies();
1650 std::vector<std::optional<url::Origin>> initiators =
1651 test_case.initiator_is_same_site ? GetSameSiteInitiators()
1652 : GetCrossSiteInitiators();
1653 ContextType expected_context_type =
1654 DoesSameSiteConsiderRedirectChain()
1655 ? test_case.expected_context_type
1656 : test_case.expected_context_type_without_chain;
1657 ContextType expected_context_type_for_main_frame_navigation =
1658 DoesSameSiteConsiderRedirectChain()
1659 ? test_case.expected_context_type_for_main_frame_navigation
1660 : test_case
1661 .expected_context_type_for_main_frame_navigation_without_chain;
1662 for (const std::vector<GURL>& url_chain : url_chains) {
1663 for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
1664 for (const std::optional<url::Origin>& initiator : initiators) {
1665 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1666 url_chain, site_for_cookies, initiator,
1667 false /* is_main_frame_navigation */,
1668 false /* force_ignore_site_for_cookies */),
1669 AllOf(ContextTypeIs(expected_context_type),
1670 // The 'method' field is kept empty because it's
1671 // only used to check http_method_bug_1221316 which
1672 // is always empty for responses.
1673 CrossSiteRedirectMetadataCorrect(
1674 HttpMethod::kUnset,
1675 test_case.expected_context_type_without_chain,
1676 test_case.expected_context_type,
1677 test_case.expected_redirect_type_with_chain)))
1678 << UrlChainToString(url_chain) << " "
1679 << site_for_cookies.ToDebugString() << " "
1680 << (initiator ? initiator->Serialize() : "nullopt");
1681 if (!CanBeMainFrameNavigation(url_chain.back(), site_for_cookies))
1682 continue;
1683 EXPECT_THAT(
1684 cookie_util::ComputeSameSiteContextForResponse(
1685 url_chain, site_for_cookies, initiator,
1686 true /* is_main_frame_navigation */,
1687 false /* force_ignore_site_for_cookies */),
1688 AllOf(
1689 ContextTypeIs(
1690 expected_context_type_for_main_frame_navigation),
1691 CrossSiteRedirectMetadataCorrect(
1692 HttpMethod::kUnset,
1693 test_case
1694 .expected_context_type_for_main_frame_navigation_without_chain,
1695 test_case.expected_context_type_for_main_frame_navigation,
1696 test_case.expected_redirect_type_with_chain)))
1697 << UrlChainToString(url_chain) << " "
1698 << site_for_cookies.ToDebugString() << " "
1699 << (initiator ? initiator->Serialize() : "nullopt");
1700 }
1701 }
1702 }
1703 }
1704 }
1705
TEST_P(CookieUtilComputeSameSiteContextTest,ForSubresource)1706 TEST_P(CookieUtilComputeSameSiteContextTest, ForSubresource) {
1707 for (const GURL& url : GetSameSiteUrls()) {
1708 // Same-site site-for-cookies.
1709 // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1710 for (const SiteForCookies& site_for_cookies :
1711 GetSameSiteSitesForCookies()) {
1712 EXPECT_THAT(
1713 cookie_util::ComputeSameSiteContextForSubresource(
1714 url, site_for_cookies, false /* force_ignore_site_for_cookies */),
1715 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1716 }
1717 }
1718 }
1719
TEST_P(CookieUtilComputeSameSiteContextTest,ForSubresource_SchemefulDowngrade)1720 TEST_P(CookieUtilComputeSameSiteContextTest,
1721 ForSubresource_SchemefulDowngrade) {
1722 // Some test cases where the context is downgraded when computed schemefully.
1723 // (Should already be covered above, but just to be explicit.)
1724 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1725 ContextType::CROSS_SITE),
1726 cookie_util::ComputeSameSiteContextForSubresource(
1727 kSiteUrl, kSecureSiteForCookies,
1728 false /* force_ignore_site_for_cookies */));
1729 EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1730 ContextType::CROSS_SITE),
1731 cookie_util::ComputeSameSiteContextForSubresource(
1732 kSecureSiteUrl, kSiteForCookies,
1733 false /* force_ignore_site_for_cookies */));
1734 }
1735
TEST_P(CookieUtilComputeSameSiteContextTest,ForSubresource_WebSocketSchemes)1736 TEST_P(CookieUtilComputeSameSiteContextTest, ForSubresource_WebSocketSchemes) {
1737 // wss/https and http/ws are considered the same for schemeful purposes.
1738 EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
1739 kWssUrl, kSecureSiteForCookies,
1740 false /* force_ignore_site_for_cookies */),
1741 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1742 EXPECT_THAT(
1743 cookie_util::ComputeSameSiteContextForSubresource(
1744 kWsUrl, kSiteForCookies, false /* force_ignore_site_for_cookies */),
1745 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1746 }
1747
TEST_P(CookieUtilComputeSameSiteContextTest,ForceIgnoreSiteForCookies)1748 TEST_P(CookieUtilComputeSameSiteContextTest, ForceIgnoreSiteForCookies) {
1749 // force_ignore_site_for_cookies overrides all checks and returns same-site
1750 // (STRICT for get or LAX for set).
1751 for (const GURL& url : GetAllUrls()) {
1752 for (const SiteForCookies& site_for_cookies : GetAllSitesForCookies()) {
1753 for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
1754 for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1755 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1756 url, site_for_cookies, initiator,
1757 true /* force_ignore_site_for_cookies */),
1758 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1759 EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
1760 url, site_for_cookies,
1761 true /* force_ignore_site_for_cookies */),
1762 ContextTypeIs(ContextType::SAME_SITE_LAX));
1763 for (bool is_main_frame_navigation :
1764 IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
1765 EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1766 method, {url}, site_for_cookies, initiator,
1767 is_main_frame_navigation,
1768 true /* force_ignore_site_for_cookies */),
1769 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1770 EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1771 {url}, site_for_cookies, initiator,
1772 is_main_frame_navigation,
1773 true /* force_ignore_site_for_cookies */),
1774 ContextTypeIs(ContextType::SAME_SITE_LAX));
1775 EXPECT_THAT(
1776 cookie_util::ComputeSameSiteContextForRequest(
1777 method, {site_for_cookies.RepresentativeUrl(), url},
1778 site_for_cookies, initiator, is_main_frame_navigation,
1779 true /* force_ignore_site_for_cookies */),
1780 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1781 EXPECT_THAT(
1782 cookie_util::ComputeSameSiteContextForResponse(
1783 {site_for_cookies.RepresentativeUrl(), url},
1784 site_for_cookies, initiator, is_main_frame_navigation,
1785 true /* force_ignore_site_for_cookies */),
1786 ContextTypeIs(ContextType::SAME_SITE_LAX));
1787 }
1788 EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
1789 url, site_for_cookies,
1790 true /* force_ignore_site_for_cookies */),
1791 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1792 }
1793 }
1794 }
1795 }
1796 }
1797
1798 INSTANTIATE_TEST_SUITE_P(/* no label */,
1799 CookieUtilComputeSameSiteContextTest,
1800 ::testing::Combine(::testing::Bool(),
1801 ::testing::Bool()));
1802
TEST(CookieUtilTest,IsCookieAccessResultInclude)1803 TEST(CookieUtilTest, IsCookieAccessResultInclude) {
1804 EXPECT_FALSE(cookie_util::IsCookieAccessResultInclude(CookieAccessResult(
1805 CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR))));
1806
1807 EXPECT_TRUE(cookie_util::IsCookieAccessResultInclude(CookieAccessResult()));
1808 }
1809
1810 } // namespace
1811
1812 } // namespace net
1813