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