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/canonical_cookie.h"
6
7 #include <memory>
8 #include <string>
9 #include <vector>
10
11 #include "base/test/metrics/histogram_tester.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "base/time/time.h"
14 #include "build/build_config.h"
15 #include "net/base/features.h"
16 #include "net/cookies/canonical_cookie_test_helpers.h"
17 #include "net/cookies/cookie_constants.h"
18 #include "net/cookies/cookie_inclusion_status.h"
19 #include "net/cookies/cookie_options.h"
20 #include "net/cookies/parsed_cookie.h"
21 #include "testing/gmock/include/gmock/gmock-matchers.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/abseil-cpp/absl/types/optional.h"
25 #include "url/gurl.h"
26 #include "url/third_party/mozilla/url_parse.h"
27
28 namespace net {
29
30 namespace {
31 const std::vector<std::string> kCookieableSchemes = {"http", "https", "ws",
32 "wss"};
33
34 // Helper for testing BuildCookieLine
MatchCookieLineToVector(const std::string & line,const std::vector<std::unique_ptr<CanonicalCookie>> & cookies)35 void MatchCookieLineToVector(
36 const std::string& line,
37 const std::vector<std::unique_ptr<CanonicalCookie>>& cookies) {
38 std::vector<CanonicalCookie> list;
39 for (const auto& cookie : cookies)
40 list.push_back(*cookie);
41 EXPECT_EQ(line, CanonicalCookie::BuildCookieLine(list));
42 }
43
44 } // namespace
45
46 using testing::_;
47 using testing::AllOf;
48 using testing::Eq;
49 using testing::Not;
50 using testing::Property;
51
52 // Tests which use this class verify the expiry date clamping behavior when
53 // kClampCookieExpiryTo400Days is enabled. This caps expiry dates on new/updated
54 // cookies to max of 400 days, but does not affect previously stored cookies.
55 class CanonicalCookieWithClampingTest
56 : public testing::Test,
57 public testing::WithParamInterface<bool> {
58 public:
CanonicalCookieWithClampingTest()59 CanonicalCookieWithClampingTest() {
60 scoped_feature_list_.InitWithFeatureState(
61 features::kClampCookieExpiryTo400Days,
62 IsClampCookieExpiryTo400DaysEnabled());
63 }
IsClampCookieExpiryTo400DaysEnabled()64 bool IsClampCookieExpiryTo400DaysEnabled() { return GetParam(); }
65
66 private:
67 base::test::ScopedFeatureList scoped_feature_list_;
68 };
69
70 INSTANTIATE_TEST_SUITE_P(/* no label */,
71 CanonicalCookieWithClampingTest,
72 testing::Bool());
73
TEST(CanonicalCookieTest,Constructor)74 TEST(CanonicalCookieTest, Constructor) {
75 base::Time current_time = base::Time::Now();
76
77 // CreateUnsafeCookieForTesting just forwards to the constructor.
78 auto cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
79 "A", "2", "www.example.com", "/test", current_time, base::Time(),
80 base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
81 COOKIE_PRIORITY_DEFAULT, false, absl::nullopt,
82 CookieSourceScheme::kSecure, 443);
83 EXPECT_EQ("A", cookie1->Name());
84 EXPECT_EQ("2", cookie1->Value());
85 EXPECT_EQ("www.example.com", cookie1->Domain());
86 EXPECT_EQ("/test", cookie1->Path());
87 EXPECT_FALSE(cookie1->IsSecure());
88 EXPECT_FALSE(cookie1->IsHttpOnly());
89 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie1->SameSite());
90 EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie1->Priority());
91 EXPECT_FALSE(cookie1->IsSameParty());
92 EXPECT_FALSE(cookie1->IsPartitioned());
93 EXPECT_EQ(cookie1->SourceScheme(), CookieSourceScheme::kSecure);
94 EXPECT_EQ(cookie1->SourcePort(), 443);
95
96 auto cookie2 = CanonicalCookie::CreateUnsafeCookieForTesting(
97 "A", "2", ".www.example.com", "/", current_time, base::Time(),
98 base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
99 COOKIE_PRIORITY_DEFAULT, true,
100 CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")),
101 CookieSourceScheme::kNonSecure, 65536);
102 EXPECT_EQ("A", cookie2->Name());
103 EXPECT_EQ("2", cookie2->Value());
104 EXPECT_EQ(".www.example.com", cookie2->Domain());
105 EXPECT_EQ("/", cookie2->Path());
106 EXPECT_FALSE(cookie2->IsSecure());
107 EXPECT_FALSE(cookie2->IsHttpOnly());
108 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2->SameSite());
109 EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie2->Priority());
110 EXPECT_TRUE(cookie2->IsSameParty());
111 EXPECT_TRUE(cookie2->IsPartitioned());
112 EXPECT_EQ(cookie2->SourceScheme(), CookieSourceScheme::kNonSecure);
113 // Because the port can be set explicitly in the constructor its value can be
114 // independent of the other parameters. In this case, test that an out of
115 // range port is kept out of range.
116 EXPECT_EQ(cookie2->SourcePort(), 65536);
117
118 // Set Secure to true but don't specify source_scheme or port.
119 auto cookie3 = CanonicalCookie::CreateUnsafeCookieForTesting(
120 "A", "2", ".www.example.com", "/", current_time, base::Time(),
121 base::Time(), base::Time(), true /* secure */, false,
122 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
123 EXPECT_TRUE(cookie3->IsSecure());
124 EXPECT_EQ(cookie3->SourceScheme(), CookieSourceScheme::kUnset);
125 EXPECT_EQ(cookie3->SourcePort(), url::PORT_UNSPECIFIED);
126
127 auto cookie4 = CanonicalCookie::CreateUnsafeCookieForTesting(
128 "A", "2", ".www.example.com", "/test", current_time, base::Time(),
129 base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
130 COOKIE_PRIORITY_DEFAULT, false);
131 EXPECT_EQ("A", cookie4->Name());
132 EXPECT_EQ("2", cookie4->Value());
133 EXPECT_EQ(".www.example.com", cookie4->Domain());
134 EXPECT_EQ("/test", cookie4->Path());
135 EXPECT_FALSE(cookie4->IsSecure());
136 EXPECT_FALSE(cookie4->IsHttpOnly());
137 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie4->SameSite());
138 EXPECT_FALSE(cookie4->IsSameParty());
139 EXPECT_FALSE(cookie4->IsPartitioned());
140 EXPECT_EQ(cookie4->SourceScheme(), CookieSourceScheme::kUnset);
141 EXPECT_EQ(cookie4->SourcePort(), url::PORT_UNSPECIFIED);
142
143 // Test some port edge cases: unspecified.
144 auto cookie5 = CanonicalCookie::CreateUnsafeCookieForTesting(
145 "A", "2", ".www.example.com", "/", current_time, base::Time(),
146 base::Time(), base::Time(), true /* secure */, false,
147 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false,
148 absl::nullopt, CookieSourceScheme::kUnset, url::PORT_UNSPECIFIED);
149 EXPECT_EQ(cookie5->SourcePort(), url::PORT_UNSPECIFIED);
150
151 // Test some port edge cases: invalid.
152 auto cookie6 = CanonicalCookie::CreateUnsafeCookieForTesting(
153 "A", "2", ".www.example.com", "/", current_time, base::Time(),
154 base::Time(), base::Time(), true /* secure */, false,
155 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false,
156 absl::nullopt, CookieSourceScheme::kUnset, url::PORT_INVALID);
157 EXPECT_EQ(cookie6->SourcePort(), url::PORT_INVALID);
158 }
159
TEST(CanonicalCookieTest,CreationCornerCases)160 TEST(CanonicalCookieTest, CreationCornerCases) {
161 base::Time creation_time = base::Time::Now();
162 std::unique_ptr<CanonicalCookie> cookie;
163 absl::optional<base::Time> server_time = absl::nullopt;
164
165 // Space in name.
166 cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
167 "A C=2", creation_time, server_time,
168 absl::nullopt /* cookie_partition_key */);
169 EXPECT_TRUE(cookie.get());
170 EXPECT_EQ("A C", cookie->Name());
171
172 // Semicolon in path.
173 cookie = CanonicalCookie::Create(GURL("http://fool/;/"), "*", creation_time,
174 server_time,
175 absl::nullopt /* cookie_partition_key */);
176 EXPECT_TRUE(cookie.get());
177
178 // Control characters in name or value.
179 CookieInclusionStatus status;
180 cookie = CanonicalCookie::Create(
181 GURL("http://www.example.com/test/foo.html"), "\b=foo", creation_time,
182 server_time, absl::nullopt /* cookie_partition_key */, &status);
183 EXPECT_FALSE(cookie.get());
184 EXPECT_TRUE(status.HasExclusionReason(
185 CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
186 cookie = CanonicalCookie::Create(
187 GURL("http://www.example.com/test/foo.html"), "bar=\b", creation_time,
188 server_time, absl::nullopt /* cookie_partition_key */, &status);
189 EXPECT_FALSE(cookie.get());
190 EXPECT_TRUE(status.HasExclusionReason(
191 CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
192
193 // The ParsedCookie constructor unit tests cover many edge cases related to
194 // invalid sizes when parsing a cookie line, and since CanonicalCookie::Create
195 // creates a ParsedCookie immediately, there's no point in replicating all
196 // of those tests here. We should test that the corresponding ExclusionReason
197 // gets passed back correctly, though.
198 std::string too_long_value(ParsedCookie::kMaxCookieNamePlusValueSize + 1,
199 'a');
200
201 cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
202 too_long_value, creation_time, server_time,
203 absl::nullopt /* cookie_partition_key */,
204 &status);
205 EXPECT_FALSE(cookie.get());
206 EXPECT_TRUE(
207 status.HasExclusionReason(CookieInclusionStatus::ExclusionReason::
208 EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE));
209 }
210
TEST(CanonicalCookieTest,Create)211 TEST(CanonicalCookieTest, Create) {
212 // Test creating cookies from a cookie string.
213 GURL url("http://www.example.com/test/foo.html");
214 GURL https_url("https://www.example.com/test/foo.html");
215 base::Time creation_time = base::Time::Now();
216 absl::optional<base::Time> server_time = absl::nullopt;
217
218 std::unique_ptr<CanonicalCookie> cookie(
219 CanonicalCookie::Create(url, "A=2", creation_time, server_time,
220 absl::nullopt /* cookie_partition_key */));
221 EXPECT_EQ("A", cookie->Name());
222 EXPECT_EQ("2", cookie->Value());
223 EXPECT_EQ("www.example.com", cookie->Domain());
224 EXPECT_EQ("/test", cookie->Path());
225 EXPECT_FALSE(cookie->IsSecure());
226 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
227 EXPECT_EQ(cookie->SourcePort(), 80);
228
229 GURL url2("http://www.foo.com");
230 cookie = CanonicalCookie::Create(url2, "B=1", creation_time, server_time,
231 absl::nullopt /* cookie_partition_key */);
232 EXPECT_EQ("B", cookie->Name());
233 EXPECT_EQ("1", cookie->Value());
234 EXPECT_EQ("www.foo.com", cookie->Domain());
235 EXPECT_EQ("/", cookie->Path());
236 EXPECT_FALSE(cookie->IsSecure());
237 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
238 EXPECT_EQ(cookie->SourcePort(), 80);
239
240 // Test creating secure cookies. Secure scheme is not checked upon creation,
241 // so a URL of any scheme can create a Secure cookie.
242 cookie =
243 CanonicalCookie::Create(url, "A=2; Secure", creation_time, server_time,
244 absl::nullopt /* cookie_partition_key */);
245 EXPECT_TRUE(cookie->IsSecure());
246
247 cookie = CanonicalCookie::Create(https_url, "A=2; Secure", creation_time,
248 server_time,
249 absl::nullopt /* cookie_partition_key */);
250 EXPECT_TRUE(cookie->IsSecure());
251
252 GURL url3("https://www.foo.com");
253 cookie =
254 CanonicalCookie::Create(url3, "A=2; Secure", creation_time, server_time,
255 absl::nullopt /* cookie_partition_key */);
256 EXPECT_TRUE(cookie->IsSecure());
257 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
258
259 cookie = CanonicalCookie::Create(url3, "A=2", creation_time, server_time,
260 absl::nullopt /* cookie_partition_key */);
261 EXPECT_FALSE(cookie->IsSecure());
262 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
263
264 // Test creating cookie from localhost URL.
265 cookie = CanonicalCookie::Create(GURL("http://localhost/path"), "A=2",
266 creation_time, server_time,
267 absl::nullopt /* cookie_partition_key */);
268 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
269
270 cookie = CanonicalCookie::Create(GURL("http://127.0.0.1/path"), "A=2",
271 creation_time, server_time,
272 absl::nullopt /* cookie_partition_key */);
273 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
274
275 cookie = CanonicalCookie::Create(GURL("http://[::1]/path"), "A=2",
276 creation_time, server_time,
277 absl::nullopt /* cookie_partition_key */);
278 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
279
280 cookie = CanonicalCookie::Create(GURL("https://localhost/path"), "A=2",
281 creation_time, server_time,
282 absl::nullopt /* cookie_partition_key */);
283 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
284
285 cookie = CanonicalCookie::Create(GURL("https://127.0.0.1/path"), "A=2",
286 creation_time, server_time,
287 absl::nullopt /* cookie_partition_key */);
288 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
289
290 cookie = CanonicalCookie::Create(GURL("https://[::1]/path"), "A=2",
291 creation_time, server_time,
292 absl::nullopt /* cookie_partition_key */);
293 EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
294
295 // Test creating http only cookies. HttpOnly is not checked upon creation.
296 cookie =
297 CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
298 absl::nullopt /* cookie_partition_key */);
299 EXPECT_TRUE(cookie->IsHttpOnly());
300
301 cookie =
302 CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
303 absl::nullopt /* cookie_partition_key */);
304 EXPECT_TRUE(cookie->IsHttpOnly());
305
306 // Test creating SameSite cookies. SameSite is not checked upon creation.
307 cookie = CanonicalCookie::Create(url, "A=2; SameSite=Strict", creation_time,
308 server_time,
309 absl::nullopt /* cookie_partition_key */);
310 ASSERT_TRUE(cookie.get());
311 EXPECT_EQ(CookieSameSite::STRICT_MODE, cookie->SameSite());
312 cookie = CanonicalCookie::Create(url, "A=2; SameSite=Lax", creation_time,
313 server_time,
314 absl::nullopt /* cookie_partition_key */);
315 ASSERT_TRUE(cookie.get());
316 EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite());
317 cookie = CanonicalCookie::Create(url, "A=2; SameSite=Extended", creation_time,
318 server_time,
319 absl::nullopt /* cookie_partition_key */);
320 ASSERT_TRUE(cookie.get());
321 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
322 cookie = CanonicalCookie::Create(url, "A=2; SameSite=None", creation_time,
323 server_time,
324 absl::nullopt /* cookie_partition_key */);
325 ASSERT_TRUE(cookie.get());
326 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
327 cookie = CanonicalCookie::Create(url, "A=2", creation_time, server_time,
328 absl::nullopt /* cookie_partition_key */);
329 ASSERT_TRUE(cookie.get());
330 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
331
332 // Test creating cookies with different ports.
333 cookie = CanonicalCookie::Create(GURL("http://www.foo.com"), "B=1",
334 creation_time, server_time,
335 absl::nullopt /* cookie_partition_key */);
336 EXPECT_EQ(cookie->SourcePort(), 80);
337
338 cookie = CanonicalCookie::Create(GURL("http://www.foo.com:81"), "B=1",
339 creation_time, server_time,
340 absl::nullopt /* cookie_partition_key */);
341 EXPECT_EQ(cookie->SourcePort(), 81);
342
343 cookie = CanonicalCookie::Create(GURL("https://www.foo.com"), "B=1",
344 creation_time, server_time,
345 absl::nullopt /* cookie_partition_key */);
346 EXPECT_EQ(cookie->SourcePort(), 443);
347
348 cookie = CanonicalCookie::Create(GURL("https://www.foo.com:1234"), "B=1",
349 creation_time, server_time,
350 absl::nullopt /* cookie_partition_key */);
351 EXPECT_EQ(cookie->SourcePort(), 1234);
352
353 cookie = CanonicalCookie::Create(GURL("http://www.foo.com:443"), "B=1",
354 creation_time, server_time,
355 absl::nullopt /* cookie_partition_key */);
356 EXPECT_EQ(cookie->SourcePort(), 443);
357
358 // An invalid port leads to an invalid GURL, which causes cookie creation
359 // to fail.
360 CookieInclusionStatus status;
361 cookie = CanonicalCookie::Create(
362 GURL("http://www.foo.com:70000"), "B=1", creation_time, server_time,
363 absl::nullopt /* cookie_partition_key */, &status);
364 EXPECT_FALSE(cookie.get());
365 EXPECT_TRUE(status.HasExclusionReason(
366 CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
367 }
368
TEST(CanonicalCookieTest,CreateInvalidUrl)369 TEST(CanonicalCookieTest, CreateInvalidUrl) {
370 base::Time creation_time = base::Time::Now();
371 absl::optional<base::Time> server_time = absl::nullopt;
372 CookieInclusionStatus status;
373 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
374 GURL("http://.127.0.0.1/path"), "A=2", creation_time, server_time,
375 absl::nullopt /* cookie_partition_key */, &status);
376 EXPECT_FALSE(cookie.get());
377 EXPECT_TRUE(status.HasExclusionReason(
378 CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
379 }
380
381 // Test that a cookie string with an empty domain attribute generates a
382 // canonical host cookie.
TEST(CanonicalCookieTest,CreateHostCookieFromString)383 TEST(CanonicalCookieTest, CreateHostCookieFromString) {
384 // Create a new canonical host cookie via empty string domain in the
385 // cookie_line.
386 GURL url("http://www.example.com/test/foo.html");
387 base::Time creation_time = base::Time::Now();
388 absl::optional<base::Time> server_time = absl::nullopt;
389 std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
390 url, "A=2; domain=; Secure", creation_time, server_time,
391 absl::nullopt /*cookie_partition_key*/));
392 EXPECT_EQ("www.example.com", cookie->Domain());
393 EXPECT_TRUE(cookie->IsHostCookie());
394 }
395
TEST(CanonicalCookieTest,CreateNonStandardSameSite)396 TEST(CanonicalCookieTest, CreateNonStandardSameSite) {
397 GURL url("http://www.example.com/test/foo.html");
398 base::Time now = base::Time::Now();
399 std::unique_ptr<CanonicalCookie> cookie;
400 absl::optional<base::Time> server_time = absl::nullopt;
401
402 // Non-standard value for the SameSite attribute.
403 cookie = CanonicalCookie::Create(url, "A=2; SameSite=NonStandard", now,
404 server_time,
405 absl::nullopt /* cookie_partition_key */);
406 EXPECT_TRUE(cookie.get());
407 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
408
409 // Omit value for the SameSite attribute.
410 cookie = CanonicalCookie::Create(url, "A=2; SameSite", now, server_time,
411 absl::nullopt /* cookie_partition_key */);
412 EXPECT_TRUE(cookie.get());
413 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
414 }
415
TEST(CanonicalCookieTest,CreateSameSiteInCrossSiteContexts)416 TEST(CanonicalCookieTest, CreateSameSiteInCrossSiteContexts) {
417 GURL url("http://www.example.com/test/foo.html");
418 base::Time now = base::Time::Now();
419 std::unique_ptr<CanonicalCookie> cookie;
420 absl::optional<base::Time> server_time = absl::nullopt;
421
422 // A cookie can be created from any SameSiteContext regardless of SameSite
423 // value (it is upon setting the cookie that the SameSiteContext comes into
424 // effect).
425 cookie =
426 CanonicalCookie::Create(url, "A=2; SameSite=Strict", now, server_time,
427 absl::nullopt /* cookie_partition_key */);
428 EXPECT_TRUE(cookie.get());
429 cookie = CanonicalCookie::Create(url, "A=2; SameSite=Lax", now, server_time,
430 absl::nullopt /* cookie_partition_key */);
431 EXPECT_TRUE(cookie.get());
432 cookie = CanonicalCookie::Create(url, "A=2; SameSite=None", now, server_time,
433 absl::nullopt /* cookie_partition_key */);
434 EXPECT_TRUE(cookie.get());
435 cookie = CanonicalCookie::Create(url, "A=2;", now, server_time,
436 absl::nullopt /* cookie_partition_key */);
437 EXPECT_TRUE(cookie.get());
438 }
439
TEST(CanonicalCookieTest,CreateHttpOnly)440 TEST(CanonicalCookieTest, CreateHttpOnly) {
441 GURL url("http://www.example.com/test/foo.html");
442 base::Time now = base::Time::Now();
443 absl::optional<base::Time> server_time = absl::nullopt;
444 CookieInclusionStatus status;
445
446 // An HttpOnly cookie can be created.
447 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
448 url, "A=2; HttpOnly", now, server_time,
449 absl::nullopt /* cookie_partition_key */, &status);
450 EXPECT_TRUE(cookie->IsHttpOnly());
451 EXPECT_TRUE(status.IsInclude());
452 }
453
TEST(CanonicalCookieTest,CreateWithInvalidDomain)454 TEST(CanonicalCookieTest, CreateWithInvalidDomain) {
455 GURL url("http://www.example.com/test/foo.html");
456 base::Time now = base::Time::Now();
457 absl::optional<base::Time> server_time = absl::nullopt;
458 CookieInclusionStatus status;
459
460 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
461 url, "A=2; Domain=wrongdomain.com", now, server_time,
462 absl::nullopt /* cookie_partition_key */, &status);
463 EXPECT_EQ(nullptr, cookie.get());
464 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
465 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
466 }
467
468 // Creating a cookie for an eTLD is possible, but it must match the hostname and
469 // be a host cookie.
TEST(CanonicalCookieTest,CreateFromPublicSuffix)470 TEST(CanonicalCookieTest, CreateFromPublicSuffix) {
471 GURL url("http://com/path");
472 base::Time now = base::Time::Now();
473 absl::optional<base::Time> server_time = absl::nullopt;
474 CookieInclusionStatus status;
475
476 // Host cookie can be created for an eTLD.
477 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
478 url, "A=2", now, server_time, absl::nullopt, &status);
479 EXPECT_TRUE(status.IsInclude());
480 EXPECT_TRUE(cookie->IsHostCookie());
481 EXPECT_EQ("com", cookie->Domain());
482
483 // Attempting to create a domain cookie still yields a valid cookie, but only
484 // if the domain attribute is the same as the URL's host, and it becomes a
485 // host cookie only.
486 cookie = CanonicalCookie::Create(url, "A=2; domain=com", now, server_time,
487 absl::nullopt, &status);
488 EXPECT_TRUE(status.IsInclude());
489 EXPECT_TRUE(cookie->IsHostCookie());
490 EXPECT_EQ("com", cookie->Domain());
491
492 // Same thing if the domain attribute is specified with a dot.
493 cookie = CanonicalCookie::Create(url, "A=2; domain=.com", now, server_time,
494 absl::nullopt, &status);
495 EXPECT_TRUE(status.IsInclude());
496 EXPECT_TRUE(cookie->IsHostCookie());
497 EXPECT_EQ("com", cookie->Domain());
498
499 // Capitalization is ok because everything is canonicalized.
500 cookie = CanonicalCookie::Create(url, "A=2; domain=CoM", now, server_time,
501 absl::nullopt, &status);
502 EXPECT_TRUE(status.IsInclude());
503 EXPECT_TRUE(cookie->IsHostCookie());
504 EXPECT_EQ("com", cookie->Domain());
505
506 // Test an eTLD that is more than one label.
507 // If the domain attribute minus any leading dot is the same as the url's
508 // host, allow it to become a host cookie.
509 GURL multilabel_url = GURL("http://co.uk/path");
510 cookie = CanonicalCookie::Create(multilabel_url, "A=2", now, server_time,
511 absl::nullopt, &status);
512 EXPECT_TRUE(status.IsInclude());
513 EXPECT_TRUE(cookie->IsHostCookie());
514 EXPECT_EQ("co.uk", cookie->Domain());
515
516 cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=co.uk", now,
517 server_time, absl::nullopt, &status);
518 EXPECT_TRUE(status.IsInclude());
519 EXPECT_TRUE(cookie->IsHostCookie());
520 EXPECT_EQ("co.uk", cookie->Domain());
521
522 cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=.co.uk", now,
523 server_time, absl::nullopt, &status);
524 EXPECT_TRUE(status.IsInclude());
525 EXPECT_TRUE(cookie->IsHostCookie());
526 EXPECT_EQ("co.uk", cookie->Domain());
527
528 // Don't allow setting a domain cookie from a public suffix for a superdomain.
529 cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=uk", now,
530 server_time, absl::nullopt, &status);
531 EXPECT_EQ(nullptr, cookie.get());
532 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
533 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
534
535 cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=.uk", now,
536 server_time, absl::nullopt, &status);
537 EXPECT_EQ(nullptr, cookie.get());
538 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
539 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
540
541 // Don't allow setting a domain cookie for an unrelated domain.
542 cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=foo.com", now,
543 server_time, absl::nullopt, &status);
544 EXPECT_EQ(nullptr, cookie.get());
545 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
546 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
547
548 // Don't allow setting a domain cookie for some other domain with no
549 // registrable domain.
550 cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=com", now,
551 server_time, absl::nullopt, &status);
552 EXPECT_EQ(nullptr, cookie.get());
553 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
554 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
555 }
556
TEST(CanonicalCookieTest,CreateWithNonASCIIDomain)557 TEST(CanonicalCookieTest, CreateWithNonASCIIDomain) {
558 GURL url("http://www.xn--xample-9ua.com/test/foo.html");
559 base::Time now = base::Time::Now();
560 absl::optional<base::Time> server_time = absl::nullopt;
561
562 // Test with feature flag enabled.
563 {
564 base::test::ScopedFeatureList feature_list;
565 feature_list.InitAndEnableFeature(features::kCookieDomainRejectNonASCII);
566 CookieInclusionStatus status;
567
568 // Test that non-ascii characters are rejected.
569 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
570 url, "A=1; Domain=\xC3\xA9xample.com", now, server_time,
571 absl::nullopt /* cookie_partition_key */, &status);
572 EXPECT_EQ(nullptr, cookie.get());
573 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
574 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN,
575 CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII}));
576 EXPECT_FALSE(
577 status.HasWarningReason(CookieInclusionStatus::WARN_DOMAIN_NON_ASCII));
578 }
579
580 // Test with feature flag disabled.
581 {
582 base::test::ScopedFeatureList feature_list;
583 feature_list.InitAndDisableFeature(features::kCookieDomainRejectNonASCII);
584 CookieInclusionStatus status2;
585
586 std::unique_ptr<CanonicalCookie> cookie2 = CanonicalCookie::Create(
587 url, "A=2; Domain=\xC3\xA9xample.com", now, server_time,
588 absl::nullopt /* cookie_partition_key */, &status2);
589
590 EXPECT_TRUE(cookie2.get());
591 EXPECT_TRUE(status2.IsInclude());
592 EXPECT_TRUE(
593 status2.HasWarningReason(CookieInclusionStatus::WARN_DOMAIN_NON_ASCII));
594 }
595
596 // Test that regular ascii punycode still works.
597 CookieInclusionStatus status3;
598 std::unique_ptr<CanonicalCookie> cookie3 = CanonicalCookie::Create(
599 url, "A=3; Domain=xn--xample-9ua.com", now, server_time,
600 absl::nullopt /* cookie_partition_key */, &status3);
601 EXPECT_TRUE(cookie3.get());
602 EXPECT_TRUE(status3.IsInclude());
603 EXPECT_FALSE(
604 status3.HasWarningReason(CookieInclusionStatus::WARN_DOMAIN_NON_ASCII));
605 }
606
TEST(CanonicalCookieTest,CreateWithDomainAsIP)607 TEST(CanonicalCookieTest, CreateWithDomainAsIP) {
608 GURL url("http://1.1.1.1");
609 GURL url6("http://[2606:2800:220:1:248:1893:25c8:1946]");
610
611 base::Time now = base::Time::Now();
612 absl::optional<base::Time> server_time = absl::nullopt;
613 CookieInclusionStatus status;
614
615 const struct {
616 const GURL url;
617 const std::string cookie_line;
618 const bool expectedResult;
619 } kTests[] = {
620 {url, "d=1;Domain=1.1.1.1;", true},
621 {url, "dd=1;Domain=.1.1.1.1;", true},
622 {url, "ds=1;Domain=1.1.1;", false},
623 {url, "dsd=1;Domain=.1.1.1;", false},
624 {url, "dx=1;Domain=0x01.0x1.0x1.0x1;", false},
625 {url, "dxd=1;Domain=.0x01.0x1.0x1.0x1;", false},
626 {url, "do=1;Domain=0001.0001.0001.0001;", false},
627 {url, "d10=1;Domain=16843009;", false},
628 {url, "d16=value;Domain=0x1010101;", false},
629 {url, "d8=1;Domain=0100200401;", false},
630 {url, "dm=1;Domain=00001.0x01.1.001;", false},
631 {url6, "d1ipv6=1;Domain=[2606:2800:220:1:248:1893:25c8:1946];", true},
632 {url6, "dd1ipv6=1;Domain=.[2606:2800:220:1:248:1893:25c8:1946];", true},
633 {url6, "dc1ipv6=1;Domain=[2606:2800:220:1:248:1893:25C8:1946];", true},
634 {url6, "d2ipv6=1;Domain=2606:2800:220:1:248:1893:25c8:1946;", false},
635 {url6, "dd2ipv6=1;Domain=.2606:2800:220:1:248:1893:25c8:1946;", false},
636 {url6, "dc2ipv6=1;Domain=2606:2800:220:1:248:1893:25C8:1946;", false},
637 };
638
639 for (const auto& test : kTests) {
640 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
641 test.url, test.cookie_line, now, server_time,
642 absl::nullopt /* cookie_partition_key */, &status);
643 if (test.expectedResult) {
644 ASSERT_TRUE(cookie.get());
645 EXPECT_EQ(test.url.host(), cookie->Domain());
646 } else {
647 EXPECT_EQ(nullptr, cookie.get());
648 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
649 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
650 }
651 }
652 }
653
TEST(CanonicalCookieTest,CreateSameParty)654 TEST(CanonicalCookieTest, CreateSameParty) {
655 GURL url("http://www.example.com/test/foo.html");
656 GURL https_url("https://www.example.com/test/foo.html");
657 base::Time creation_time = base::Time::Now();
658 absl::optional<base::Time> server_time = absl::nullopt;
659
660 CookieInclusionStatus status;
661 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
662 url, "A=2; SameParty; Secure", creation_time, server_time,
663 absl::nullopt /* cookie_partition_key */, &status);
664 ASSERT_TRUE(cookie.get());
665 EXPECT_TRUE(status.IsInclude());
666 EXPECT_TRUE(cookie->IsSecure());
667 EXPECT_TRUE(cookie->IsSameParty());
668 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
669
670 cookie = CanonicalCookie::Create(
671 url, "A=2; SameParty; SameSite=None; Secure", creation_time, server_time,
672 absl::nullopt /* cookie_partition_key */, &status);
673 ASSERT_TRUE(cookie.get());
674 EXPECT_TRUE(status.IsInclude());
675 EXPECT_TRUE(cookie->IsSecure());
676 EXPECT_TRUE(cookie->IsSameParty());
677 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
678
679 cookie = CanonicalCookie::Create(
680 url, "A=2; SameParty; SameSite=Lax; Secure", creation_time, server_time,
681 absl::nullopt /* cookie_partition_key */, &status);
682 ASSERT_TRUE(cookie.get());
683 EXPECT_TRUE(status.IsInclude());
684 EXPECT_TRUE(cookie->IsSecure());
685 EXPECT_TRUE(cookie->IsSameParty());
686 EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite());
687
688 // SameParty cookie with SameSite=Strict is invalid.
689 cookie = CanonicalCookie::Create(
690 url, "A=2; SameParty; SameSite=Strict; Secure", creation_time,
691 server_time, absl::nullopt /* cookie_partition_key */, &status);
692 EXPECT_FALSE(cookie.get());
693 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
694 {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
695
696 // SameParty cookie without Secure is invalid.
697 cookie = CanonicalCookie::Create(
698 url, "A=2; SameParty; SameSite=Lax", creation_time, server_time,
699 absl::nullopt /* cookie_partition_key */, &status);
700 EXPECT_FALSE(cookie.get());
701 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
702 {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
703 }
704
TEST(CanonicalCookieTest,CreateWithPartitioned)705 TEST(CanonicalCookieTest, CreateWithPartitioned) {
706 GURL url("https://www.example.com/test/foo.html");
707 base::Time creation_time = base::Time::Now();
708 absl::optional<base::Time> server_time = absl::nullopt;
709 auto partition_key = absl::make_optional(
710 CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com")));
711 CookieInclusionStatus status;
712
713 // Valid Partitioned attribute
714 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
715 url, "__Host-A=2; Partitioned; Path=/; Secure", creation_time,
716 server_time, partition_key, &status);
717 ASSERT_TRUE(cookie.get());
718 EXPECT_TRUE(status.IsInclude());
719 EXPECT_TRUE(cookie->IsSecure());
720 EXPECT_TRUE(cookie->IsPartitioned());
721 EXPECT_EQ(partition_key, cookie->PartitionKey());
722 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
723
724 // Create() without Partitioned in the cookie line should not result in a
725 // partitioned cookie.
726 status = CookieInclusionStatus();
727 cookie =
728 CanonicalCookie::Create(url, "__Host-A=2; Path=/; Secure", creation_time,
729 server_time, partition_key, &status);
730 ASSERT_TRUE(cookie.get());
731 EXPECT_TRUE(status.IsInclude());
732 EXPECT_FALSE(cookie->IsPartitioned());
733 EXPECT_FALSE(cookie->PartitionKey());
734
735 // Partitioned cookies with no __Host- prefix are still valid if they still
736 // have Secure, Path=/, and no Domain.
737 status = CookieInclusionStatus();
738 cookie = CanonicalCookie::Create(url, "A=2; Partitioned; Path=/; Secure",
739 creation_time, server_time, partition_key,
740 &status);
741 EXPECT_TRUE(cookie.get());
742 EXPECT_TRUE(status.IsInclude());
743 EXPECT_TRUE(cookie->IsPartitioned());
744 EXPECT_EQ(partition_key, cookie->PartitionKey());
745
746 // Invalid Partitioned attribute: No Secure attribute.
747 status = CookieInclusionStatus();
748 cookie =
749 CanonicalCookie::Create(url, "A=2; Partitioned; Path=/", creation_time,
750 server_time, partition_key, &status);
751 EXPECT_FALSE(cookie.get());
752 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
753 {CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED}));
754
755 // Partitioned attribute: No Path attribute.
756 status = CookieInclusionStatus();
757 cookie =
758 CanonicalCookie::Create(url, "A=2; Partitioned; Secure", creation_time,
759 server_time, partition_key, &status);
760 EXPECT_TRUE(cookie.get());
761 EXPECT_TRUE(status.IsInclude());
762 EXPECT_TRUE(cookie->IsPartitioned());
763 EXPECT_EQ(partition_key, cookie->PartitionKey());
764
765 // Partitioned attribute: Path attribute not equal to "/".
766 status = CookieInclusionStatus();
767 cookie = CanonicalCookie::Create(
768 url, "A=2; Partitioned; Path=/foobar; Secure", creation_time, server_time,
769 partition_key, &status);
770 EXPECT_TRUE(cookie.get());
771 EXPECT_TRUE(status.IsInclude());
772 EXPECT_TRUE(cookie->IsPartitioned());
773 EXPECT_EQ(partition_key, cookie->PartitionKey());
774
775 // Partitioned attribute: Domain cookie.
776 status = CookieInclusionStatus();
777 cookie = CanonicalCookie::Create(
778 url, "A=2; Partitioned; Path=/; Secure; Domain=example.com",
779 creation_time, server_time, partition_key, &status);
780 EXPECT_TRUE(cookie.get());
781 LOG(ERROR) << status;
782 EXPECT_TRUE(status.IsInclude());
783 EXPECT_TRUE(cookie->IsPartitioned());
784 EXPECT_EQ(partition_key, cookie->PartitionKey());
785
786 // No Partitioned attribute but with a nonce.
787 status = CookieInclusionStatus();
788 auto partition_key_with_nonce =
789 absl::make_optional(CookiePartitionKey::FromURLForTesting(
790 GURL("https://toplevelsite.com"), base::UnguessableToken::Create()));
791 cookie =
792 CanonicalCookie::Create(url, "__Host-A=2; Path=/; Secure", creation_time,
793 server_time, partition_key_with_nonce, &status);
794 EXPECT_TRUE(cookie.get());
795 EXPECT_TRUE(status.IsInclude());
796 EXPECT_TRUE(cookie->IsPartitioned());
797 EXPECT_EQ(partition_key_with_nonce, cookie->PartitionKey());
798 }
799
TEST(CanonicalCookieTest,CreateWithPartitioned_Localhost)800 TEST(CanonicalCookieTest, CreateWithPartitioned_Localhost) {
801 GURL url("http://localhost:8000/foo/bar.html");
802 base::Time creation_time = base::Time::Now();
803 absl::optional<base::Time> server_time = absl::nullopt;
804 auto partition_key =
805 CookiePartitionKey::FromURLForTesting(GURL("http://localhost:8000"));
806 CookieInclusionStatus status;
807
808 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
809 url, "foo=bar; Path=/; Secure; Partitioned", creation_time, server_time,
810 partition_key, &status);
811 ASSERT_TRUE(cookie.get());
812 EXPECT_TRUE(status.IsInclude());
813 EXPECT_TRUE(cookie->IsSecure());
814 EXPECT_TRUE(cookie->IsPartitioned());
815 EXPECT_EQ(partition_key, cookie->PartitionKey());
816 EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
817 }
818
TEST_P(CanonicalCookieWithClampingTest,CreateWithMaxAge)819 TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
820 GURL url("http://www.example.com/test/foo.html");
821 base::Time creation_time = base::Time::Now();
822 absl::optional<base::Time> server_time = absl::nullopt;
823
824 // Max-age with positive integer.
825 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
826 url, "A=1; max-age=60", creation_time, server_time,
827 absl::nullopt /* cookie_partition_key */);
828 EXPECT_TRUE(cookie.get());
829 EXPECT_TRUE(cookie->IsPersistent());
830 EXPECT_FALSE(cookie->IsExpired(creation_time));
831 EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
832 EXPECT_TRUE(cookie->IsCanonical());
833
834 // Max-age with expires (max-age should take precedence).
835 cookie = CanonicalCookie::Create(
836 url, "A=1; expires=01-Jan-1970, 00:00:00 GMT; max-age=60", creation_time,
837 server_time, absl::nullopt /* cookie_partition_key */);
838 EXPECT_TRUE(cookie.get());
839 EXPECT_TRUE(cookie->IsPersistent());
840 EXPECT_FALSE(cookie->IsExpired(creation_time));
841 EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
842 EXPECT_TRUE(cookie->IsCanonical());
843
844 // Max-age=0 should create an expired cookie with expiry equal to the earliest
845 // representable time.
846 cookie =
847 CanonicalCookie::Create(url, "A=1; max-age=0", creation_time, server_time,
848 absl::nullopt /* cookie_partition_key */);
849 EXPECT_TRUE(cookie.get());
850 EXPECT_TRUE(cookie->IsPersistent());
851 EXPECT_TRUE(cookie->IsExpired(creation_time));
852 EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
853 EXPECT_TRUE(cookie->IsCanonical());
854
855 // Negative max-age should create an expired cookie with expiry equal to the
856 // earliest representable time.
857 cookie = CanonicalCookie::Create(url, "A=1; max-age=-1", creation_time,
858 server_time,
859 absl::nullopt /* cookie_partition_key */);
860 EXPECT_TRUE(cookie.get());
861 EXPECT_TRUE(cookie->IsPersistent());
862 EXPECT_TRUE(cookie->IsExpired(creation_time));
863 EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
864 EXPECT_TRUE(cookie->IsCanonical());
865
866 // Max-age with whitespace (should be trimmed out).
867 cookie = CanonicalCookie::Create(url, "A=1; max-age = 60 ; Secure",
868 creation_time, server_time,
869 absl::nullopt /* cookie_partition_key */);
870 EXPECT_TRUE(cookie.get());
871 EXPECT_TRUE(cookie->IsPersistent());
872 EXPECT_FALSE(cookie->IsExpired(creation_time));
873 EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
874 EXPECT_TRUE(cookie->IsCanonical());
875
876 // Max-age with non-integer should be ignored.
877 cookie = CanonicalCookie::Create(url, "A=1; max-age=abcd", creation_time,
878 server_time,
879 absl::nullopt /* cookie_partition_key */);
880 EXPECT_TRUE(cookie.get());
881 EXPECT_FALSE(cookie->IsPersistent());
882 EXPECT_FALSE(cookie->IsExpired(creation_time));
883 EXPECT_TRUE(cookie->IsCanonical());
884
885 // Overflow max-age should be clipped.
886 cookie = CanonicalCookie::Create(url,
887 "A=1; "
888 "max-age="
889 "9999999999999999999999999999999999999999999"
890 "999999999999999999999999999999999999999999",
891 creation_time, server_time,
892 absl::nullopt /* cookie_partition_key */);
893 EXPECT_TRUE(cookie.get());
894 EXPECT_TRUE(cookie->IsPersistent());
895 EXPECT_FALSE(cookie->IsExpired(creation_time));
896 if (IsClampCookieExpiryTo400DaysEnabled()) {
897 EXPECT_EQ(creation_time + base::Days(400), cookie->ExpiryDate());
898 } else {
899 EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
900 }
901 EXPECT_TRUE(cookie->IsCanonical());
902
903 // Underflow max-age should be clipped.
904 cookie = CanonicalCookie::Create(url,
905 "A=1; "
906 "max-age=-"
907 "9999999999999999999999999999999999999999999"
908 "999999999999999999999999999999999999999999",
909 creation_time, server_time,
910 absl::nullopt /* cookie_partition_key */);
911 EXPECT_TRUE(cookie.get());
912 EXPECT_TRUE(cookie->IsPersistent());
913 EXPECT_TRUE(cookie->IsExpired(creation_time));
914 EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
915 EXPECT_TRUE(cookie->IsCanonical());
916 }
917
TEST_P(CanonicalCookieWithClampingTest,CreateWithExpires)918 TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
919 GURL url("http://www.example.com/test/foo.html");
920 base::Time creation_time = base::Time::Now();
921 absl::optional<base::Time> server_time = absl::nullopt;
922
923 // Expires in the past
924 base::Time past_date = base::Time::Now() - base::Days(10);
925 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
926 url, "A=1; expires=" + base::TimeFormatHTTP(past_date), creation_time,
927 server_time, absl::nullopt /* cookie_partition_key */);
928 EXPECT_TRUE(cookie.get());
929 EXPECT_TRUE(cookie->IsPersistent());
930 EXPECT_TRUE(cookie->IsExpired(creation_time));
931 EXPECT_TRUE((past_date - cookie->ExpiryDate()).magnitude() <
932 base::Seconds(1));
933 EXPECT_TRUE(cookie->IsCanonical());
934
935 // Expires in the future
936 base::Time future_date = base::Time::Now() + base::Days(10);
937 cookie = CanonicalCookie::Create(
938 url, "A=1; expires=" + base::TimeFormatHTTP(future_date), creation_time,
939 server_time, absl::nullopt /* cookie_partition_key */);
940 EXPECT_TRUE(cookie.get());
941 EXPECT_TRUE(cookie->IsPersistent());
942 EXPECT_FALSE(cookie->IsExpired(creation_time));
943 EXPECT_TRUE((future_date - cookie->ExpiryDate()).magnitude() <
944 base::Seconds(1));
945 EXPECT_TRUE(cookie->IsCanonical());
946
947 // Expires in the far future
948 future_date = base::Time::Now() + base::Days(800);
949 cookie = CanonicalCookie::Create(
950 url, "A=1; expires=" + base::TimeFormatHTTP(future_date), creation_time,
951 server_time, absl::nullopt /* cookie_partition_key */);
952 EXPECT_TRUE(cookie.get());
953 EXPECT_TRUE(cookie->IsPersistent());
954 EXPECT_FALSE(cookie->IsExpired(creation_time));
955 if (IsClampCookieExpiryTo400DaysEnabled()) {
956 EXPECT_TRUE(
957 (cookie->ExpiryDate() - creation_time - base::Days(400)).magnitude() <
958 base::Seconds(1));
959 } else {
960 EXPECT_TRUE((future_date - cookie->ExpiryDate()).magnitude() <
961 base::Seconds(1));
962 }
963 EXPECT_TRUE(cookie->IsCanonical());
964
965 // Expires in the far future using CreateUnsafeCookieForTesting.
966 cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
967 "A", "1", url.host(), url.path(), creation_time, base::Time::Max(),
968 base::Time(), base::Time(), true, false, CookieSameSite::UNSPECIFIED,
969 COOKIE_PRIORITY_HIGH, false, absl::nullopt /* cookie_partition_key */,
970 CookieSourceScheme::kSecure, 443);
971 EXPECT_TRUE(cookie.get());
972 EXPECT_TRUE(cookie->IsPersistent());
973 EXPECT_FALSE(cookie->IsExpired(creation_time));
974 EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
975 EXPECT_EQ(base::Time(), cookie->LastUpdateDate());
976 if (IsClampCookieExpiryTo400DaysEnabled()) {
977 EXPECT_FALSE(cookie->IsCanonical());
978 } else {
979 EXPECT_TRUE(cookie->IsCanonical());
980 }
981
982 // Expires in the far future using FromStorage.
983 cookie = CanonicalCookie::FromStorage(
984 "A", "B", "www.foo.com", "/bar", creation_time, base::Time::Max(),
985 base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
986 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
987 false /*same_party*/, absl::nullopt /*partition_key*/,
988 CookieSourceScheme::kSecure, 443);
989 EXPECT_TRUE(cookie.get());
990 EXPECT_TRUE(cookie->IsPersistent());
991 EXPECT_FALSE(cookie->IsExpired(creation_time));
992 EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
993 EXPECT_EQ(base::Time(), cookie->LastUpdateDate());
994 if (IsClampCookieExpiryTo400DaysEnabled()) {
995 EXPECT_FALSE(cookie->IsCanonical());
996 } else {
997 EXPECT_TRUE(cookie->IsCanonical());
998 }
999 }
1000
TEST(CanonicalCookieTest,EmptyExpiry)1001 TEST(CanonicalCookieTest, EmptyExpiry) {
1002 GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
1003 base::Time creation_time = base::Time::Now();
1004 absl::optional<base::Time> server_time = absl::nullopt;
1005
1006 std::string cookie_line =
1007 "ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
1008 std::unique_ptr<CanonicalCookie> cookie(
1009 CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
1010 absl::nullopt /* cookie_partition_key */));
1011 EXPECT_TRUE(cookie.get());
1012 EXPECT_FALSE(cookie->IsPersistent());
1013 EXPECT_FALSE(cookie->IsExpired(creation_time));
1014 EXPECT_EQ(base::Time(), cookie->ExpiryDate());
1015
1016 // With a stale server time
1017 server_time = creation_time - base::Hours(1);
1018 cookie = CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
1019 absl::nullopt /* cookie_partition_key */);
1020 EXPECT_TRUE(cookie.get());
1021 EXPECT_FALSE(cookie->IsPersistent());
1022 EXPECT_FALSE(cookie->IsExpired(creation_time));
1023 EXPECT_EQ(base::Time(), cookie->ExpiryDate());
1024
1025 // With a future server time
1026 server_time = creation_time + base::Hours(1);
1027 cookie = CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
1028 absl::nullopt /* cookie_partition_key */);
1029 EXPECT_TRUE(cookie.get());
1030 EXPECT_FALSE(cookie->IsPersistent());
1031 EXPECT_FALSE(cookie->IsExpired(creation_time));
1032 EXPECT_EQ(base::Time(), cookie->ExpiryDate());
1033 }
1034
TEST_P(CanonicalCookieWithClampingTest,CreateWithLastUpdate)1035 TEST_P(CanonicalCookieWithClampingTest, CreateWithLastUpdate) {
1036 GURL url("http://www.example.com/test/foo.html");
1037 base::Time creation_time = base::Time::Now() - base::Days(1);
1038 base::Time last_update_time = base::Time::Now() - base::Hours(1);
1039 absl::optional<base::Time> server_time = absl::nullopt;
1040
1041 // Creating a cookie sets the last update date as now.
1042 std::unique_ptr<CanonicalCookie> cookie =
1043 CanonicalCookie::Create(url, "A=1", creation_time, server_time,
1044 /*cookie_partition_key=*/absl::nullopt);
1045 ASSERT_TRUE(cookie.get());
1046 EXPECT_TRUE((base::Time::Now() - cookie->LastUpdateDate()).magnitude() <
1047 base::Seconds(1));
1048
1049 // Creating a sanitized cookie sets the last update date as now.
1050 cookie = CanonicalCookie::CreateSanitizedCookie(
1051 url, "A", "1", url.host(), url.path(), creation_time, base::Time(),
1052 creation_time, /*secure=*/true,
1053 /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
1054 COOKIE_PRIORITY_DEFAULT, /*same_party=*/false,
1055 /*partition_key=*/absl::nullopt);
1056 ASSERT_TRUE(cookie.get());
1057 EXPECT_TRUE((base::Time::Now() - cookie->LastUpdateDate()).magnitude() <
1058 base::Seconds(1));
1059
1060 // Creating an unsafe cookie allows us to set the last update date.
1061 cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1062 "A", "1", url.host(), url.path(), creation_time, base::Time(),
1063 base::Time(), last_update_time, /*secure=*/true,
1064 /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
1065 COOKIE_PRIORITY_DEFAULT, /*same_party=*/false,
1066 /*partition_key=*/absl::nullopt, CookieSourceScheme::kSecure,
1067 /*source_port=*/443);
1068 ASSERT_TRUE(cookie.get());
1069 EXPECT_EQ(last_update_time, cookie->LastUpdateDate());
1070
1071 // Loading a cookie from storage allows us to set the last update date.
1072 cookie = CanonicalCookie::FromStorage(
1073 "A", "1", url.host(), url.path(), creation_time, base::Time(),
1074 base::Time(), last_update_time, /*secure=*/true,
1075 /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
1076 COOKIE_PRIORITY_DEFAULT, /*same_party=*/false,
1077 /*partition_key=*/absl::nullopt, CookieSourceScheme::kSecure,
1078 /*source_port=*/443);
1079 ASSERT_TRUE(cookie.get());
1080 EXPECT_EQ(last_update_time, cookie->LastUpdateDate());
1081 }
1082
TEST(CanonicalCookieTest,IsEquivalent)1083 TEST(CanonicalCookieTest, IsEquivalent) {
1084 GURL url("https://www.example.com/");
1085 std::string cookie_name = "A";
1086 std::string cookie_value = "2EDA-EF";
1087 std::string cookie_domain = ".www.example.com";
1088 std::string cookie_path = "/path";
1089 base::Time creation_time = base::Time::Now();
1090 base::Time expiration_time = creation_time + base::Days(2);
1091 base::Time update_time = creation_time + base::Days(1);
1092 bool secure = false;
1093 bool httponly = false;
1094 CookieSameSite same_site = CookieSameSite::NO_RESTRICTION;
1095 bool same_party = false;
1096
1097 // Test that a cookie is equivalent to itself.
1098 auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1099 cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1100 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1101 COOKIE_PRIORITY_MEDIUM, same_party);
1102 EXPECT_TRUE(cookie->IsEquivalent(*cookie));
1103 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*cookie));
1104
1105 // Test that two identical cookies are equivalent.
1106 auto other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1107 cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1108 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1109 COOKIE_PRIORITY_MEDIUM, same_party);
1110 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1111 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1112
1113 // Tests that use different variations of attribute values that
1114 // DON'T affect cookie equivalence.
1115 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1116 cookie_name, "2", cookie_domain, cookie_path, creation_time,
1117 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1118 COOKIE_PRIORITY_HIGH, same_party);
1119 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1120 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1121 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1122
1123 base::Time other_creation_time = creation_time + base::Minutes(2);
1124 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1125 cookie_name, "2", cookie_domain, cookie_path, other_creation_time,
1126 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1127 COOKIE_PRIORITY_MEDIUM, same_party);
1128 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1129 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1130 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1131
1132 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1133 cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1134 expiration_time, base::Time(), update_time, true, httponly, same_site,
1135 COOKIE_PRIORITY_LOW, same_party);
1136 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1137 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1138 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1139
1140 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1141 cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1142 expiration_time, base::Time(), update_time, secure, true, same_site,
1143 COOKIE_PRIORITY_LOW, same_party);
1144 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1145 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1146 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1147
1148 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1149 cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1150 expiration_time, base::Time(), update_time, secure, httponly,
1151 CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW, same_party);
1152 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1153 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1154 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1155
1156 // Test the effect of a differing last_update_time on equivalency.
1157 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1158 cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1159 expiration_time, base::Time(), base::Time(), secure, httponly, same_site,
1160 COOKIE_PRIORITY_LOW, same_party);
1161 EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1162 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1163 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1164 EXPECT_FALSE(cookie->HasEquivalentDataMembers(*other_cookie));
1165
1166 // Cookies whose names mismatch are not equivalent.
1167 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1168 "B", cookie_value, cookie_domain, cookie_path, creation_time,
1169 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1170 COOKIE_PRIORITY_MEDIUM, same_party);
1171 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1172 EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1173 EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1174
1175 // A domain cookie at 'www.example.com' is not equivalent to a host cookie
1176 // at the same domain. These are, however, equivalent according to the laxer
1177 // rules of 'IsEquivalentForSecureCookieMatching'.
1178 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1179 cookie_name, cookie_value, "www.example.com", cookie_path, creation_time,
1180 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1181 COOKIE_PRIORITY_MEDIUM, same_party);
1182 EXPECT_TRUE(cookie->IsDomainCookie());
1183 EXPECT_FALSE(other_cookie->IsDomainCookie());
1184 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1185 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1186 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1187
1188 // Likewise, a cookie on 'example.com' is not equivalent to a cookie on
1189 // 'www.example.com', but they are equivalent for secure cookie matching.
1190 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1191 cookie_name, cookie_value, ".example.com", cookie_path, creation_time,
1192 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1193 COOKIE_PRIORITY_MEDIUM, same_party);
1194 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1195 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1196 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1197
1198 // Paths are a bit more complicated. 'IsEquivalent' requires an exact path
1199 // match, while secure cookie matching uses a more relaxed 'IsOnPath' check.
1200 // That is, |cookie| set on '/path' is not equivalent in either way to
1201 // |other_cookie| set on '/test' or '/path/subpath'. It is, however,
1202 // equivalent for secure cookie matching to |other_cookie| set on '/'.
1203 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1204 cookie_name, cookie_value, cookie_domain, "/test", creation_time,
1205 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1206 COOKIE_PRIORITY_MEDIUM, same_party);
1207 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1208 EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1209 EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1210
1211 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1212 cookie_name, cookie_value, cookie_domain, cookie_path + "/subpath",
1213 creation_time, expiration_time, base::Time(), update_time, secure,
1214 httponly, same_site, COOKIE_PRIORITY_MEDIUM, same_party);
1215 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1216 // The path comparison is asymmetric
1217 EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1218 EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1219
1220 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1221 cookie_name, cookie_value, cookie_domain, "/", creation_time,
1222 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1223 COOKIE_PRIORITY_MEDIUM, same_party);
1224 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1225 EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1226 EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1227
1228 // Partitioned cookies are not equivalent to unpartitioned cookies.
1229 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1230 cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1231 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1232 COOKIE_PRIORITY_MEDIUM, same_party,
1233 CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")));
1234 EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1235 EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1236
1237 // Partitioned cookies are equal if they have the same partition key.
1238 auto paritioned_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1239 cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1240 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1241 COOKIE_PRIORITY_MEDIUM, same_party,
1242 CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")));
1243 EXPECT_TRUE(paritioned_cookie->IsEquivalent(*other_cookie));
1244 EXPECT_TRUE(
1245 paritioned_cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1246
1247 // Partitioned cookies with different partition keys are not equal
1248 other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1249 cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1250 expiration_time, base::Time(), update_time, secure, httponly, same_site,
1251 COOKIE_PRIORITY_MEDIUM, same_party,
1252 CookiePartitionKey::FromURLForTesting(GURL("https://bar.com")));
1253 EXPECT_FALSE(paritioned_cookie->IsEquivalent(*other_cookie));
1254 EXPECT_FALSE(
1255 paritioned_cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1256 }
1257
TEST(CanonicalCookieTest,IsEquivalentForSecureCookieMatching)1258 TEST(CanonicalCookieTest, IsEquivalentForSecureCookieMatching) {
1259 struct {
1260 struct {
1261 const char* name;
1262 const char* domain;
1263 const char* path;
1264 absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt;
1265 } cookie, secure_cookie;
1266 bool equivalent;
1267 bool is_symmetric; // Whether the reverse comparison has the same result.
1268 } kTests[] = {
1269 // Equivalent to itself
1270 {{"A", "a.foo.com", "/"}, {"A", "a.foo.com", "/"}, true, true},
1271 {{"A", ".a.foo.com", "/"}, {"A", ".a.foo.com", "/"}, true, true},
1272 // Names are different
1273 {{"A", "a.foo.com", "/"}, {"B", "a.foo.com", "/"}, false, true},
1274 // Host cookie and domain cookie with same hostname match
1275 {{"A", "a.foo.com", "/"}, {"A", ".a.foo.com", "/"}, true, true},
1276 // Subdomains and superdomains match
1277 {{"A", "a.foo.com", "/"}, {"A", ".foo.com", "/"}, true, true},
1278 {{"A", ".a.foo.com", "/"}, {"A", ".foo.com", "/"}, true, true},
1279 {{"A", "a.foo.com", "/"}, {"A", "foo.com", "/"}, true, true},
1280 {{"A", ".a.foo.com", "/"}, {"A", "foo.com", "/"}, true, true},
1281 // Different domains don't match
1282 {{"A", "a.foo.com", "/"}, {"A", "b.foo.com", "/"}, false, true},
1283 {{"A", "a.foo.com", "/"}, {"A", "ba.foo.com", "/"}, false, true},
1284 // Path attribute matches if it is a subdomain, but not vice versa.
1285 {{"A", "a.foo.com", "/sub"}, {"A", "a.foo.com", "/"}, true, false},
1286 // Different paths don't match
1287 {{"A", "a.foo.com", "/sub"}, {"A", "a.foo.com", "/other"}, false, true},
1288 {{"A", "a.foo.com", "/a/b"}, {"A", "a.foo.com", "/a/c"}, false, true},
1289 // Partitioned cookies are not equivalent to unpartitioned cookies.
1290 {{"A", ".a.foo.com", "/"},
1291 {"A", ".a.foo.com", "/",
1292 CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1293 false,
1294 true},
1295 // Partitioned cookies are equivalent if they have the same partition key.
1296 {{"A", "a.foo.com", "/",
1297 CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1298 {"A", "a.foo.com", "/",
1299 CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1300 true,
1301 true},
1302 // Partitioned cookies are *not* equivalent if they have the different
1303 // partition keys.
1304 {{"A", "a.foo.com", "/",
1305 CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1306 {"A", "a.foo.com", "/",
1307 CookiePartitionKey::FromURLForTesting(GURL("https://baz.com"))},
1308 false,
1309 true},
1310 };
1311
1312 for (auto test : kTests) {
1313 auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1314 test.cookie.name, "value1", test.cookie.domain, test.cookie.path,
1315 base::Time(), base::Time(), base::Time(), base::Time(),
1316 false /* secure */, false /* httponly */, CookieSameSite::LAX_MODE,
1317 COOKIE_PRIORITY_MEDIUM, false /* sameparty */,
1318 test.cookie.cookie_partition_key);
1319 auto secure_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1320 test.secure_cookie.name, "value2", test.secure_cookie.domain,
1321 test.secure_cookie.path, base::Time(), base::Time(), base::Time(),
1322 base::Time(), true /* secure */, false /* httponly */,
1323 CookieSameSite::LAX_MODE, COOKIE_PRIORITY_MEDIUM, false /* sameparty */,
1324 test.secure_cookie.cookie_partition_key);
1325
1326 EXPECT_EQ(test.equivalent,
1327 cookie->IsEquivalentForSecureCookieMatching(*secure_cookie));
1328 EXPECT_EQ(test.equivalent == test.is_symmetric,
1329 secure_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1330 }
1331 }
1332
TEST(CanonicalCookieTest,IsDomainMatch)1333 TEST(CanonicalCookieTest, IsDomainMatch) {
1334 GURL url("http://www.example.com/test/foo.html");
1335 base::Time creation_time = base::Time::Now();
1336 absl::optional<base::Time> server_time = absl::nullopt;
1337
1338 std::unique_ptr<CanonicalCookie> cookie(
1339 CanonicalCookie::Create(url, "A=2", creation_time, server_time,
1340 absl::nullopt /* cookie_partition_key */));
1341 EXPECT_TRUE(cookie->IsHostCookie());
1342 EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1343 EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1344 EXPECT_FALSE(cookie->IsDomainMatch("foo.www.example.com"));
1345 EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
1346 EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
1347
1348 cookie = CanonicalCookie::Create(url, "A=2; Domain=www.example.com",
1349 creation_time, server_time,
1350 absl::nullopt /* cookie_partition_key */);
1351 EXPECT_TRUE(cookie->IsDomainCookie());
1352 EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1353 EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1354 EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
1355 EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
1356 EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
1357
1358 cookie = CanonicalCookie::Create(url, "A=2; Domain=.www.example.com",
1359 creation_time, server_time,
1360 absl::nullopt /* cookie_partition_key */);
1361 EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1362 EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1363 EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
1364 EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
1365 EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
1366 }
1367
TEST(CanonicalCookieTest,IsOnPath)1368 TEST(CanonicalCookieTest, IsOnPath) {
1369 base::Time creation_time = base::Time::Now();
1370 absl::optional<base::Time> server_time = absl::nullopt;
1371
1372 std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
1373 GURL("http://www.example.com"), "A=2", creation_time, server_time,
1374 absl::nullopt /* cookie_partition_key */));
1375 EXPECT_TRUE(cookie->IsOnPath("/"));
1376 EXPECT_TRUE(cookie->IsOnPath("/test"));
1377 EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
1378
1379 // Test the empty string edge case.
1380 EXPECT_FALSE(cookie->IsOnPath(std::string()));
1381
1382 cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
1383 "A=2", creation_time, server_time,
1384 absl::nullopt /* cookie_partition_key */);
1385 EXPECT_FALSE(cookie->IsOnPath("/"));
1386 EXPECT_TRUE(cookie->IsOnPath("/test"));
1387 EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
1388 EXPECT_TRUE(cookie->IsOnPath("/test/sample/bar.html"));
1389 }
1390
TEST(CanonicalCookieTest,GetEffectiveSameSite)1391 TEST(CanonicalCookieTest, GetEffectiveSameSite) {
1392 struct {
1393 CookieSameSite same_site;
1394 CookieEffectiveSameSite expected_effective_same_site;
1395 // nullopt for following members indicates same effective SameSite result
1396 // for all possible values.
1397 absl::optional<CookieAccessSemantics> access_semantics = absl::nullopt;
1398 absl::optional<bool> is_cookie_recent = absl::nullopt;
1399 } kTestCases[] = {
1400 // Explicitly specified SameSite always has the same effective SameSite
1401 // regardless of the access semantics.
1402 {CookieSameSite::NO_RESTRICTION, CookieEffectiveSameSite::NO_RESTRICTION},
1403 {CookieSameSite::LAX_MODE, CookieEffectiveSameSite::LAX_MODE},
1404 {CookieSameSite::STRICT_MODE, CookieEffectiveSameSite::STRICT_MODE},
1405 {CookieSameSite::NO_RESTRICTION, CookieEffectiveSameSite::NO_RESTRICTION},
1406
1407 // UNSPECIFIED always maps to NO_RESTRICTION if LEGACY access semantics.
1408 {CookieSameSite::UNSPECIFIED, CookieEffectiveSameSite::NO_RESTRICTION,
1409 CookieAccessSemantics::LEGACY},
1410
1411 // UNSPECIFIED with non-LEGACY access semantics depends on whether cookie
1412 // is recently created.
1413 {CookieSameSite::UNSPECIFIED,
1414 CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1415 CookieAccessSemantics::NONLEGACY, true},
1416 {CookieSameSite::UNSPECIFIED,
1417 CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1418 CookieAccessSemantics::UNKNOWN, true},
1419 {CookieSameSite::UNSPECIFIED, CookieEffectiveSameSite::LAX_MODE,
1420 CookieAccessSemantics::NONLEGACY, false},
1421 {CookieSameSite::UNSPECIFIED, CookieEffectiveSameSite::LAX_MODE,
1422 CookieAccessSemantics::UNKNOWN, false},
1423 };
1424
1425 for (const auto& test : kTestCases) {
1426 std::vector<std::unique_ptr<CanonicalCookie>> cookies;
1427
1428 base::Time now = base::Time::Now();
1429 base::Time recent_creation_time = now - (kLaxAllowUnsafeMaxAge / 4);
1430 base::Time not_recent_creation_time = now - (kLaxAllowUnsafeMaxAge * 4);
1431 base::Time expiry_time = now + (kLaxAllowUnsafeMaxAge / 4);
1432
1433 if (!test.is_cookie_recent.has_value() || *test.is_cookie_recent) {
1434 // Recent session cookie.
1435 cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1436 "A", "2", "example.test", "/", recent_creation_time, base::Time(),
1437 base::Time(), base::Time(), true /* secure */, false /* httponly */,
1438 test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1439 // Recent persistent cookie.
1440 cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1441 "A", "2", "example.test", "/", recent_creation_time, expiry_time,
1442 base::Time(), base::Time(), true /* secure */, false /* httponly */,
1443 test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1444 }
1445 if (!test.is_cookie_recent.has_value() || !(*test.is_cookie_recent)) {
1446 // Not-recent session cookie.
1447 cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1448 "A", "2", "example.test", "/", not_recent_creation_time, base::Time(),
1449 base::Time(), base::Time(), true /* secure */, false /* httponly */,
1450 test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1451 // Not-recent persistent cookie.
1452 cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1453 "A", "2", "example.test", "/", not_recent_creation_time, expiry_time,
1454 base::Time(), base::Time(), true /* secure */, false /* httponly */,
1455 test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1456 }
1457
1458 std::vector<CookieAccessSemantics> access_semantics = {
1459 CookieAccessSemantics::UNKNOWN, CookieAccessSemantics::LEGACY,
1460 CookieAccessSemantics::NONLEGACY};
1461 if (test.access_semantics.has_value())
1462 access_semantics = {*test.access_semantics};
1463
1464 for (const auto& cookie : cookies) {
1465 for (const auto semantics : access_semantics) {
1466 EXPECT_EQ(test.expected_effective_same_site,
1467 cookie->GetEffectiveSameSiteForTesting(semantics));
1468 }
1469 }
1470 }
1471 }
1472
TEST(CanonicalCookieTest,IncludeForRequestURL)1473 TEST(CanonicalCookieTest, IncludeForRequestURL) {
1474 GURL url("http://www.example.com");
1475 base::Time creation_time = base::Time::Now();
1476 CookieOptions options = CookieOptions::MakeAllInclusive();
1477 absl::optional<base::Time> server_time = absl::nullopt;
1478
1479 std::unique_ptr<CanonicalCookie> cookie(
1480 CanonicalCookie::Create(url, "A=2", creation_time, server_time,
1481 absl::nullopt /* cookie_partition_key */));
1482 EXPECT_TRUE(cookie
1483 ->IncludeForRequestURL(
1484 url, options,
1485 CookieAccessParams{
1486 net::CookieAccessSemantics::UNKNOWN,
1487 /*delegate_treats_url_as_trustworthy=*/false,
1488 CookieSamePartyStatus::kNoSamePartyEnforcement})
1489 .status.IsInclude());
1490 EXPECT_TRUE(cookie
1491 ->IncludeForRequestURL(
1492 GURL("http://www.example.com/foo/bar"), options,
1493 CookieAccessParams{
1494 net::CookieAccessSemantics::UNKNOWN,
1495 /*delegate_treats_url_as_trustworthy=*/false,
1496 CookieSamePartyStatus::kNoSamePartyEnforcement})
1497 .status.IsInclude());
1498 EXPECT_TRUE(cookie
1499 ->IncludeForRequestURL(
1500 GURL("https://www.example.com/foo/bar"), options,
1501 CookieAccessParams{
1502 net::CookieAccessSemantics::UNKNOWN,
1503 /*delegate_treats_url_as_trustworthy=*/false,
1504 CookieSamePartyStatus::kNoSamePartyEnforcement})
1505 .status.IsInclude());
1506 EXPECT_TRUE(cookie
1507 ->IncludeForRequestURL(
1508 GURL("https://sub.example.com"), options,
1509 CookieAccessParams{
1510 net::CookieAccessSemantics::UNKNOWN,
1511 /*delegate_treats_url_as_trustworthy=*/false,
1512 CookieSamePartyStatus::kNoSamePartyEnforcement})
1513 .status.HasExactlyExclusionReasonsForTesting(
1514 {CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH}));
1515 EXPECT_TRUE(cookie
1516 ->IncludeForRequestURL(
1517 GURL("https://sub.www.example.com"), options,
1518 CookieAccessParams{
1519 net::CookieAccessSemantics::UNKNOWN,
1520 /*delegate_treats_url_as_trustworthy=*/false,
1521 CookieSamePartyStatus::kNoSamePartyEnforcement})
1522 .status.HasExactlyExclusionReasonsForTesting(
1523 {CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH}));
1524
1525 // Test that cookie with a cookie path that does not match the url path are
1526 // not included.
1527 cookie = CanonicalCookie::Create(url, "A=2; Path=/foo/bar", creation_time,
1528 server_time,
1529 absl::nullopt /* cookie_partition_key */);
1530 EXPECT_TRUE(cookie
1531 ->IncludeForRequestURL(
1532 url, options,
1533 CookieAccessParams{
1534 net::CookieAccessSemantics::UNKNOWN,
1535 /*delegate_treats_url_as_trustworthy=*/false,
1536 CookieSamePartyStatus::kNoSamePartyEnforcement})
1537 .status.HasExactlyExclusionReasonsForTesting(
1538 {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
1539 EXPECT_TRUE(cookie
1540 ->IncludeForRequestURL(
1541 GURL("http://www.example.com/foo/bar/index.html"),
1542 options,
1543 CookieAccessParams{
1544 net::CookieAccessSemantics::UNKNOWN,
1545 /*delegate_treats_url_as_trustworthy=*/false,
1546 CookieSamePartyStatus::kNoSamePartyEnforcement})
1547 .status.IsInclude());
1548
1549 // Test that a secure cookie is not included for a non secure URL.
1550 GURL secure_url("https://www.example.com");
1551 cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
1552 server_time,
1553 absl::nullopt /* cookie_partition_key */);
1554 EXPECT_TRUE(cookie->IsSecure());
1555 EXPECT_TRUE(cookie
1556 ->IncludeForRequestURL(
1557 secure_url, options,
1558 CookieAccessParams{
1559 net::CookieAccessSemantics::UNKNOWN,
1560 /*delegate_treats_url_as_trustworthy=*/false,
1561 CookieSamePartyStatus::kNoSamePartyEnforcement})
1562 .status.IsInclude());
1563 EXPECT_TRUE(cookie
1564 ->IncludeForRequestURL(
1565 url, options,
1566 CookieAccessParams{
1567 net::CookieAccessSemantics::UNKNOWN,
1568 /*delegate_treats_url_as_trustworthy=*/false,
1569 CookieSamePartyStatus::kNoSamePartyEnforcement})
1570 .status.HasExactlyExclusionReasonsForTesting(
1571 {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
1572
1573 // Test that a delegate can make an exception, however, and ask for a
1574 // non-secure URL to be treated as trustworthy... with a warning.
1575 cookie =
1576 CanonicalCookie::Create(url, "A=2; Secure", creation_time, server_time,
1577 absl::nullopt /* cookie_partition_key */);
1578 ASSERT_TRUE(cookie);
1579 EXPECT_TRUE(cookie->IsSecure());
1580 CookieAccessResult result = cookie->IncludeForRequestURL(
1581 url, options,
1582 CookieAccessParams{net::CookieAccessSemantics::UNKNOWN,
1583 /*delegate_treats_url_as_trustworthy=*/true,
1584 CookieSamePartyStatus::kNoSamePartyEnforcement});
1585 EXPECT_TRUE(result.status.IsInclude());
1586 EXPECT_TRUE(result.status.HasWarningReason(
1587 CookieInclusionStatus::WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC));
1588
1589 // The same happens for localhost even w/o delegate intervention.
1590 GURL localhost_url("http://localhost/");
1591 cookie = CanonicalCookie::Create(localhost_url, "A=2; Secure", creation_time,
1592 server_time,
1593 absl::nullopt /* cookie_partition_key */);
1594 ASSERT_TRUE(cookie);
1595 EXPECT_TRUE(cookie->IsSecure());
1596 result = cookie->IncludeForRequestURL(
1597 localhost_url, options,
1598 CookieAccessParams{net::CookieAccessSemantics::UNKNOWN,
1599 /*delegate_treats_url_as_trustworthy=*/false,
1600 CookieSamePartyStatus::kNoSamePartyEnforcement});
1601 EXPECT_TRUE(result.status.IsInclude());
1602 EXPECT_TRUE(result.status.HasWarningReason(
1603 CookieInclusionStatus::WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC));
1604
1605 // An unneeded exception doesn't add a warning, however.
1606 cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
1607 server_time,
1608 absl::nullopt /* cookie_partition_key */);
1609 ASSERT_TRUE(cookie);
1610 EXPECT_TRUE(cookie->IsSecure());
1611 result = cookie->IncludeForRequestURL(
1612 secure_url, options,
1613 CookieAccessParams{net::CookieAccessSemantics::UNKNOWN,
1614 /*delegate_treats_url_as_trustworthy=*/true,
1615 CookieSamePartyStatus::kNoSamePartyEnforcement});
1616 EXPECT_TRUE(result.status.IsInclude());
1617 EXPECT_FALSE(result.status.ShouldWarn());
1618
1619 //
1620
1621 // Test that http only cookies are only included if the include httponly flag
1622 // is set on the cookie options.
1623 options.set_include_httponly();
1624 cookie =
1625 CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
1626 absl::nullopt /* cookie_partition_key */);
1627 EXPECT_TRUE(cookie->IsHttpOnly());
1628 EXPECT_TRUE(cookie
1629 ->IncludeForRequestURL(
1630 url, options,
1631 CookieAccessParams{
1632 net::CookieAccessSemantics::UNKNOWN,
1633 /*delegate_treats_url_as_trustworthy=*/false,
1634 CookieSamePartyStatus::kNoSamePartyEnforcement})
1635 .status.IsInclude());
1636 options.set_exclude_httponly();
1637 EXPECT_TRUE(cookie
1638 ->IncludeForRequestURL(
1639 url, options,
1640 CookieAccessParams{
1641 net::CookieAccessSemantics::UNKNOWN,
1642 /*delegate_treats_url_as_trustworthy=*/false,
1643 CookieSamePartyStatus::kNoSamePartyEnforcement})
1644 .status.HasExactlyExclusionReasonsForTesting(
1645 {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
1646 }
1647
1648 struct IncludeForRequestURLTestCase {
1649 std::string cookie_line;
1650 CookieSameSite expected_samesite;
1651 CookieEffectiveSameSite expected_effective_samesite;
1652 CookieOptions::SameSiteCookieContext request_options_samesite_context;
1653 CookieInclusionStatus expected_inclusion_status;
1654 base::TimeDelta creation_time_delta = base::TimeDelta();
1655 };
1656
VerifyIncludeForRequestURLTestCases(CookieAccessSemantics access_semantics,std::vector<IncludeForRequestURLTestCase> test_cases)1657 void VerifyIncludeForRequestURLTestCases(
1658 CookieAccessSemantics access_semantics,
1659 std::vector<IncludeForRequestURLTestCase> test_cases) {
1660 GURL url("https://example.test");
1661
1662 for (const auto& test : test_cases) {
1663 base::Time creation_time = base::Time::Now() - test.creation_time_delta;
1664 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
1665 url, test.cookie_line, creation_time, absl::nullopt /* server_time */,
1666 absl::nullopt /* cookie_partition_key */);
1667 EXPECT_EQ(test.expected_samesite, cookie->SameSite());
1668
1669 CookieOptions request_options;
1670 request_options.set_same_site_cookie_context(
1671 test.request_options_samesite_context);
1672
1673 EXPECT_THAT(
1674 cookie->IncludeForRequestURL(
1675 url, request_options,
1676 CookieAccessParams{access_semantics,
1677 /*delegate_treats_url_as_trustworthy=*/false,
1678 CookieSamePartyStatus::kNoSamePartyEnforcement}),
1679 MatchesCookieAccessResult(test.expected_inclusion_status,
1680 test.expected_effective_samesite,
1681 access_semantics, true))
1682 << cookie->Name() << "=" << cookie->Value();
1683 }
1684 }
1685
TEST(CanonicalCookieTest,IncludeForRequestURLSameSite)1686 TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
1687 const base::TimeDelta kLongAge = kLaxAllowUnsafeMaxAge * 4;
1688 const base::TimeDelta kShortAge = kLaxAllowUnsafeMaxAge / 4;
1689
1690 using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
1691
1692 // Test cases that are the same regardless of feature status or access
1693 // semantics. For Schemeful Same-Site this means that the context downgrade is
1694 // a no-op (such as for NO_RESTRICTION cookies) or that there is no downgrade:
1695 std::vector<IncludeForRequestURLTestCase> common_test_cases = {
1696 // Strict cookies:
1697 {"Common=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
1698 CookieEffectiveSameSite::STRICT_MODE,
1699 SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1700 CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
1701 {"Common=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
1702 CookieEffectiveSameSite::STRICT_MODE,
1703 SameSiteCookieContext(
1704 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1705 CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
1706 {"Common=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
1707 CookieEffectiveSameSite::STRICT_MODE,
1708 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1709 CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
1710 {"Common=4;SameSite=Strict", CookieSameSite::STRICT_MODE,
1711 CookieEffectiveSameSite::STRICT_MODE,
1712 SameSiteCookieContext(
1713 SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1714 CookieInclusionStatus()},
1715 // Lax cookies:
1716 {"Common=5;SameSite=Lax", CookieSameSite::LAX_MODE,
1717 CookieEffectiveSameSite::LAX_MODE,
1718 SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1719 CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
1720 {"Common=6;SameSite=Lax", CookieSameSite::LAX_MODE,
1721 CookieEffectiveSameSite::LAX_MODE,
1722 SameSiteCookieContext(
1723 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1724 CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
1725 {"Common=7;SameSite=Lax", CookieSameSite::LAX_MODE,
1726 CookieEffectiveSameSite::LAX_MODE,
1727 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1728 CookieInclusionStatus()},
1729 {"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
1730 CookieEffectiveSameSite::LAX_MODE,
1731 SameSiteCookieContext(
1732 SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1733 CookieInclusionStatus()},
1734 // Lax cookies with downgrade:
1735 {"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
1736 CookieEffectiveSameSite::LAX_MODE,
1737 SameSiteCookieContext(
1738 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1739 SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1740 CookieInclusionStatus()},
1741 // None and Secure cookies:
1742 {"Common=10;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1743 CookieEffectiveSameSite::NO_RESTRICTION,
1744 SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1745 CookieInclusionStatus()},
1746 {"Common=11;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1747 CookieEffectiveSameSite::NO_RESTRICTION,
1748 SameSiteCookieContext(
1749 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1750 CookieInclusionStatus()},
1751 {"Common=12;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1752 CookieEffectiveSameSite::NO_RESTRICTION,
1753 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1754 CookieInclusionStatus()},
1755 {"Common=13;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1756 CookieEffectiveSameSite::NO_RESTRICTION,
1757 SameSiteCookieContext(
1758 SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1759 CookieInclusionStatus()},
1760 // Because NO_RESTRICTION cookies are always sent, the schemeful context
1761 // downgrades shouldn't matter.
1762 {"Common=14;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1763 CookieEffectiveSameSite::NO_RESTRICTION,
1764 SameSiteCookieContext(
1765 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1766 SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1767 CookieInclusionStatus()},
1768 {"Common=15;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1769 CookieEffectiveSameSite::NO_RESTRICTION,
1770 SameSiteCookieContext(
1771 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1772 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1773 CookieInclusionStatus()},
1774 {"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1775 CookieEffectiveSameSite::NO_RESTRICTION,
1776 SameSiteCookieContext(
1777 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1778 SameSiteCookieContext::ContextType::CROSS_SITE),
1779 CookieInclusionStatus()},
1780 {"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1781 CookieEffectiveSameSite::NO_RESTRICTION,
1782 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
1783 SameSiteCookieContext::ContextType::CROSS_SITE),
1784 CookieInclusionStatus()},
1785 {"Common=18;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1786 CookieEffectiveSameSite::NO_RESTRICTION,
1787 SameSiteCookieContext(
1788 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
1789 SameSiteCookieContext::ContextType::CROSS_SITE),
1790 CookieInclusionStatus()},
1791 };
1792
1793 // Test cases where the unspecified-SameSite cookie defaults to SameSite=None
1794 // due to LEGACY access semantics):
1795 std::vector<IncludeForRequestURLTestCase> default_none_test_cases = {
1796 {"DefaultNone=1", CookieSameSite::UNSPECIFIED,
1797 CookieEffectiveSameSite::NO_RESTRICTION,
1798 SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1799 CookieInclusionStatus::MakeFromReasonsForTesting(
1800 std::vector<CookieInclusionStatus::ExclusionReason>(),
1801 {CookieInclusionStatus::
1802 WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT})},
1803 {"DefaultNone=2", CookieSameSite::UNSPECIFIED,
1804 CookieEffectiveSameSite::NO_RESTRICTION,
1805 SameSiteCookieContext(
1806 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1807 CookieInclusionStatus::MakeFromReasonsForTesting(
1808 std::vector<CookieInclusionStatus::ExclusionReason>(),
1809 {CookieInclusionStatus::
1810 WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT})},
1811
1812 {"DefaultNone=3", CookieSameSite::UNSPECIFIED,
1813 CookieEffectiveSameSite::NO_RESTRICTION,
1814 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1815 CookieInclusionStatus()},
1816 {"DefaultNone=4", CookieSameSite::UNSPECIFIED,
1817 CookieEffectiveSameSite::NO_RESTRICTION,
1818 SameSiteCookieContext(
1819 SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1820 CookieInclusionStatus()}};
1821
1822 // Test cases where the unspecified-SameSite cookie defaults to SameSite=Lax:
1823 std::vector<IncludeForRequestURLTestCase> default_lax_test_cases = {
1824 // Unspecified recently-created cookies (with SameSite-by-default):
1825 {"DefaultLax=1", CookieSameSite::UNSPECIFIED,
1826 CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1827 SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1828 CookieInclusionStatus(
1829 CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
1830 CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
1831 kShortAge},
1832 {"DefaultLax=2", CookieSameSite::UNSPECIFIED,
1833 CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1834 SameSiteCookieContext(
1835 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1836 CookieInclusionStatus::MakeFromReasonsForTesting(
1837 std::vector<CookieInclusionStatus::ExclusionReason>(),
1838 {CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE}),
1839 kShortAge},
1840 {"DefaultLax=3", CookieSameSite::UNSPECIFIED,
1841 CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1842 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1843 CookieInclusionStatus(), kShortAge},
1844 {"DefaultLax=4", CookieSameSite::UNSPECIFIED,
1845 CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1846 SameSiteCookieContext(
1847 SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1848 CookieInclusionStatus(), kShortAge},
1849 // Unspecified not-recently-created cookies (with SameSite-by-default):
1850 {"DefaultLax=5", CookieSameSite::UNSPECIFIED,
1851 CookieEffectiveSameSite::LAX_MODE,
1852 SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1853 CookieInclusionStatus(
1854 CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
1855 CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
1856 kLongAge},
1857 {"DefaultLax=6", CookieSameSite::UNSPECIFIED,
1858 CookieEffectiveSameSite::LAX_MODE,
1859 SameSiteCookieContext(
1860 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1861 CookieInclusionStatus(
1862 CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
1863 CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
1864 kLongAge},
1865 {"DefaultLax=7", CookieSameSite::UNSPECIFIED,
1866 CookieEffectiveSameSite::LAX_MODE,
1867 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1868 CookieInclusionStatus(), kLongAge},
1869 {"DefaultLax=8", CookieSameSite::UNSPECIFIED,
1870 CookieEffectiveSameSite::LAX_MODE,
1871 SameSiteCookieContext(
1872 SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1873 CookieInclusionStatus(), kLongAge},
1874 };
1875
1876 // Test cases that require LEGACY semantics or Schemeful Same-Site to be
1877 // disabled.
1878 std::vector<IncludeForRequestURLTestCase> schemeful_disabled_test_cases = {
1879 {"LEGACY_Schemeful=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
1880 CookieEffectiveSameSite::STRICT_MODE,
1881 SameSiteCookieContext(
1882 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1883 SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1884 CookieInclusionStatus::MakeFromReasonsForTesting(
1885 std::vector<CookieInclusionStatus::ExclusionReason>(),
1886 {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
1887 {"LEGACY_Schemeful=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
1888 CookieEffectiveSameSite::STRICT_MODE,
1889 SameSiteCookieContext(
1890 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1891 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1892 CookieInclusionStatus::MakeFromReasonsForTesting(
1893 std::vector<CookieInclusionStatus::ExclusionReason>(),
1894 {CookieInclusionStatus::
1895 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1896 {"LEGACY_Schemeful=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
1897 CookieEffectiveSameSite::STRICT_MODE,
1898 SameSiteCookieContext(
1899 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1900 SameSiteCookieContext::ContextType::CROSS_SITE),
1901 CookieInclusionStatus::MakeFromReasonsForTesting(
1902 std::vector<CookieInclusionStatus::ExclusionReason>(),
1903 {CookieInclusionStatus::
1904 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1905 {"LEGACY_Schemeful=4;SameSite=Lax", CookieSameSite::LAX_MODE,
1906 CookieEffectiveSameSite::LAX_MODE,
1907 SameSiteCookieContext(
1908 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1909 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1910 CookieInclusionStatus::MakeFromReasonsForTesting(
1911 std::vector<CookieInclusionStatus::ExclusionReason>(),
1912 {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1913 {"LEGACY_Schemeful=5;SameSite=Lax", CookieSameSite::LAX_MODE,
1914 CookieEffectiveSameSite::LAX_MODE,
1915 SameSiteCookieContext(
1916 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1917 SameSiteCookieContext::ContextType::CROSS_SITE),
1918 CookieInclusionStatus::MakeFromReasonsForTesting(
1919 std::vector<CookieInclusionStatus::ExclusionReason>(),
1920 {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1921 {"LEGACY_Schemeful=6;SameSite=Lax", CookieSameSite::LAX_MODE,
1922 CookieEffectiveSameSite::LAX_MODE,
1923 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
1924 SameSiteCookieContext::ContextType::CROSS_SITE),
1925 CookieInclusionStatus::MakeFromReasonsForTesting(
1926 std::vector<CookieInclusionStatus::ExclusionReason>(),
1927 {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
1928 };
1929
1930 // Test cases that require NONLEGACY or UNKNOWN semantics with Schemeful
1931 // Same-Site enabled
1932 std::vector<IncludeForRequestURLTestCase> schemeful_enabled_test_cases = {
1933 {"NONLEGACY_Schemeful=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
1934 CookieEffectiveSameSite::STRICT_MODE,
1935 SameSiteCookieContext(
1936 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1937 SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1938 CookieInclusionStatus::MakeFromReasonsForTesting(
1939 {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
1940 {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
1941 {"NONLEGACY_Schemeful=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
1942 CookieEffectiveSameSite::STRICT_MODE,
1943 SameSiteCookieContext(
1944 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1945 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1946 CookieInclusionStatus::MakeFromReasonsForTesting(
1947 {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
1948 {CookieInclusionStatus::
1949 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1950 {"NONLEGACY_Schemeful=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
1951 CookieEffectiveSameSite::STRICT_MODE,
1952 SameSiteCookieContext(
1953 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1954 SameSiteCookieContext::ContextType::CROSS_SITE),
1955 CookieInclusionStatus::MakeFromReasonsForTesting(
1956 {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
1957 {CookieInclusionStatus::
1958 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1959 {"NONLEGACY_Schemeful=4;SameSite=Lax", CookieSameSite::LAX_MODE,
1960 CookieEffectiveSameSite::LAX_MODE,
1961 SameSiteCookieContext(
1962 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1963 SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1964 CookieInclusionStatus::MakeFromReasonsForTesting(
1965 {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
1966 {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1967 {"NONLEGACY_Schemeful=5;SameSite=Lax", CookieSameSite::LAX_MODE,
1968 CookieEffectiveSameSite::LAX_MODE,
1969 SameSiteCookieContext(
1970 SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1971 SameSiteCookieContext::ContextType::CROSS_SITE),
1972 CookieInclusionStatus::MakeFromReasonsForTesting(
1973 {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
1974 {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1975 {"NONLEGACY_Schemeful=6;SameSite=Lax", CookieSameSite::LAX_MODE,
1976 CookieEffectiveSameSite::LAX_MODE,
1977 SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
1978 SameSiteCookieContext::ContextType::CROSS_SITE),
1979 CookieInclusionStatus::MakeFromReasonsForTesting(
1980 {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
1981 {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
1982 };
1983
1984 auto SchemefulIndependentCases = [&]() {
1985 // Run the test cases that are independent of Schemeful Same-Site.
1986 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
1987 common_test_cases);
1988 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
1989 default_lax_test_cases);
1990 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
1991 common_test_cases);
1992 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
1993 default_none_test_cases);
1994 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
1995 common_test_cases);
1996 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
1997 default_lax_test_cases);
1998 };
1999
2000 {
2001 // Schemeful Same-Site disabled.
2002 base::test::ScopedFeatureList feature_list;
2003 feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
2004
2005 SchemefulIndependentCases();
2006
2007 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
2008 schemeful_disabled_test_cases);
2009 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
2010 schemeful_disabled_test_cases);
2011 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
2012 schemeful_disabled_test_cases);
2013 }
2014 {
2015 // Schemeful Same-Site enabled.
2016 base::test::ScopedFeatureList feature_list;
2017 feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
2018
2019 SchemefulIndependentCases();
2020
2021 // With LEGACY access the cases should act as if schemeful is disabled, even
2022 // when it's not.
2023 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
2024 schemeful_disabled_test_cases);
2025
2026 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
2027 schemeful_enabled_test_cases);
2028 VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
2029 schemeful_enabled_test_cases);
2030 }
2031 }
2032
2033 // Test that SameSite=None requires Secure.
TEST(CanonicalCookieTest,IncludeCookiesWithoutSameSiteMustBeSecure)2034 TEST(CanonicalCookieTest, IncludeCookiesWithoutSameSiteMustBeSecure) {
2035 GURL url("https://www.example.com");
2036 base::Time creation_time = base::Time::Now();
2037 absl::optional<base::Time> server_time = absl::nullopt;
2038 CookieOptions options;
2039
2040 // Make a SameSite=None, *not* Secure cookie.
2041 std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
2042 url, "A=2; SameSite=None", creation_time, server_time,
2043 absl::nullopt /* cookie_partition_key */);
2044 ASSERT_TRUE(cookie.get());
2045 EXPECT_FALSE(cookie->IsSecure());
2046 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
2047 EXPECT_EQ(CookieEffectiveSameSite::NO_RESTRICTION,
2048 cookie->GetEffectiveSameSiteForTesting());
2049
2050 // UKNOWN semantics results in modern behavior (requiring Secure).
2051 EXPECT_TRUE(cookie
2052 ->IncludeForRequestURL(
2053 url, options,
2054 CookieAccessParams{
2055 CookieAccessSemantics::UNKNOWN,
2056 /*delegate_treats_url_as_trustworthy=*/false,
2057 CookieSamePartyStatus::kNoSamePartyEnforcement})
2058 .status.HasExactlyExclusionReasonsForTesting(
2059 {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE}));
2060
2061 // LEGACY semantics does not require Secure for SameSite=None cookies.
2062 EXPECT_TRUE(cookie
2063 ->IncludeForRequestURL(
2064 url, options,
2065 CookieAccessParams{
2066 CookieAccessSemantics::LEGACY,
2067 /*delegate_treats_url_as_trustworthy=*/false,
2068 CookieSamePartyStatus::kNoSamePartyEnforcement})
2069 .status.IsInclude());
2070
2071 // NONLEGACY semantics results in modern behavior (requiring Secure).
2072 EXPECT_TRUE(cookie
2073 ->IncludeForRequestURL(
2074 url, options,
2075 CookieAccessParams{
2076 CookieAccessSemantics::NONLEGACY,
2077 /*delegate_treats_url_as_trustworthy=*/false,
2078 CookieSamePartyStatus::kNoSamePartyEnforcement})
2079 .status.HasExactlyExclusionReasonsForTesting(
2080 {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE}));
2081 }
2082
TEST(CanonicalCookieTest,IncludeForRequestURLSameParty)2083 TEST(CanonicalCookieTest, IncludeForRequestURLSameParty) {
2084 GURL url("https://www.example.com");
2085 base::Time creation_time = base::Time::Now();
2086 absl::optional<base::Time> server_time = absl::nullopt;
2087 CookieOptions options;
2088
2089 // SameSite is not specified.
2090 std::unique_ptr<CanonicalCookie> cookie_samesite_unspecified =
2091 CanonicalCookie::Create(url, "A=2; SameParty; Secure", creation_time,
2092 server_time,
2093 absl::nullopt /* cookie_partition_key */);
2094 ASSERT_TRUE(cookie_samesite_unspecified.get());
2095 EXPECT_TRUE(cookie_samesite_unspecified->IsSecure());
2096 EXPECT_EQ(CookieSameSite::UNSPECIFIED,
2097 cookie_samesite_unspecified->SameSite());
2098 EXPECT_EQ(CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
2099 cookie_samesite_unspecified->GetEffectiveSameSiteForTesting());
2100 EXPECT_TRUE(cookie_samesite_unspecified->IsSameParty());
2101
2102 // SameSite=None.
2103 std::unique_ptr<CanonicalCookie> cookie_samesite_none =
2104 CanonicalCookie::Create(url, "A=2; SameSite=None; SameParty; Secure",
2105 creation_time, server_time,
2106 absl::nullopt /* cookie_partition_key */);
2107 ASSERT_TRUE(cookie_samesite_none.get());
2108 EXPECT_TRUE(cookie_samesite_none->IsSecure());
2109 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie_samesite_none->SameSite());
2110 EXPECT_EQ(CookieEffectiveSameSite::NO_RESTRICTION,
2111 cookie_samesite_none->GetEffectiveSameSiteForTesting());
2112 EXPECT_TRUE(cookie_samesite_none->IsSameParty());
2113
2114 // SameSite=Lax.
2115 std::unique_ptr<CanonicalCookie> cookie_samesite_lax =
2116 CanonicalCookie::Create(url, "A=2; SameSite=Lax; SameParty; Secure",
2117 creation_time, server_time,
2118 absl::nullopt /* cookie_partition_key */);
2119 ASSERT_TRUE(cookie_samesite_lax.get());
2120 EXPECT_TRUE(cookie_samesite_lax->IsSecure());
2121 EXPECT_EQ(CookieSameSite::LAX_MODE, cookie_samesite_lax->SameSite());
2122 EXPECT_EQ(CookieEffectiveSameSite::LAX_MODE,
2123 cookie_samesite_lax->GetEffectiveSameSiteForTesting());
2124 EXPECT_TRUE(cookie_samesite_lax->IsSameParty());
2125
2126 for (const CanonicalCookie* cookie : {
2127 cookie_samesite_unspecified.get(),
2128 cookie_samesite_none.get(),
2129 cookie_samesite_lax.get(),
2130 }) {
2131 // SameParty cookies that should be excluded result in the appropriate
2132 // exclusion reason, and removes SAMESITE exclusion reasons.
2133 for (CookieAccessSemantics access_semantics : {
2134 CookieAccessSemantics::UNKNOWN,
2135 CookieAccessSemantics::LEGACY,
2136 CookieAccessSemantics::NONLEGACY,
2137 }) {
2138 EXPECT_THAT(cookie->IncludeForRequestURL(
2139 url, options,
2140 CookieAccessParams{
2141 access_semantics,
2142 /*delegate_treats_url_as_trustworthy=*/false,
2143 CookieSamePartyStatus::kEnforceSamePartyExclude}),
2144 MatchesCookieAccessResult(
2145 HasExactlyExclusionReasonsForTesting(
2146 std::vector<CookieInclusionStatus::ExclusionReason>(
2147 {CookieInclusionStatus::
2148 EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT})),
2149 _, _, true))
2150 << "SameSite = " << static_cast<int>(cookie->SameSite())
2151 << ", access_semantics = " << static_cast<int>(access_semantics);
2152 }
2153 }
2154 }
2155
TEST(CanonicalCookieTest,IncludeForRequestURL_SameSiteNone_Metrics)2156 TEST(CanonicalCookieTest, IncludeForRequestURL_SameSiteNone_Metrics) {
2157 using SamePartyContextType = SamePartyContext::Type;
2158
2159 constexpr bool delegate_treats_url_as_trustworthy = false;
2160 const base::Time now = base::Time::Now();
2161 const auto make_cookie = [now](CookieSameSite same_site, bool same_party) {
2162 return CanonicalCookie::CreateUnsafeCookieForTesting(
2163 "A", "1", "www.example.com", "/test", now, base::Time(), base::Time(),
2164 base::Time(), true /* secure */, false /*httponly*/, same_site,
2165 COOKIE_PRIORITY_DEFAULT, same_party);
2166 };
2167 GURL url("https://www.example.com/test");
2168
2169 const std::unique_ptr<CanonicalCookie> same_site_none_cookie =
2170 make_cookie(CookieSameSite::NO_RESTRICTION, false /* same_party */);
2171 const std::unique_ptr<CanonicalCookie> same_party_cookie =
2172 make_cookie(CookieSameSite::NO_RESTRICTION, true /* same_party */);
2173 const std::unique_ptr<CanonicalCookie> same_site_lax_cookie =
2174 make_cookie(CookieSameSite::LAX_MODE, false /* same_party */);
2175 const std::unique_ptr<CanonicalCookie> same_site_strict_cookie =
2176 make_cookie(CookieSameSite::STRICT_MODE, false /* same_party */);
2177 CookieOptions options;
2178 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2179 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
2180 // Same as default, but just to be explicit:
2181 options.set_same_party_context(
2182 SamePartyContext(SamePartyContext::Type::kCrossParty));
2183
2184 // Check that the most restrictive context is recognized and enforced.
2185 EXPECT_THAT(
2186 same_site_none_cookie->IncludeForRequestURL(
2187 url, options,
2188 CookieAccessParams(CookieAccessSemantics::LEGACY,
2189 delegate_treats_url_as_trustworthy,
2190 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2191 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2192 EXPECT_THAT(
2193 same_party_cookie->IncludeForRequestURL(
2194 url, options,
2195 CookieAccessParams(CookieAccessSemantics::LEGACY,
2196 delegate_treats_url_as_trustworthy,
2197 CookieSamePartyStatus::kEnforceSamePartyExclude)),
2198 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2199
2200 // Now tweak the context to allow a SameParty cookie (using the top&resource
2201 // definition) and make sure we get the right warning. (Note: we make the
2202 // "real" same-partyness value match the value computed for the metric, even
2203 // though they would differ unless we changed the real definition.) Then
2204 // check that if we modify the cookie as indicated, the set would be allowed,
2205 // but the next-most-restrictive variation would still be blocked.
2206 options.set_same_party_context(
2207 SamePartyContext(SamePartyContextType::kSameParty));
2208 EXPECT_THAT(
2209 same_site_none_cookie->IncludeForRequestURL(
2210 url, options,
2211 CookieAccessParams(CookieAccessSemantics::LEGACY,
2212 delegate_treats_url_as_trustworthy,
2213 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2214 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2215 EXPECT_THAT(
2216 same_party_cookie->IncludeForRequestURL(
2217 url, options,
2218 CookieAccessParams(CookieAccessSemantics::LEGACY,
2219 delegate_treats_url_as_trustworthy,
2220 CookieSamePartyStatus::kEnforceSamePartyInclude)),
2221 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2222 EXPECT_THAT(
2223 same_site_lax_cookie->IncludeForRequestURL(
2224 url, options,
2225 CookieAccessParams(CookieAccessSemantics::LEGACY,
2226 delegate_treats_url_as_trustworthy,
2227 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2228 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2229
2230 // Next: allow a SameParty cookie (using both definitions).
2231 options.set_same_party_context(SamePartyContext::MakeInclusive());
2232 EXPECT_THAT(
2233 same_site_none_cookie->IncludeForRequestURL(
2234 url, options,
2235 CookieAccessParams(CookieAccessSemantics::LEGACY,
2236 delegate_treats_url_as_trustworthy,
2237 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2238 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2239 EXPECT_THAT(
2240 same_party_cookie->IncludeForRequestURL(
2241 url, options,
2242 CookieAccessParams(CookieAccessSemantics::LEGACY,
2243 delegate_treats_url_as_trustworthy,
2244 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2245 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2246 EXPECT_THAT(
2247 same_site_lax_cookie->IncludeForRequestURL(
2248 url, options,
2249 CookieAccessParams(CookieAccessSemantics::LEGACY,
2250 delegate_treats_url_as_trustworthy,
2251 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2252 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2253
2254 // Next: allow a SameSite=Lax cookie.
2255 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2256 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
2257 EXPECT_THAT(
2258 same_site_none_cookie->IncludeForRequestURL(
2259 url, options,
2260 CookieAccessParams(CookieAccessSemantics::LEGACY,
2261 delegate_treats_url_as_trustworthy,
2262 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2263 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2264 EXPECT_THAT(
2265 same_site_lax_cookie->IncludeForRequestURL(
2266 url, options,
2267 CookieAccessParams(CookieAccessSemantics::LEGACY,
2268 delegate_treats_url_as_trustworthy,
2269 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2270 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2271 EXPECT_THAT(
2272 same_site_strict_cookie->IncludeForRequestURL(
2273 url, options,
2274 CookieAccessParams(CookieAccessSemantics::LEGACY,
2275 delegate_treats_url_as_trustworthy,
2276 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2277 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2278
2279 // Next: allow a SameSite=Strict cookie.
2280 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2281 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
2282 EXPECT_THAT(
2283 same_site_none_cookie->IncludeForRequestURL(
2284 url, options,
2285 CookieAccessParams(CookieAccessSemantics::LEGACY,
2286 delegate_treats_url_as_trustworthy,
2287 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2288 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2289 EXPECT_THAT(
2290 same_site_strict_cookie->IncludeForRequestURL(
2291 url, options,
2292 CookieAccessParams(CookieAccessSemantics::LEGACY,
2293 delegate_treats_url_as_trustworthy,
2294 CookieSamePartyStatus::kNoSamePartyEnforcement)),
2295 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2296 }
2297
2298 // Test that the CookieInclusionStatus warning for inclusion changed by
2299 // cross-site redirect context downgrade is applied correctly.
TEST(CanonicalCookieTest,IncludeForRequestURL_RedirectDowngradeWarning)2300 TEST(CanonicalCookieTest, IncludeForRequestURL_RedirectDowngradeWarning) {
2301 using Context = CookieOptions::SameSiteCookieContext;
2302 using ContextType = Context::ContextType;
2303
2304 Context::ContextMetadata strict_lax_downgrade_metadata,
2305 strict_cross_downgrade_metadata;
2306 strict_lax_downgrade_metadata.cross_site_redirect_downgrade =
2307 Context::ContextMetadata::ContextDowngradeType::kStrictToLax;
2308 strict_cross_downgrade_metadata.cross_site_redirect_downgrade =
2309 Context::ContextMetadata::ContextDowngradeType::kStrictToCross;
2310
2311 // Because there are downgrades we need to set the HTTP method as well, since
2312 // some metrics code expects that. The actual method doesn't matter here.
2313 strict_lax_downgrade_metadata.http_method_bug_1221316 =
2314 Context::ContextMetadata::HttpMethod::kGet;
2315 strict_cross_downgrade_metadata.http_method_bug_1221316 =
2316 Context::ContextMetadata::HttpMethod::kGet;
2317
2318 GURL url("https://www.example.test/test");
2319 GURL insecure_url("http://www.example.test/test");
2320
2321 const struct {
2322 ContextType context_type;
2323 Context::ContextMetadata metadata;
2324 CookieSameSite samesite;
2325 bool expect_cross_site_redirect_warning;
2326 } kTestCases[] = {
2327 // Strict-to-lax downgrade.
2328 {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata,
2329 CookieSameSite::STRICT_MODE, true},
2330 {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata,
2331 CookieSameSite::STRICT_MODE, true},
2332 {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata,
2333 CookieSameSite::LAX_MODE, false},
2334 {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata,
2335 CookieSameSite::LAX_MODE, false},
2336 {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata,
2337 CookieSameSite::NO_RESTRICTION, false},
2338 {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata,
2339 CookieSameSite::NO_RESTRICTION, false},
2340
2341 // Strict-to-cross downgrade.
2342 {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata,
2343 CookieSameSite::STRICT_MODE, true},
2344 {ContextType::CROSS_SITE, strict_cross_downgrade_metadata,
2345 CookieSameSite::STRICT_MODE, true},
2346 {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata,
2347 CookieSameSite::LAX_MODE, true},
2348 {ContextType::CROSS_SITE, strict_cross_downgrade_metadata,
2349 CookieSameSite::LAX_MODE, true},
2350 {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata,
2351 CookieSameSite::NO_RESTRICTION, false},
2352 {ContextType::CROSS_SITE, strict_cross_downgrade_metadata,
2353 CookieSameSite::NO_RESTRICTION, false},
2354 };
2355
2356 for (bool consider_redirects : {true, false}) {
2357 base::test::ScopedFeatureList feature_list;
2358 feature_list.InitWithFeatureState(
2359 features::kCookieSameSiteConsidersRedirectChain, consider_redirects);
2360
2361 for (CookieAccessSemantics semantics :
2362 {CookieAccessSemantics::LEGACY, CookieAccessSemantics::NONLEGACY}) {
2363 // There are no downgrade warnings for undowngraded contexts.
2364 for (ContextType context_type :
2365 {ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_LAX,
2366 ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
2367 ContextType::CROSS_SITE}) {
2368 for (CookieSameSite samesite :
2369 {CookieSameSite::UNSPECIFIED, CookieSameSite::NO_RESTRICTION,
2370 CookieSameSite::LAX_MODE, CookieSameSite::STRICT_MODE}) {
2371 std::unique_ptr<CanonicalCookie> cookie =
2372 CanonicalCookie::CreateUnsafeCookieForTesting(
2373 "A", "1", "www.example.test", "/test", base::Time::Now(),
2374 base::Time(), base::Time(), base::Time(), /*secure=*/true,
2375 /*httponly=*/false, samesite, COOKIE_PRIORITY_DEFAULT,
2376 /*same_party=*/false);
2377
2378 CookieOptions options;
2379 options.set_same_site_cookie_context(Context(context_type));
2380
2381 EXPECT_FALSE(
2382 cookie
2383 ->IncludeForRequestURL(
2384 url, options,
2385 CookieAccessParams(
2386 semantics,
2387 /*delegate_treats_url_as_trustworthy=*/false,
2388 CookieSamePartyStatus::kNoSamePartyEnforcement))
2389 .status.HasWarningReason(
2390 CookieInclusionStatus::
2391 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
2392 }
2393 }
2394
2395 for (const auto& test : kTestCases) {
2396 std::unique_ptr<CanonicalCookie> cookie =
2397 CanonicalCookie::CreateUnsafeCookieForTesting(
2398 "A", "1", "www.example.test", "/test", base::Time::Now(),
2399 base::Time(), base::Time(), base::Time(), /*secure=*/true,
2400 /*httponly=*/false, test.samesite, COOKIE_PRIORITY_DEFAULT,
2401 /*same_party=*/false);
2402
2403 CookieOptions options;
2404 options.set_same_site_cookie_context(
2405 Context(test.context_type, test.context_type, test.metadata,
2406 test.metadata));
2407 EXPECT_EQ(
2408 cookie
2409 ->IncludeForRequestURL(
2410 url, options,
2411 CookieAccessParams(
2412 semantics,
2413 /*delegate_treats_url_as_trustworthy=*/false,
2414 CookieSamePartyStatus::kNoSamePartyEnforcement))
2415 .status.HasWarningReason(
2416 CookieInclusionStatus::
2417 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION),
2418 test.expect_cross_site_redirect_warning);
2419
2420 // SameSite warnings not applied if other exclusion reasons apply (e.g.
2421 // non-https with Secure attribute).
2422 EXPECT_FALSE(
2423 cookie
2424 ->IncludeForRequestURL(
2425 insecure_url, options,
2426 CookieAccessParams(
2427 semantics,
2428 /*delegate_treats_url_as_trustworthy=*/false,
2429 CookieSamePartyStatus::kNoSamePartyEnforcement))
2430 .status.HasWarningReason(
2431 CookieInclusionStatus::
2432 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
2433 }
2434 }
2435 }
2436 }
2437
TEST(CanonicalCookieTest,MultipleExclusionReasons)2438 TEST(CanonicalCookieTest, MultipleExclusionReasons) {
2439 GURL url("http://www.not-secure.com/foo");
2440 base::Time creation_time = base::Time::Now();
2441 absl::optional<base::Time> server_time = absl::nullopt;
2442 CookieOptions options;
2443 options.set_exclude_httponly();
2444 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2445 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
2446
2447 // Test IncludeForRequestURL()
2448 // Note: This is a cookie that should never exist normally, because Create()
2449 // would weed it out.
2450 auto cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
2451 "name", "value", "other-domain.com", "/bar", creation_time, base::Time(),
2452 base::Time(), base::Time(), true /* secure */, true /* httponly */,
2453 CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
2454 EXPECT_THAT(
2455 cookie1->IncludeForRequestURL(
2456 url, options,
2457 CookieAccessParams{CookieAccessSemantics::UNKNOWN,
2458 /*delegate_treats_url_as_trustworthy=*/false,
2459 CookieSamePartyStatus::kNoSamePartyEnforcement}),
2460 MatchesCookieAccessResult(
2461 CookieInclusionStatus::MakeFromReasonsForTesting({
2462 CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
2463 CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
2464 CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH,
2465 CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
2466 CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT,
2467 }),
2468 _, _, false));
2469
2470 // Test Create()
2471 CookieInclusionStatus create_status;
2472 auto cookie2 = CanonicalCookie::Create(
2473 url, "__Secure-notactuallysecure=value;Domain=some-other-domain.com",
2474 creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2475 &create_status);
2476 ASSERT_FALSE(cookie2);
2477 EXPECT_TRUE(create_status.HasExactlyExclusionReasonsForTesting(
2478 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX,
2479 CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
2480
2481 // Test IsSetPermittedInContext()
2482 auto cookie3 = CanonicalCookie::Create(
2483 url, "name=value;HttpOnly;SameSite=Lax", creation_time, server_time,
2484 absl::nullopt /* cookie_partition_key */);
2485 ASSERT_TRUE(cookie3);
2486 EXPECT_THAT(
2487 cookie3->IsSetPermittedInContext(
2488 url, options,
2489 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
2490 false /* delegate_treats_url_as_trustworthy */,
2491 CookieSamePartyStatus::kNoSamePartyEnforcement),
2492 kCookieableSchemes),
2493 MatchesCookieAccessResult(
2494 CookieInclusionStatus::MakeFromReasonsForTesting(
2495 {CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
2496 CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}),
2497 _, _, false));
2498 }
2499
TEST(CanonicalCookieTest,PartialCompare)2500 TEST(CanonicalCookieTest, PartialCompare) {
2501 GURL url("http://www.example.com");
2502 base::Time creation_time = base::Time::Now();
2503 absl::optional<base::Time> server_time = absl::nullopt;
2504 std::unique_ptr<CanonicalCookie> cookie(
2505 CanonicalCookie::Create(url, "a=b", creation_time, server_time,
2506 absl::nullopt /* cookie_partition_key */));
2507 std::unique_ptr<CanonicalCookie> cookie_different_path(
2508 CanonicalCookie::Create(url, "a=b; path=/foo", creation_time, server_time,
2509 absl::nullopt /* cookie_partition_key */));
2510 std::unique_ptr<CanonicalCookie> cookie_different_value(
2511 CanonicalCookie::Create(url, "a=c", creation_time, server_time,
2512 absl::nullopt /* cookie_partition_key */));
2513
2514 // Cookie is equivalent to itself.
2515 EXPECT_FALSE(cookie->PartialCompare(*cookie));
2516
2517 // Changing the path affects the ordering.
2518 EXPECT_TRUE(cookie->PartialCompare(*cookie_different_path));
2519 EXPECT_FALSE(cookie_different_path->PartialCompare(*cookie));
2520
2521 // Changing the value does not affect the ordering.
2522 EXPECT_FALSE(cookie->PartialCompare(*cookie_different_value));
2523 EXPECT_FALSE(cookie_different_value->PartialCompare(*cookie));
2524
2525 // Cookies identical for PartialCompare() are equivalent.
2526 EXPECT_TRUE(cookie->IsEquivalent(*cookie_different_value));
2527 EXPECT_TRUE(cookie->IsEquivalent(*cookie));
2528 }
2529
TEST(CanonicalCookieTest,SecureCookiePrefix)2530 TEST(CanonicalCookieTest, SecureCookiePrefix) {
2531 GURL https_url("https://www.example.test");
2532 GURL http_url("http://www.example.test");
2533 base::Time creation_time = base::Time::Now();
2534 absl::optional<base::Time> server_time = absl::nullopt;
2535 CookieInclusionStatus status;
2536
2537 // A __Secure- cookie must be Secure.
2538 EXPECT_FALSE(CanonicalCookie::Create(
2539 https_url, "__Secure-A=B", creation_time, server_time,
2540 absl::nullopt /* cookie_partition_key */, &status));
2541 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2542 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2543 EXPECT_FALSE(CanonicalCookie::Create(
2544 https_url, "__Secure-A=B; httponly", creation_time, server_time,
2545 absl::nullopt /* cookie_partition_key */, &status));
2546 // (EXCLUDE_HTTP_ONLY would be fine, too)
2547 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2548 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2549
2550 // Prefixes are case insensitive.
2551 EXPECT_FALSE(CanonicalCookie::Create(
2552 https_url, "__secure-A=C;", creation_time, server_time,
2553 absl::nullopt /* cookie_partition_key */));
2554 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2555 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2556 EXPECT_FALSE(CanonicalCookie::Create(
2557 https_url, "__SECURE-A=C;", creation_time, server_time,
2558 absl::nullopt /* cookie_partition_key */));
2559 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2560 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2561 EXPECT_FALSE(CanonicalCookie::Create(
2562 https_url, "__SeCuRe-A=C;", creation_time, server_time,
2563 absl::nullopt /* cookie_partition_key */));
2564 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2565 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2566
2567 {
2568 base::test::ScopedFeatureList scope_feature_list;
2569 scope_feature_list.InitAndDisableFeature(
2570 features::kCaseInsensitiveCookiePrefix);
2571
2572 EXPECT_TRUE(CanonicalCookie::Create(
2573 https_url, "__secure-A=C;", creation_time, server_time,
2574 absl::nullopt /* cookie_partition_key */));
2575 EXPECT_TRUE(CanonicalCookie::Create(
2576 https_url, "__SECURE-A=C;", creation_time, server_time,
2577 absl::nullopt /* cookie_partition_key */));
2578 EXPECT_TRUE(CanonicalCookie::Create(
2579 https_url, "__SeCuRe-A=C;", creation_time, server_time,
2580 absl::nullopt /* cookie_partition_key */));
2581 }
2582
2583 // A typoed prefix does not have to be Secure.
2584 EXPECT_TRUE(CanonicalCookie::Create(
2585 https_url, "__SecureA=B; Secure", creation_time, server_time,
2586 absl::nullopt /* cookie_partition_key */));
2587 EXPECT_TRUE(CanonicalCookie::Create(
2588 https_url, "__SecureA=C;", creation_time, server_time,
2589 absl::nullopt /* cookie_partition_key */));
2590 EXPECT_TRUE(CanonicalCookie::Create(
2591 https_url, "_Secure-A=C;", creation_time, server_time,
2592 absl::nullopt /* cookie_partition_key */));
2593 EXPECT_TRUE(CanonicalCookie::Create(
2594 https_url, "Secure-A=C;", creation_time, server_time,
2595 absl::nullopt /* cookie_partition_key */));
2596
2597 // A __Secure- cookie can't be set on a non-secure origin.
2598 EXPECT_FALSE(CanonicalCookie::Create(
2599 http_url, "__Secure-A=B; Secure", creation_time, server_time,
2600 absl::nullopt /* cookie_partition_key */, &status));
2601 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2602 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2603
2604 // Hidden __Secure- prefixes should be rejected.
2605 EXPECT_FALSE(CanonicalCookie::Create(
2606 https_url, "=__Secure-A=B; Secure", creation_time, server_time,
2607 absl::nullopt /* cookie_partition_key */, &status));
2608 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2609 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2610 EXPECT_FALSE(CanonicalCookie::Create(
2611 https_url, "=__Secure-A; Secure", creation_time, server_time,
2612 absl::nullopt /* cookie_partition_key */, &status));
2613 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2614 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2615
2616 // While tricky, this isn't considered hidden and is fine.
2617 EXPECT_TRUE(CanonicalCookie::Create(
2618 https_url, "A=__Secure-A=B; Secure", creation_time, server_time,
2619 absl::nullopt /* cookie_partition_key */));
2620 }
2621
TEST(CanonicalCookieTest,HostCookiePrefix)2622 TEST(CanonicalCookieTest, HostCookiePrefix) {
2623 GURL https_url("https://www.example.test");
2624 GURL http_url("http://www.example.test");
2625 base::Time creation_time = base::Time::Now();
2626 absl::optional<base::Time> server_time = absl::nullopt;
2627 std::string domain = https_url.host();
2628 CookieInclusionStatus status;
2629
2630 // A __Host- cookie must be Secure.
2631 EXPECT_FALSE(CanonicalCookie::Create(
2632 https_url, "__Host-A=B;", creation_time, server_time,
2633 absl::nullopt /* cookie_partition_key */, &status));
2634 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2635 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2636 EXPECT_FALSE(CanonicalCookie::Create(
2637 https_url, "__Host-A=B; Domain=" + domain + "; Path=/;", creation_time,
2638 server_time, absl::nullopt /* cookie_partition_key */, &status));
2639 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2640 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2641 EXPECT_TRUE(CanonicalCookie::Create(
2642 https_url, "__Host-A=B; Path=/; Secure;", creation_time, server_time,
2643 absl::nullopt /* cookie_partition_key */));
2644
2645 // A __Host- cookie must be set from a secure scheme.
2646 EXPECT_FALSE(CanonicalCookie::Create(
2647 http_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
2648 creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2649 &status));
2650 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2651 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2652 EXPECT_TRUE(CanonicalCookie::Create(
2653 https_url, "__Host-A=B; Path=/; Secure;", creation_time, server_time,
2654 absl::nullopt /* cookie_partition_key */));
2655
2656 // A __Host- cookie can't have a Domain.
2657 EXPECT_FALSE(CanonicalCookie::Create(
2658 https_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
2659 creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2660 &status));
2661 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2662 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2663 EXPECT_FALSE(CanonicalCookie::Create(
2664 https_url, "__Host-A=B; Domain=" + domain + "; Secure;", creation_time,
2665 server_time, absl::nullopt /* cookie_partition_key */, &status));
2666 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2667 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2668
2669 // A __Host- cookie may have a domain if it's an IP address that matches the
2670 // URL.
2671 EXPECT_TRUE(CanonicalCookie::Create(
2672 GURL("https://127.0.0.1"),
2673 "__Host-A=B; Domain=127.0.0.1; Path=/; Secure;", creation_time,
2674 server_time, absl::nullopt /* cookie_partition_key */, &status));
2675 // A __Host- cookie with an IP address domain does not need the domain
2676 // attribute specified explicitly (just like a normal domain).
2677 EXPECT_TRUE(CanonicalCookie::Create(
2678 GURL("https://127.0.0.1"), "__Host-A=B; Domain=; Path=/; Secure;",
2679 creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2680 &status));
2681
2682 // A __Host- cookie must have a Path of "/".
2683 EXPECT_FALSE(CanonicalCookie::Create(
2684 https_url, "__Host-A=B; Path=/foo; Secure;", creation_time, server_time,
2685 absl::nullopt /* cookie_partition_key */, &status));
2686 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2687 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2688 EXPECT_FALSE(CanonicalCookie::Create(
2689 https_url, "__Host-A=B; Secure;", creation_time, server_time,
2690 absl::nullopt /* cookie_partition_key */, &status));
2691 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2692 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2693 EXPECT_TRUE(CanonicalCookie::Create(
2694 https_url, "__Host-A=B; Secure; Path=/;", creation_time, server_time,
2695 absl::nullopt /* cookie_partition_key */));
2696
2697 // Prefixes are case insensitive.
2698 EXPECT_FALSE(CanonicalCookie::Create(
2699 http_url, "__host-A=B; Domain=" + domain + "; Path=/;", creation_time,
2700 server_time, absl::nullopt /* cookie_partition_key */, &status));
2701 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2702 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2703
2704 EXPECT_FALSE(CanonicalCookie::Create(
2705 http_url, "__HOST-A=B; Domain=" + domain + "; Path=/;", creation_time,
2706 server_time, absl::nullopt /* cookie_partition_key */, &status));
2707 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2708 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2709
2710 EXPECT_FALSE(CanonicalCookie::Create(
2711 http_url, "__HoSt-A=B; Domain=" + domain + "; Path=/;", creation_time,
2712 server_time, absl::nullopt /* cookie_partition_key */, &status));
2713 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2714 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2715
2716 {
2717 base::test::ScopedFeatureList scope_feature_list;
2718 scope_feature_list.InitAndDisableFeature(
2719 features::kCaseInsensitiveCookiePrefix);
2720
2721 EXPECT_TRUE(CanonicalCookie::Create(
2722 http_url, "__host-A=B; Domain=" + domain + "; Path=/;", creation_time,
2723 server_time, absl::nullopt /* cookie_partition_key */, &status));
2724
2725 EXPECT_TRUE(CanonicalCookie::Create(
2726 http_url, "__HOST-A=B; Domain=" + domain + "; Path=/;", creation_time,
2727 server_time, absl::nullopt /* cookie_partition_key */, &status));
2728
2729 EXPECT_TRUE(CanonicalCookie::Create(
2730 http_url, "__HoSt-A=B; Domain=" + domain + "; Path=/;", creation_time,
2731 server_time, absl::nullopt /* cookie_partition_key */, &status));
2732 }
2733
2734 // Rules don't apply for a typoed prefix.
2735 EXPECT_TRUE(CanonicalCookie::Create(
2736 https_url, "__HostA=B; Domain=" + domain + "; Secure;", creation_time,
2737 server_time, absl::nullopt /* cookie_partition_key */));
2738
2739 EXPECT_TRUE(CanonicalCookie::Create(
2740 https_url, "_Host-A=B; Domain=" + domain + "; Secure;", creation_time,
2741 server_time, absl::nullopt /* cookie_partition_key */));
2742
2743 EXPECT_TRUE(CanonicalCookie::Create(
2744 https_url, "Host-A=B; Domain=" + domain + "; Secure;", creation_time,
2745 server_time, absl::nullopt /* cookie_partition_key */));
2746
2747 // Hidden __Host- prefixes should be rejected.
2748 EXPECT_FALSE(CanonicalCookie::Create(
2749 https_url, "=__Host-A=B; Path=/; Secure;", creation_time, server_time,
2750 absl::nullopt /* cookie_partition_key */, &status));
2751 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2752 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2753 EXPECT_FALSE(CanonicalCookie::Create(
2754 https_url, "=__Host-A; Path=/; Secure;", creation_time, server_time,
2755 absl::nullopt /* cookie_partition_key */, &status));
2756 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2757 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2758
2759 // While tricky, this isn't considered hidden and is fine.
2760 EXPECT_TRUE(CanonicalCookie::Create(
2761 https_url, "A=__Host-A=B; Path=/; Secure;", creation_time, server_time,
2762 absl::nullopt /* cookie_partition_key */));
2763 }
2764
TEST(CanonicalCookieTest,CanCreateSecureCookiesFromAnyScheme)2765 TEST(CanonicalCookieTest, CanCreateSecureCookiesFromAnyScheme) {
2766 GURL http_url("http://www.example.com");
2767 GURL https_url("https://www.example.com");
2768 base::Time creation_time = base::Time::Now();
2769 absl::optional<base::Time> server_time = absl::nullopt;
2770
2771 std::unique_ptr<CanonicalCookie> http_cookie_no_secure(
2772 CanonicalCookie::Create(http_url, "a=b", creation_time, server_time,
2773 absl::nullopt /* cookie_partition_key */));
2774 std::unique_ptr<CanonicalCookie> http_cookie_secure(CanonicalCookie::Create(
2775 http_url, "a=b; Secure", creation_time, server_time,
2776 absl::nullopt /* cookie_partition_key */));
2777 std::unique_ptr<CanonicalCookie> https_cookie_no_secure(
2778 CanonicalCookie::Create(https_url, "a=b", creation_time, server_time,
2779 absl::nullopt /* cookie_partition_key */));
2780 std::unique_ptr<CanonicalCookie> https_cookie_secure(CanonicalCookie::Create(
2781 https_url, "a=b; Secure", creation_time, server_time,
2782 absl::nullopt /* cookie_partition_key */));
2783
2784 EXPECT_TRUE(http_cookie_no_secure.get());
2785 EXPECT_TRUE(http_cookie_secure.get());
2786 EXPECT_TRUE(https_cookie_no_secure.get());
2787 EXPECT_TRUE(https_cookie_secure.get());
2788 }
2789
TEST(CanonicalCookieTest,IsCanonical)2790 TEST(CanonicalCookieTest, IsCanonical) {
2791 // Base correct template.
2792 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2793 "A", "B", "x.y", "/path", base::Time(), base::Time(),
2794 base::Time(), base::Time(), false, false,
2795 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2796 ->IsCanonical());
2797
2798 // Newline in name.
2799 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2800 "A\n", "B", "x.y", "/path", base::Time(), base::Time(),
2801 base::Time(), base::Time(), false, false,
2802 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2803 ->IsCanonical());
2804
2805 // Carriage return in name.
2806 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2807 "A\r", "B", "x.y", "/path", base::Time(), base::Time(),
2808 base::Time(), base::Time(), false, false,
2809 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2810 ->IsCanonical());
2811
2812 // Null character in name.
2813 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2814 std::string("A\0Z", 3), "B", "x.y", "/path", base::Time(),
2815 base::Time(), base::Time(), base::Time(), false, false,
2816 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2817 ->IsCanonical());
2818
2819 // Name begins with whitespace.
2820 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2821 " A", "B", "x.y", "/path", base::Time(), base::Time(),
2822 base::Time(), base::Time(), false, false,
2823 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2824 ->IsCanonical());
2825
2826 // Name ends with whitespace.
2827 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2828 "A ", "B", "x.y", "/path", base::Time(), base::Time(),
2829 base::Time(), base::Time(), false, false,
2830 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2831 ->IsCanonical());
2832
2833 // Empty name. (Note this is against the spec but compatible with other
2834 // browsers.)
2835 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2836 "", "B", "x.y", "/path", base::Time(), base::Time(),
2837 base::Time(), base::Time(), false, false,
2838 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2839 ->IsCanonical());
2840
2841 // Space in name
2842 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2843 "A C", "B", "x.y", "/path", base::Time(), base::Time(),
2844 base::Time(), base::Time(), false, false,
2845 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2846 ->IsCanonical());
2847
2848 // Extra space suffixing name.
2849 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2850 "A ", "B", "x.y", "/path", base::Time(), base::Time(),
2851 base::Time(), base::Time(), false, false,
2852 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2853 ->IsCanonical());
2854
2855 // '=' character in name.
2856 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2857 "A=", "B", "x.y", "/path", base::Time(), base::Time(),
2858 base::Time(), base::Time(), false, false,
2859 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2860 ->IsCanonical());
2861
2862 // Separator in name.
2863 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2864 "A;", "B", "x.y", "/path", base::Time(), base::Time(),
2865 base::Time(), base::Time(), false, false,
2866 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2867 ->IsCanonical());
2868
2869 // '=' character in value.
2870 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2871 "A", "B=", "x.y", "/path", base::Time(), base::Time(),
2872 base::Time(), base::Time(), false, false,
2873 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2874 ->IsCanonical());
2875
2876 // Separator in value.
2877 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2878 "A", "B;", "x.y", "/path", base::Time(), base::Time(),
2879 base::Time(), base::Time(), false, false,
2880 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2881 ->IsCanonical());
2882
2883 // Separator in domain.
2884 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2885 "A", "B", ";x.y", "/path", base::Time(), base::Time(),
2886 base::Time(), base::Time(), false, false,
2887 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2888 ->IsCanonical());
2889
2890 // Garbage in domain.
2891 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2892 "A", "B", "@:&", "/path", base::Time(), base::Time(),
2893 base::Time(), base::Time(), false, false,
2894 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2895 ->IsCanonical());
2896
2897 // Space in domain.
2898 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2899 "A", "B", "x.y ", "/path", base::Time(), base::Time(),
2900 base::Time(), base::Time(), false, false,
2901 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2902 ->IsCanonical());
2903
2904 // Empty domain. (This is against cookie spec, but needed for Chrome's
2905 // out-of-spec use of cookies for extensions; see http://crbug.com/730633.
2906 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2907 "A", "B", "", "/path", base::Time(), base::Time(),
2908 base::Time(), base::Time(), false, false,
2909 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2910 ->IsCanonical());
2911
2912 // Path does not start with a "/".
2913 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2914 "A", "B", "x.y", "path", base::Time(), base::Time(),
2915 base::Time(), base::Time(), false, false,
2916 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2917 ->IsCanonical());
2918
2919 // Empty path.
2920 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2921 "A", "B", "x.y", "", base::Time(), base::Time(),
2922 base::Time(), base::Time(), false, false,
2923 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2924 ->IsCanonical());
2925
2926 // "localhost" as domain.
2927 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2928 "A", "B", "localhost", "/path", base::Time(), base::Time(),
2929 base::Time(), base::Time(), false, false,
2930 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2931 ->IsCanonical());
2932
2933 // non-ASCII domain.
2934 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2935 "A", "B", "\xC3\xA9xample.com", "/path", base::Time(),
2936 base::Time(), base::Time(), base::Time(), false, false,
2937 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2938 ->IsCanonical());
2939
2940 // punycode domain.
2941 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2942 "A", "B", "xn--xample-9ua.com", "/path", base::Time(),
2943 base::Time(), base::Time(), base::Time(), false, false,
2944 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2945 ->IsCanonical());
2946
2947 // Localhost IPv4 address as domain.
2948 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2949 "A", "B", "127.0.0.1", "/path", base::Time(), base::Time(),
2950 base::Time(), base::Time(), false, false,
2951 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2952 ->IsCanonical());
2953
2954 // Simple IPv4 address as domain.
2955 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2956 "A", "B", "1.2.3.4", "/path", base::Time(), base::Time(),
2957 base::Time(), base::Time(), false, false,
2958 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2959 ->IsCanonical());
2960
2961 // period-prefixed IPv4 address as domain.
2962 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2963 "A", "B", ".1.3.2.4", "/path", base::Time(), base::Time(),
2964 base::Time(), base::Time(), false, false,
2965 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2966 ->IsCanonical());
2967
2968 // period-prefixed truncated IPv4 address as domain.
2969 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2970 "A", "B", ".3.2.4", "/path", base::Time(), base::Time(),
2971 base::Time(), base::Time(), true, false,
2972 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2973 ->IsCanonical());
2974
2975 // truncated IPv4 address as domain.
2976 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2977 "A", "B", "3.2.4", "/path", base::Time(), base::Time(),
2978 base::Time(), base::Time(), true, false,
2979 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2980 ->IsCanonical());
2981
2982 // Non-canonical IPv4 address as domain.
2983 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2984 "A", "B", "01.2.03.4", "/path", base::Time(), base::Time(),
2985 base::Time(), base::Time(), false, false,
2986 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2987 ->IsCanonical());
2988
2989 // Non-canonical IPv4 address as domain.
2990 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2991 "A", "B", "16843009", "/path", base::Time(), base::Time(),
2992 base::Time(), base::Time(), false, false,
2993 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2994 ->IsCanonical());
2995
2996 // Non-canonical IPv4 address as domain.
2997 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2998 "A", "B", "0x1010101", "/path", base::Time(), base::Time(),
2999 base::Time(), base::Time(), false, false,
3000 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3001 ->IsCanonical());
3002
3003 // Null IPv6 address as domain.
3004 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3005 "A", "B", "[::]", "/path", base::Time(), base::Time(),
3006 base::Time(), base::Time(), false, false,
3007 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3008 ->IsCanonical());
3009
3010 // Localhost IPv6 address as domain.
3011 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3012 "A", "B", "[::1]", "/path", base::Time(), base::Time(),
3013 base::Time(), base::Time(), false, false,
3014 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3015 ->IsCanonical());
3016
3017 // Fully speced IPv6 address as domain.
3018 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3019 "A", "B", "[2001:0DB8:AC10:FE01:0000:0000:0000:0000]",
3020 "/path", base::Time(), base::Time(), base::Time(),
3021 base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
3022 COOKIE_PRIORITY_LOW, false)
3023 ->IsCanonical());
3024
3025 // Zero abbreviated IPv6 address as domain. Not canonical because of leading
3026 // zeros & uppercase hex letters.
3027 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3028 "A", "B", "[2001:0DB8:AC10:FE01::]", "/path", base::Time(),
3029 base::Time(), base::Time(), base::Time(), false, false,
3030 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3031 ->IsCanonical());
3032
3033 // Zero prefixes removed IPv6 address as domain. Not canoncial because of
3034 // uppercase hex letters.
3035 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3036 "A", "B", "[2001:DB8:AC10:FE01::]", "/path", base::Time(),
3037 base::Time(), base::Time(), base::Time(), false, false,
3038 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3039 ->IsCanonical());
3040
3041 // Lowercased hex IPv6 address as domain.
3042 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3043 "A", "B", "[2001:db8:ac10:fe01::]", "/path", base::Time(),
3044 base::Time(), base::Time(), base::Time(), false, false,
3045 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3046 ->IsCanonical());
3047
3048 // Lowercased hex IPv6 address as domain for domain cookie.
3049 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3050 "A", "B", ".[2001:db8:ac10:fe01::]", "/path", base::Time(),
3051 base::Time(), base::Time(), base::Time(), false, false,
3052 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3053 ->IsCanonical());
3054
3055 // Incomplete lowercased hex IPv6 address as domain.
3056 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3057 "A", "B", "[2001:db8:ac10:fe01:]", "/path", base::Time(),
3058 base::Time(), base::Time(), base::Time(), false, false,
3059 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3060 ->IsCanonical());
3061
3062 // Missing square brackets in IPv6 address as domain.
3063 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3064 "A", "B", "2606:2800:220:1:248:1893:25c8:1946", "/path",
3065 base::Time(), base::Time(), base::Time(), base::Time(),
3066 false, false, CookieSameSite::NO_RESTRICTION,
3067 COOKIE_PRIORITY_LOW, false)
3068 ->IsCanonical());
3069
3070 // Properly formatted host cookie.
3071 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3072 "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
3073 base::Time(), base::Time(), true, false,
3074 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3075 ->IsCanonical());
3076
3077 // Insecure host cookie.
3078 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3079 "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
3080 base::Time(), base::Time(), false, false,
3081 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3082 ->IsCanonical());
3083
3084 // Host cookie with non-null path.
3085 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3086 "__Host-A", "B", "x.y", "/path", base::Time(), base::Time(),
3087 base::Time(), base::Time(), true, false,
3088 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3089 ->IsCanonical());
3090
3091 // Host cookie with empty domain.
3092 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3093 "__Host-A", "B", "", "/", base::Time(), base::Time(),
3094 base::Time(), base::Time(), true, false,
3095 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3096 ->IsCanonical());
3097
3098 // Host cookie with period prefixed domain.
3099 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3100 "__Host-A", "B", ".x.y", "/", base::Time(), base::Time(),
3101 base::Time(), base::Time(), true, false,
3102 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3103 ->IsCanonical());
3104
3105 // Properly formatted secure cookie.
3106 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3107 "__Secure-A", "B", "x.y", "/", base::Time(), base::Time(),
3108 base::Time(), base::Time(), true, false,
3109 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3110 ->IsCanonical());
3111
3112 // Insecure secure cookie.
3113 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3114 "__Secure-A", "B", "x.y", "/", base::Time(), base::Time(),
3115 base::Time(), base::Time(), false, false,
3116 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3117 ->IsCanonical());
3118
3119 // SameParty attribute used correctly (with Secure and non-Strict SameSite).
3120 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3121 "A", "B", "x.y", "/", base::Time(), base::Time(),
3122 base::Time(), base::Time(), true, false,
3123 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, true)
3124 ->IsCanonical());
3125 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3126 "A", "B", "x.y", "/", base::Time(), base::Time(),
3127 base::Time(), base::Time(), true, false,
3128 CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_LOW, true)
3129 ->IsCanonical());
3130 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3131 "A", "B", "x.y", "/", base::Time(), base::Time(),
3132 base::Time(), base::Time(), true, false,
3133 CookieSameSite::LAX_MODE, COOKIE_PRIORITY_LOW, true)
3134 ->IsCanonical());
3135
3136 // SameParty without Secure is not canonical.
3137 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3138 "A", "B", "x.y", "/", base::Time(), base::Time(),
3139 base::Time(), base::Time(), false, false,
3140 CookieSameSite::LAX_MODE, COOKIE_PRIORITY_LOW, true)
3141 ->IsCanonical());
3142
3143 // SameParty with SameSite=Strict is not canonical.
3144 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3145 "A", "B", "x.y", "/", base::Time(), base::Time(),
3146 base::Time(), base::Time(), true, false,
3147 CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW, true)
3148 ->IsCanonical());
3149
3150 // Partitioned attribute used correctly (__Host- prefix, no SameParty).
3151 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3152 "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
3153 base::Time(), base::Time(), /*secure=*/true,
3154 /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3155 COOKIE_PRIORITY_LOW,
3156 /*same_party=*/false,
3157 CookiePartitionKey::FromURLForTesting(
3158 GURL("https://toplevelsite.com")))
3159 ->IsCanonical());
3160
3161 // Partitioned attribute with no __Host- prefix is still valid if it has
3162 // Secure, Path=/, and no Domain.
3163 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3164 "A", "B", "x.y", "/", base::Time(), base::Time(),
3165 base::Time(), base::Time(), /*secure=*/true,
3166 /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3167 COOKIE_PRIORITY_LOW,
3168 /*same_party=*/false,
3169 CookiePartitionKey::FromURLForTesting(
3170 GURL("https://toplevelsite.com")))
3171 ->IsCanonical());
3172
3173 // Partitioned attribute invalid, not Secure.
3174 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3175 "A", "B", "x.y", "/", base::Time(), base::Time(),
3176 base::Time(), base::Time(), /*secure=*/false,
3177 /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3178 COOKIE_PRIORITY_LOW,
3179 /*same_party=*/false,
3180 CookiePartitionKey::FromURLForTesting(
3181 GURL("https://toplevelsite.com")))
3182 ->IsCanonical());
3183
3184 // Partitioned attribute is valid when Path != "/".
3185 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3186 "A", "B", "x.y", "/foo/bar", base::Time(), base::Time(),
3187 base::Time(), base::Time(), /*secure=*/true,
3188 /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3189 COOKIE_PRIORITY_LOW,
3190 /*same_party=*/false,
3191 CookiePartitionKey::FromURLForTesting(
3192 GURL("https://toplevelsite.com")))
3193 ->IsCanonical());
3194
3195 // Partitioned attribute is valid when Domain attribute also included.
3196 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3197 "A", "B", ".x.y", "/", base::Time(), base::Time(),
3198 base::Time(), base::Time(), /*secure=*/true,
3199 /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3200 COOKIE_PRIORITY_LOW,
3201 /*same_party=*/false,
3202 CookiePartitionKey::FromURLForTesting(
3203 GURL("https://toplevelsite.com")))
3204 ->IsCanonical());
3205
3206 // Hidden cookie prefixes.
3207 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3208 "", "__Secure-a=b", "x.y", "/", base::Time(), base::Time(),
3209 base::Time(), base::Time(), true, false,
3210 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3211 ->IsCanonical());
3212
3213 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3214 "", "__Secure-a", "x.y", "/", base::Time(), base::Time(),
3215 base::Time(), base::Time(), true, false,
3216 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3217 ->IsCanonical());
3218
3219 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3220 "", "__Host-a=b", "x.y", "/", base::Time(), base::Time(),
3221 base::Time(), base::Time(), true, false,
3222 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3223 ->IsCanonical());
3224
3225 EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3226 "", "__Host-a", "x.y", "/", base::Time(), base::Time(),
3227 base::Time(), base::Time(), true, false,
3228 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3229 ->IsCanonical());
3230
3231 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3232 "a", "__Secure-a=b", "x.y", "/", base::Time(), base::Time(),
3233 base::Time(), base::Time(), true, false,
3234 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3235 ->IsCanonical());
3236
3237 EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3238 "a", "__Host-a=b", "x.y", "/", base::Time(), base::Time(),
3239 base::Time(), base::Time(), true, false,
3240 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3241 ->IsCanonical());
3242 }
3243
TEST(CanonicalCookieTest,TestSetCreationDate)3244 TEST(CanonicalCookieTest, TestSetCreationDate) {
3245 auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
3246 "A", "B", "x.y", "/path", base::Time(), base::Time(), base::Time(),
3247 base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
3248 COOKIE_PRIORITY_LOW, false);
3249 EXPECT_TRUE(cookie->CreationDate().is_null());
3250
3251 base::Time now(base::Time::Now());
3252 cookie->SetCreationDate(now);
3253 EXPECT_EQ(now, cookie->CreationDate());
3254 }
3255
TEST(CanonicalCookieTest,TestPrefixHistograms)3256 TEST(CanonicalCookieTest, TestPrefixHistograms) {
3257 base::HistogramTester histograms;
3258 const char kCookiePrefixHistogram[] = "Cookie.CookiePrefix";
3259 const char kCookiePrefixVariantHistogram[] =
3260 "Cookie.CookiePrefix.CaseVariant";
3261 const char kVariantValidHistogram[] = "Cookie.CookiePrefix.CaseVariantValid";
3262 const char kVariantCountHistogram[] = "Cookie.CookiePrefix.CaseVariantCount";
3263 GURL https_url("https://www.example.test");
3264 base::Time creation_time = base::Time::Now();
3265 absl::optional<base::Time> server_time = absl::nullopt;
3266
3267 EXPECT_FALSE(CanonicalCookie::Create(
3268 https_url, "__Host-A=B;", creation_time, server_time,
3269 absl::nullopt /* cookie_partition_key */));
3270
3271 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3272 CanonicalCookie::COOKIE_PREFIX_HOST, 1);
3273
3274 EXPECT_TRUE(CanonicalCookie::Create(
3275 https_url, "__Host-A=B; Path=/; Secure", creation_time, server_time,
3276 absl::nullopt /* cookie_partition_key */));
3277 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3278 CanonicalCookie::COOKIE_PREFIX_HOST, 2);
3279 EXPECT_TRUE(CanonicalCookie::Create(
3280 https_url, "__HostA=B; Path=/; Secure", creation_time, server_time,
3281 absl::nullopt /* cookie_partition_key */));
3282 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3283 CanonicalCookie::COOKIE_PREFIX_HOST, 2);
3284
3285 EXPECT_FALSE(CanonicalCookie::Create(
3286 https_url, "__Secure-A=B;", creation_time, server_time,
3287 absl::nullopt /* cookie_partition_key */));
3288
3289 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3290 CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
3291 EXPECT_TRUE(CanonicalCookie::Create(
3292 https_url, "__Secure-A=B; Path=/; Secure", creation_time, server_time,
3293 absl::nullopt /* cookie_partition_key */));
3294 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3295 CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
3296 EXPECT_TRUE(CanonicalCookie::Create(
3297 https_url, "__SecureA=B; Path=/; Secure", creation_time, server_time,
3298 absl::nullopt /* cookie_partition_key */));
3299 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3300 CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
3301
3302 // Test prefix case variants
3303 const int sensitive_value_host = histograms.GetBucketCount(
3304 kCookiePrefixHistogram, CanonicalCookie::COOKIE_PREFIX_HOST);
3305 const int sensitive_value_secure = histograms.GetBucketCount(
3306 kCookiePrefixHistogram, CanonicalCookie::COOKIE_PREFIX_SECURE);
3307
3308 EXPECT_TRUE(CanonicalCookie::Create(
3309 https_url, "__SECURE-A=B; Path=/; Secure", creation_time, server_time,
3310 absl::nullopt /* cookie_partition_key */));
3311 histograms.ExpectBucketCount(kCookiePrefixVariantHistogram,
3312 CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
3313 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3314 CanonicalCookie::COOKIE_PREFIX_SECURE,
3315 sensitive_value_secure);
3316
3317 EXPECT_TRUE(CanonicalCookie::Create(
3318 https_url, "__HOST-A=B; Path=/; Secure", creation_time, server_time,
3319 absl::nullopt /* cookie_partition_key */));
3320 histograms.ExpectBucketCount(kCookiePrefixVariantHistogram,
3321 CanonicalCookie::COOKIE_PREFIX_HOST, 1);
3322 histograms.ExpectBucketCount(kCookiePrefixHistogram,
3323 CanonicalCookie::COOKIE_PREFIX_HOST,
3324 sensitive_value_host);
3325
3326 // True indicates a variant
3327 histograms.ExpectBucketCount(kVariantCountHistogram, true, 2);
3328 histograms.ExpectBucketCount(kVariantCountHistogram, false, 4);
3329
3330 // Invalid variants
3331 EXPECT_FALSE(CanonicalCookie::Create(
3332 https_url, "__SECURE-A=B", creation_time, server_time,
3333 absl::nullopt /* cookie_partition_key */));
3334
3335 EXPECT_FALSE(CanonicalCookie::Create(
3336 https_url, "__HOST-A=B;", creation_time, server_time,
3337 absl::nullopt /* cookie_partition_key */));
3338
3339 histograms.ExpectBucketCount(kVariantValidHistogram, true, 2);
3340 histograms.ExpectBucketCount(kVariantValidHistogram, false, 2);
3341 }
3342
TEST(CanonicalCookieTest,TestHasNonASCIIHistograms)3343 TEST(CanonicalCookieTest, TestHasNonASCIIHistograms) {
3344 base::HistogramTester histograms;
3345 const char kCookieNonASCIINameHistogram[] = "Cookie.HasNonASCII.Name";
3346 const char kCookieNonASCIIValueHistogram[] = "Cookie.HasNonASCII.Value";
3347 const GURL test_url("https://www.example.test");
3348 int expected_name_true = 0;
3349 int expected_name_false = 0;
3350 int expected_value_true = 0;
3351 int expected_value_false = 0;
3352
3353 auto create_for_test = [&](const std::string& name,
3354 const std::string& value) {
3355 return CanonicalCookie::Create(
3356 test_url, name + "=" + value, /*creation_time=*/base::Time::Now(),
3357 /*server_time=*/absl::nullopt, /*cookie_partition_key=*/absl::nullopt);
3358 };
3359
3360 auto check_histograms = [&]() {
3361 histograms.ExpectBucketCount(kCookieNonASCIINameHistogram, true,
3362 expected_name_true);
3363 histograms.ExpectBucketCount(kCookieNonASCIINameHistogram, false,
3364 expected_name_false);
3365 histograms.ExpectBucketCount(kCookieNonASCIIValueHistogram, true,
3366 expected_value_true);
3367 histograms.ExpectBucketCount(kCookieNonASCIIValueHistogram, false,
3368 expected_value_false);
3369 };
3370
3371 EXPECT_TRUE(create_for_test("foo", "bar"));
3372 expected_name_false++;
3373 expected_value_false++;
3374 check_histograms();
3375
3376 EXPECT_TRUE(create_for_test("Uni\xf0\x9f\x8d\xaa", "bar"));
3377 expected_name_true++;
3378 expected_value_false++;
3379 check_histograms();
3380
3381 EXPECT_TRUE(create_for_test("foo", "Uni\xf0\x9f\x8d\xaa"));
3382 expected_name_false++;
3383 expected_value_true++;
3384 check_histograms();
3385
3386 EXPECT_TRUE(create_for_test("Uni\xf0\x9f\x8d\xaa", "Uni\xf0\x9f\x8d\xaa"));
3387 expected_name_true++;
3388 expected_value_true++;
3389 check_histograms();
3390 }
3391
TEST(CanonicalCookieTest,BuildCookieLine)3392 TEST(CanonicalCookieTest, BuildCookieLine) {
3393 std::vector<std::unique_ptr<CanonicalCookie>> cookies;
3394 GURL url("https://example.com/");
3395 base::Time now = base::Time::Now();
3396 absl::optional<base::Time> server_time = absl::nullopt;
3397 MatchCookieLineToVector("", cookies);
3398
3399 cookies.push_back(CanonicalCookie::Create(
3400 url, "A=B", now, server_time, absl::nullopt /* cookie_partition_key */));
3401 MatchCookieLineToVector("A=B", cookies);
3402 // Nameless cookies are sent back without a prefixed '='.
3403 cookies.push_back(CanonicalCookie::Create(
3404 url, "C", now, server_time, absl::nullopt /* cookie_partition_key */));
3405 MatchCookieLineToVector("A=B; C", cookies);
3406 // Cookies separated by ';'.
3407 cookies.push_back(CanonicalCookie::Create(
3408 url, "D=E", now, server_time, absl::nullopt /* cookie_partition_key */));
3409 MatchCookieLineToVector("A=B; C; D=E", cookies);
3410 // BuildCookieLine doesn't reorder the list, it relies on the caller to do so.
3411 cookies.push_back(
3412 CanonicalCookie::Create(url, "F=G", now - base::Seconds(1), server_time,
3413 absl::nullopt /* cookie_partition_key */));
3414 MatchCookieLineToVector("A=B; C; D=E; F=G", cookies);
3415 // BuildCookieLine doesn't deduplicate.
3416 cookies.push_back(
3417 CanonicalCookie::Create(url, "D=E", now - base::Seconds(2), server_time,
3418 absl::nullopt /* cookie_partition_key */));
3419 MatchCookieLineToVector("A=B; C; D=E; F=G; D=E", cookies);
3420 // BuildCookieLine should match the spec in the case of an empty name with a
3421 // value containing an equal sign (even if it currently produces "invalid"
3422 // cookie lines).
3423 cookies.push_back(CanonicalCookie::Create(
3424 url, "=H=I", now, server_time, absl::nullopt /* cookie_partition_key */));
3425 MatchCookieLineToVector("A=B; C; D=E; F=G; D=E; H=I", cookies);
3426 }
3427
TEST(CanonicalCookieTest,BuildCookieAttributesLine)3428 TEST(CanonicalCookieTest, BuildCookieAttributesLine) {
3429 std::unique_ptr<CanonicalCookie> cookie;
3430 GURL url("https://example.com/");
3431 base::Time now = base::Time::Now();
3432 absl::optional<base::Time> server_time = absl::nullopt;
3433
3434 cookie = CanonicalCookie::Create(url, "A=B", now, server_time,
3435 absl::nullopt /* cookie_partition_key */);
3436 EXPECT_EQ("A=B; domain=example.com; path=/",
3437 CanonicalCookie::BuildCookieAttributesLine(*cookie));
3438 // Nameless cookies are sent back without a prefixed '='.
3439 cookie = CanonicalCookie::Create(url, "C", now, server_time,
3440 absl::nullopt /* cookie_partition_key */);
3441 EXPECT_EQ("C; domain=example.com; path=/",
3442 CanonicalCookie::BuildCookieAttributesLine(*cookie));
3443 // BuildCookieAttributesLine should match the spec in the case of an empty
3444 // name with a value containing an equal sign (even if it currently produces
3445 // "invalid" cookie lines).
3446 cookie = CanonicalCookie::Create(url, "=H=I", now, server_time,
3447 absl::nullopt /* cookie_partition_key */);
3448 EXPECT_EQ("H=I; domain=example.com; path=/",
3449 CanonicalCookie::BuildCookieAttributesLine(*cookie));
3450 // BuildCookieAttributesLine should include all attributes.
3451 cookie = CanonicalCookie::Create(
3452 url, "A=B; domain=.example.com; path=/; secure; httponly; samesite=lax",
3453 now, server_time, absl::nullopt /* cookie_partition_key */);
3454 EXPECT_EQ("A=B; domain=.example.com; path=/; secure; httponly; samesite=lax",
3455 CanonicalCookie::BuildCookieAttributesLine(*cookie));
3456 }
3457
3458 // Confirm that input arguments are reflected in the output cookie.
TEST(CanonicalCookieTest,CreateSanitizedCookie_Inputs)3459 TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
3460 base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
3461 base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
3462 base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
3463 CookieInclusionStatus status;
3464 std::unique_ptr<CanonicalCookie> cc;
3465
3466 cc = CanonicalCookie::CreateSanitizedCookie(
3467 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3468 base::Time(), base::Time(), base::Time(), false /*secure*/,
3469 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3470 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3471 absl::nullopt /*partition_key*/, &status);
3472 EXPECT_TRUE(cc);
3473 EXPECT_EQ("A", cc->Name());
3474 EXPECT_EQ("B", cc->Value());
3475 EXPECT_EQ("www.foo.com", cc->Domain());
3476 EXPECT_EQ("/foo", cc->Path());
3477 EXPECT_EQ(base::Time(), cc->CreationDate());
3478 EXPECT_EQ(base::Time(), cc->LastAccessDate());
3479 EXPECT_EQ(base::Time(), cc->ExpiryDate());
3480 EXPECT_FALSE(cc->IsSecure());
3481 EXPECT_FALSE(cc->IsHttpOnly());
3482 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite());
3483 EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority());
3484 EXPECT_FALSE(cc->IsSameParty());
3485 EXPECT_FALSE(cc->IsPartitioned());
3486 EXPECT_FALSE(cc->IsDomainCookie());
3487 EXPECT_TRUE(status.IsInclude());
3488
3489 // Creation date
3490 cc = CanonicalCookie::CreateSanitizedCookie(
3491 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3492 two_hours_ago, base::Time(), base::Time(), false /*secure*/,
3493 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3494 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3495 absl::nullopt /*partition_key*/, &status);
3496 EXPECT_TRUE(cc);
3497 EXPECT_EQ(two_hours_ago, cc->CreationDate());
3498 EXPECT_TRUE(status.IsInclude());
3499
3500 // Last access date
3501 cc = CanonicalCookie::CreateSanitizedCookie(
3502 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3503 two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
3504 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3505 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3506 absl::nullopt /*partition_key*/, &status);
3507 EXPECT_TRUE(cc);
3508 EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
3509 EXPECT_TRUE(status.IsInclude());
3510
3511 // Expiry
3512 cc = CanonicalCookie::CreateSanitizedCookie(
3513 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3514 base::Time(), one_hour_from_now, base::Time(), false /*secure*/,
3515 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3516 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3517 absl::nullopt /*partition_key*/, &status);
3518 EXPECT_TRUE(cc);
3519 EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
3520 EXPECT_TRUE(status.IsInclude());
3521
3522 // Secure
3523 cc = CanonicalCookie::CreateSanitizedCookie(
3524 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3525 base::Time(), base::Time(), base::Time(), true /*secure*/,
3526 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3527 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3528 absl::nullopt /*partition_key*/, &status);
3529 EXPECT_TRUE(cc);
3530 EXPECT_TRUE(cc->IsSecure());
3531 EXPECT_TRUE(status.IsInclude());
3532
3533 // Httponly
3534 cc = CanonicalCookie::CreateSanitizedCookie(
3535 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3536 base::Time(), base::Time(), base::Time(), false /*secure*/,
3537 true /*httponly*/, CookieSameSite::NO_RESTRICTION,
3538 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3539 absl::nullopt /*partition_key*/, &status);
3540 EXPECT_TRUE(cc);
3541 EXPECT_TRUE(cc->IsHttpOnly());
3542 EXPECT_TRUE(status.IsInclude());
3543
3544 // Same site
3545 cc = CanonicalCookie::CreateSanitizedCookie(
3546 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3547 base::Time(), base::Time(), base::Time(), false /*secure*/,
3548 false /*httponly*/, CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
3549 false /*same_party*/, absl::nullopt /*partition_key*/, &status);
3550 EXPECT_TRUE(cc);
3551 EXPECT_EQ(CookieSameSite::LAX_MODE, cc->SameSite());
3552 EXPECT_TRUE(status.IsInclude());
3553
3554 // Priority
3555 cc = CanonicalCookie::CreateSanitizedCookie(
3556 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3557 base::Time(), base::Time(), base::Time(), false /*secure*/,
3558 false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
3559 false /*same_party*/, absl::nullopt /*partition_key*/, &status);
3560 EXPECT_TRUE(cc);
3561 EXPECT_EQ(COOKIE_PRIORITY_LOW, cc->Priority());
3562 EXPECT_TRUE(status.IsInclude());
3563
3564 // Domain cookie
3565 cc = CanonicalCookie::CreateSanitizedCookie(
3566 GURL("https://www.foo.com"), "A", "B", "www.foo.com", "/foo",
3567 base::Time(), base::Time(), base::Time(), false /*secure*/,
3568 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3569 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3570 absl::nullopt /*partition_key*/, &status);
3571 EXPECT_TRUE(cc);
3572 EXPECT_TRUE(cc->IsDomainCookie());
3573 EXPECT_TRUE(status.IsInclude());
3574
3575 // SameParty
3576 cc = CanonicalCookie::CreateSanitizedCookie(
3577 GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3578 base::Time(), base::Time(), base::Time(), true /*secure*/,
3579 false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
3580 true /*same_party*/, absl::nullopt /*partition_key*/, &status);
3581 EXPECT_TRUE(cc);
3582 EXPECT_TRUE(cc->IsSameParty());
3583 EXPECT_TRUE(status.IsInclude());
3584
3585 // Partitioned
3586 cc = CanonicalCookie::CreateSanitizedCookie(
3587 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3588 base::Time(), base::Time(), base::Time(), true /*secure*/,
3589 false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
3590 false /*same_party*/,
3591 CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com")),
3592 &status);
3593 EXPECT_TRUE(cc);
3594 EXPECT_TRUE(cc->IsPartitioned());
3595 EXPECT_TRUE(status.IsInclude());
3596 }
3597
3598 // Make sure sanitization and blocking of cookies works correctly.
TEST(CanonicalCookieTest,CreateSanitizedCookie_Logic)3599 TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
3600 base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
3601 base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
3602 base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
3603 CookieInclusionStatus status;
3604
3605 // Simple path and domain variations.
3606 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3607 GURL("http://www.foo.com/foo"), "A", "B", std::string(), "/foo",
3608 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3609 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3610 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3611 absl::nullopt /*partition_key*/, &status));
3612 EXPECT_TRUE(status.IsInclude());
3613 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3614 GURL("http://www.foo.com/bar"), "C", "D", "www.foo.com", "/",
3615 two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
3616 true /*httponly*/, CookieSameSite::NO_RESTRICTION,
3617 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3618 absl::nullopt /*partition_key*/, &status));
3619 EXPECT_TRUE(status.IsInclude());
3620 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3621 GURL("https://www.foo.com"), "E", "F", std::string(), std::string(),
3622 base::Time(), base::Time(), base::Time(), true /*secure*/,
3623 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3624 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3625 absl::nullopt /*partition_key*/, &status));
3626 EXPECT_TRUE(status.IsInclude());
3627
3628 // Test the file:// protocol.
3629 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3630 GURL("file:///"), "A", "B", std::string(), "/foo", one_hour_ago,
3631 one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
3632 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3633 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3634 EXPECT_TRUE(status.IsInclude());
3635 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3636 GURL("file:///home/user/foo.txt"), "A", "B", std::string(), "/foo",
3637 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3638 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3639 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3640 absl::nullopt /*partition_key*/, &status));
3641 EXPECT_TRUE(status.IsInclude());
3642 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3643 GURL("file:///home/user/foo.txt"), "A", "B", "home", "/foo", one_hour_ago,
3644 one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
3645 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3646 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3647 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3648 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3649
3650 // Test that malformed attributes fail to set the cookie.
3651 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3652 GURL("http://www.foo.com/foo"), " A", "B", std::string(), "/foo",
3653 base::Time(), base::Time(), base::Time(), false /*secure*/,
3654 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3655 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3656 absl::nullopt /*partition_key*/, &status));
3657 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3658 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3659 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3660 GURL("http://www.foo.com/foo"), "A;", "B", std::string(), "/foo",
3661 base::Time(), base::Time(), base::Time(), false /*secure*/,
3662 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3663 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3664 absl::nullopt /*partition_key*/, &status));
3665 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3666 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3667 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3668 GURL("http://www.foo.com/foo"), "A=", "B", std::string(), "/foo",
3669 base::Time(), base::Time(), base::Time(), false /*secure*/,
3670 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3671 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3672 absl::nullopt /*partition_key*/, &status));
3673 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3674 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3675 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3676 GURL("http://www.foo.com/foo"), "A\x07", "B", std::string(), "/foo",
3677 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3678 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3679 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3680 absl::nullopt /*partition_key*/, &status));
3681 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3682 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3683 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3684 GURL("http://www.foo.com"), "A", " B", std::string(), "/foo",
3685 base::Time(), base::Time(), base::Time(), false /*secure*/,
3686 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3687 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3688 absl::nullopt /*partition_key*/, &status));
3689 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3690 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3691 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3692 GURL("http://www.foo.com"), "A", "\x0fZ", std::string(), "/foo",
3693 base::Time(), base::Time(), base::Time(), false /*secure*/,
3694 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3695 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3696 absl::nullopt /*partition_key*/, &status));
3697 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3698 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3699 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3700 GURL("http://www.foo.com"), "A", "B", "www.foo.com ", "/foo",
3701 base::Time(), base::Time(), base::Time(), false /*secure*/,
3702 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3703 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3704 absl::nullopt /*partition_key*/, &status));
3705 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3706 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3707 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3708 GURL("http://www.foo.com/foo"), "A", "B", "foo.ozzzzzzle", "/foo",
3709 base::Time(), base::Time(), base::Time(), false /*secure*/,
3710 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3711 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3712 absl::nullopt /*partition_key*/, &status));
3713 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3714 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3715 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3716 GURL("http://www.foo.com/foo"), "A", "B", std::string(), "foo",
3717 base::Time(), base::Time(), base::Time(), false /*secure*/,
3718 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3719 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3720 absl::nullopt /*partition_key*/, &status));
3721 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3722 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3723 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3724 GURL("http://www.foo.com"), "A", "B", std::string(), "/foo ",
3725 base::Time(), base::Time(), base::Time(), false /*secure*/,
3726 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3727 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3728 absl::nullopt /*partition_key*/, &status));
3729 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3730 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3731 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3732 GURL("http://www.foo.com/foo"), "A", "B", "%2Efoo.com", "/foo",
3733 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3734 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3735 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3736 absl::nullopt /*partition_key*/, &status));
3737 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3738 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3739 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3740 GURL("http://domaintest.%E3%81%BF%E3%82%93%E3%81%AA"), "A", "B",
3741 "domaintest.%E3%81%BF%E3%82%93%E3%81%AA", "/foo", base::Time(),
3742 base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
3743 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3744 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3745 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3746 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3747
3748 std::unique_ptr<CanonicalCookie> cc;
3749
3750 // Confirm that setting domain cookies with or without leading periods,
3751 // or on domains different from the URL's, functions correctly.
3752 cc = CanonicalCookie::CreateSanitizedCookie(
3753 GURL("http://www.foo.com/foo"), "A", "B", "www.foo.com", "/foo",
3754 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3755 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3756 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3757 absl::nullopt /*partition_key*/, &status);
3758 ASSERT_TRUE(cc);
3759 EXPECT_TRUE(cc->IsDomainCookie());
3760 EXPECT_EQ(".www.foo.com", cc->Domain());
3761 EXPECT_TRUE(status.IsInclude());
3762
3763 cc = CanonicalCookie::CreateSanitizedCookie(
3764 GURL("http://www.foo.com/foo"), "A", "B", ".www.foo.com", "/foo",
3765 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3766 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3767 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3768 absl::nullopt /*partition_key*/, &status);
3769 ASSERT_TRUE(cc);
3770 EXPECT_TRUE(cc->IsDomainCookie());
3771 EXPECT_EQ(".www.foo.com", cc->Domain());
3772 EXPECT_TRUE(status.IsInclude());
3773
3774 cc = CanonicalCookie::CreateSanitizedCookie(
3775 GURL("http://www.foo.com/foo"), "A", "B", ".foo.com", "/foo",
3776 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3777 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3778 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3779 absl::nullopt /*partition_key*/, &status);
3780 ASSERT_TRUE(cc);
3781 EXPECT_TRUE(cc->IsDomainCookie());
3782 EXPECT_EQ(".foo.com", cc->Domain());
3783 EXPECT_TRUE(status.IsInclude());
3784
3785 cc = CanonicalCookie::CreateSanitizedCookie(
3786 GURL("http://www.foo.com/foo"), "A", "B", ".www2.www.foo.com", "/foo",
3787 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3788 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3789 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3790 absl::nullopt /*partition_key*/, &status);
3791 EXPECT_FALSE(cc);
3792 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3793 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3794
3795 // Secure/URL Scheme mismatch.
3796 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3797 GURL("http://www.foo.com"), "A", "B", std::string(), "/foo ",
3798 base::Time(), base::Time(), base::Time(), true /*secure*/,
3799 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3800 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3801 absl::nullopt /*partition_key*/, &status));
3802 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3803 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3804
3805 // Null creation date/non-null last access date conflict.
3806 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3807 GURL("http://www.foo.com"), "A", "B", std::string(), "/foo", base::Time(),
3808 base::Time(), base::Time::Now(), false /*secure*/, false /*httponly*/,
3809 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3810 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3811 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3812 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3813
3814 // Domain doesn't match URL
3815 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3816 GURL("http://www.foo.com"), "A", "B", "www.bar.com", "/", base::Time(),
3817 base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
3818 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3819 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3820 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3821 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3822
3823 // Path with unusual characters escaped.
3824 cc = CanonicalCookie::CreateSanitizedCookie(
3825 GURL("http://www.foo.com"), "A", "B", std::string(), "/foo\x7F",
3826 base::Time(), base::Time(), base::Time(), false /*secure*/,
3827 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3828 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3829 absl::nullopt /*partition_key*/, &status);
3830 ASSERT_TRUE(cc);
3831 EXPECT_EQ("/foo%7F", cc->Path());
3832 EXPECT_TRUE(status.IsInclude());
3833
3834 // Ensure that all characters get escaped the same on all platforms. This is
3835 // also useful for visualizing which characters will actually be escaped.
3836 std::stringstream ss;
3837 ss << "/";
3838 for (uint8_t character = 0; character < 0xFF; character++) {
3839 // Skip any "terminating characters" that CreateSanitizedCookie does not
3840 // allow to be in `path`.
3841 if (character == '\0' || character == '\n' || character == '\r' ||
3842 character == ';') {
3843 continue;
3844 }
3845 ss << character;
3846 }
3847 ss << "\xFF";
3848 std::string initial(ss.str());
3849 std::string expected =
3850 "/%01%02%03%04%05%06%07%08%09%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%"
3851 "1A%1B%1C%1D%1E%1F%20!%22%23$%&'()*+,-./"
3852 "0123456789:%3C=%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/"
3853 "]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%80%81%82%83%84%85%86%87%"
3854 "88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%"
3855 "A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%"
3856 "B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%"
3857 "D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%"
3858 "E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
3859 cc = CanonicalCookie::CreateSanitizedCookie(
3860 GURL("http://www.foo.com"), "A", "B", std::string(), initial,
3861 base::Time(), base::Time(), base::Time(), false /*secure*/,
3862 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3863 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3864 absl::nullopt /*partition_key*/, &status);
3865 ASSERT_TRUE(cc);
3866 EXPECT_EQ(expected, cc->Path());
3867 EXPECT_TRUE(status.IsInclude());
3868
3869 // Empty name and value.
3870 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3871 GURL("http://www.foo.com"), "", "", std::string(), "/", base::Time(),
3872 base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
3873 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3874 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3875 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3876 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3877
3878 // Check that value can contain an equal sign, even when no name is present.
3879 // Note that in newer drafts of RFC6265bis, it is specified that a cookie with
3880 // an empty name and a value containing an equal sign should result in a
3881 // corresponding cookie line that omits the preceding equal sign. This means
3882 // that the cookie line won't be deserialized into the original cookie in this
3883 // case. For now, we'll test for compliance with the spec here, but we aim to
3884 // collect metrics and hopefully fix this in the spec (and then in
3885 // CanonicalCookie) at some point.
3886 // For reference, see: https://github.com/httpwg/http-extensions/pull/1592
3887 cc = CanonicalCookie::CreateSanitizedCookie(
3888 GURL("http://www.foo.com"), "", "ambiguous=value", std::string(),
3889 std::string(), base::Time(), base::Time(), base::Time(), false /*secure*/,
3890 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3891 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3892 absl::nullopt /*partition_key*/, &status);
3893 EXPECT_TRUE(cc);
3894 std::vector<std::unique_ptr<CanonicalCookie>> cookies;
3895 cookies.push_back(std::move(cc));
3896 MatchCookieLineToVector("ambiguous=value", cookies);
3897
3898 // Check that name can't contain an equal sign ("ambiguous=name=value" should
3899 // correctly be parsed as name: "ambiguous" and value "name=value", so
3900 // allowing this case would result in cookies that can't serialize correctly).
3901 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3902 GURL("http://www.foo.com"), "ambiguous=name", "value", std::string(),
3903 std::string(), base::Time(), base::Time(), base::Time(), false /*secure*/,
3904 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3905 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3906 absl::nullopt /*partition_key*/, &status));
3907 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3908 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3909
3910 // A __Secure- cookie must be Secure.
3911 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3912 GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
3913 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3914 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3915 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3916 EXPECT_TRUE(status.IsInclude());
3917 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3918 GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
3919 two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
3920 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3921 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3922 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3923 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3924
3925 // A __Host- cookie must be Secure.
3926 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3927 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3928 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3929 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3930 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3931 EXPECT_TRUE(status.IsInclude());
3932 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3933 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3934 two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
3935 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3936 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3937 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3938 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3939
3940 // A __Host- cookie must have path "/".
3941 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3942 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3943 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3944 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3945 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3946 EXPECT_TRUE(status.IsInclude());
3947 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3948 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/foo",
3949 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3950 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3951 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3952 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3953 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3954
3955 // A __Host- cookie must not specify a domain.
3956 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3957 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3958 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3959 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3960 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3961 EXPECT_TRUE(status.IsInclude());
3962 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3963 GURL("https://www.foo.com"), "__Host-A", "B", ".www.foo.com", "/",
3964 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3965 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3966 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3967 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3968 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3969
3970 // Without __Host- prefix, this is a valid host cookie because it does not
3971 // specify a domain.
3972 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3973 GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
3974 one_hour_from_now, one_hour_ago, true, false,
3975 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3976 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3977 EXPECT_TRUE(status.IsInclude());
3978
3979 // Without __Host- prefix, this is a valid domain (not host) cookie.
3980 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3981 GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
3982 one_hour_from_now, one_hour_ago, true, false,
3983 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3984 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3985 EXPECT_TRUE(status.IsInclude());
3986
3987 // The __Host- prefix should not prevent otherwise-valid host cookies from
3988 // being accepted.
3989 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3990 GURL("https://127.0.0.1"), "A", "B", std::string(), "/", two_hours_ago,
3991 one_hour_from_now, one_hour_ago, true, false,
3992 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3993 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3994 EXPECT_TRUE(status.IsInclude());
3995 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3996 GURL("https://127.0.0.1"), "__Host-A", "B", std::string(), "/",
3997 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3998 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3999 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4000 EXPECT_TRUE(status.IsInclude());
4001
4002 // Host cookies should not specify domain unless it is an IP address that
4003 // matches the URL.
4004 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4005 GURL("https://127.0.0.1"), "A", "B", "127.0.0.1", "/", two_hours_ago,
4006 one_hour_from_now, one_hour_ago, true, false,
4007 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4008 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4009 EXPECT_TRUE(status.IsInclude());
4010 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4011 GURL("https://127.0.0.1"), "__Host-A", "B", "127.0.0.1", "/",
4012 two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
4013 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4014 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4015 EXPECT_TRUE(status.IsInclude());
4016
4017 // Cookies with hidden prefixes should be rejected.
4018
4019 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4020 GURL("https://www.foo.com"), "", "__Host-A=B", "", "/", two_hours_ago,
4021 one_hour_from_now, one_hour_ago, true, false,
4022 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4023 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4024 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4025 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4026
4027 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4028 GURL("https://www.foo.com"), "", "__Host-A", "", "/", two_hours_ago,
4029 one_hour_from_now, one_hour_ago, true, false,
4030 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4031 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4032 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4033 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4034
4035 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4036 GURL("https://www.foo.com"), "", "__Secure-A=B", "", "/", two_hours_ago,
4037 one_hour_from_now, one_hour_ago, true, false,
4038 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4039 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4040 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4041 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4042
4043 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4044 GURL("https://www.foo.com"), "", "__Secure-A", "", "/", two_hours_ago,
4045 one_hour_from_now, one_hour_ago, true, false,
4046 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4047 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4048 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4049 {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4050
4051 // While tricky, this aren't considered hidden prefixes and should succeed.
4052 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4053 GURL("https://www.foo.com"), "A", "__Host-A=B", "", "/", two_hours_ago,
4054 one_hour_from_now, one_hour_ago, true, false,
4055 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4056 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4057 EXPECT_TRUE(status.IsInclude());
4058
4059 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4060 GURL("https://www.foo.com"), "A", "__Secure-A=B", "", "/", two_hours_ago,
4061 one_hour_from_now, one_hour_ago, true, false,
4062 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4063 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4064 EXPECT_TRUE(status.IsInclude());
4065
4066 // SameParty attribute requires Secure and forbids SameSite=Strict.
4067 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4068 GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4069 one_hour_from_now, one_hour_ago, true /*secure*/, false,
4070 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4071 true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4072 EXPECT_TRUE(status.IsInclude());
4073 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4074 GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4075 one_hour_from_now, one_hour_ago, false /*secure*/, false,
4076 CookieSameSite::LAX_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4077 true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4078 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4079 {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4080 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4081 GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4082 one_hour_from_now, one_hour_ago, true /*secure*/, false,
4083 CookieSameSite::STRICT_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4084 true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4085 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4086 {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4087 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4088 GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4089 one_hour_from_now, one_hour_ago, false /*secure*/, false,
4090 CookieSameSite::STRICT_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4091 true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4092 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4093 {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4094
4095 // Partitioned attribute requires __Host- and forbids SameParty.
4096 status = CookieInclusionStatus();
4097 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4098 GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
4099 two_hours_ago, one_hour_from_now, one_hour_ago, true /*secure*/, false,
4100 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4101 false /*same_party*/,
4102 absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4103 GURL("https://toplevelsite.com"))),
4104 &status));
4105 EXPECT_TRUE(status.IsInclude());
4106 // No __Host- prefix is still valid if the cookie still has Secure, Path=/,
4107 // and no Domain.
4108 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4109 GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
4110 one_hour_from_now, one_hour_ago, true /*secure*/, false,
4111 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4112 false /*same_party*/,
4113 absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4114 GURL("https://toplevelsite.com"))),
4115 &status));
4116 EXPECT_TRUE(status.IsInclude());
4117 status = CookieInclusionStatus();
4118 // Invalid: Not Secure.
4119 status = CookieInclusionStatus();
4120 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4121 GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
4122 one_hour_from_now, one_hour_ago, /*secure=*/false, /*http_only=*/false,
4123 CookieSameSite::LAX_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4124 /*same_party=*/false,
4125 absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4126 GURL("https://toplevelsite.com"))),
4127 &status));
4128 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4129 {CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED}));
4130 // Invalid: invalid Path.
4131 status = CookieInclusionStatus();
4132 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4133 GURL("https://www.foo.com"), "A", "B", std::string(), "/foobar",
4134 two_hours_ago, one_hour_from_now, one_hour_ago, /*secure=*/true,
4135 /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
4136 CookiePriority::COOKIE_PRIORITY_DEFAULT,
4137 /*same_party=*/false,
4138 absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4139 GURL("https://toplevelsite.com"))),
4140 &status));
4141 EXPECT_TRUE(status.IsInclude());
4142 // Domain attribute present is still valid.
4143 status = CookieInclusionStatus();
4144 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4145 GURL("https://www.foo.com"), "A", "B", ".foo.com", "/", two_hours_ago,
4146 one_hour_from_now, one_hour_ago, /*secure=*/true, /*http_only=*/false,
4147 CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4148 /*same_party=*/false,
4149 absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4150 GURL("https://toplevelsite.com"))),
4151 &status));
4152 EXPECT_TRUE(status.IsInclude());
4153
4154 status = CookieInclusionStatus();
4155
4156 // Check that CreateSanitizedCookie can gracefully fail on inputs that would
4157 // crash cookie_util::GetCookieDomainWithString due to failing
4158 // DCHECKs. Specifically, GetCookieDomainWithString requires that if the
4159 // domain is empty or the URL's host matches the domain, then the URL's host
4160 // must pass DomainIsHostOnly; it must not begin with a period.
4161 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4162 GURL("http://..."), "A", "B", "...", "/", base::Time(), base::Time(),
4163 base::Time(), false /*secure*/, false /*httponly*/,
4164 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4165 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4166 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4167 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4168 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4169 GURL("http://."), "A", "B", std::string(), "/", base::Time(),
4170 base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
4171 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4172 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4173 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4174 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4175 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4176 GURL("http://.chromium.org"), "A", "B", ".chromium.org", "/",
4177 base::Time(), base::Time(), base::Time(), false /*secure*/,
4178 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4179 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4180 absl::nullopt /*partition_key*/, &status));
4181 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4182 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4183
4184 // Check that a file URL with an IPv6 host, and matching IPv6 domain, are
4185 // valid.
4186 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4187 GURL("file://[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
4188 base::Time(), false /*secure*/, false /*httponly*/,
4189 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4190 false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4191 EXPECT_TRUE(status.IsInclude());
4192
4193 // On Windows, URLs beginning with two backslashes are considered file
4194 // URLs. On other platforms, they are invalid.
4195 auto double_backslash_ipv6_cookie = CanonicalCookie::CreateSanitizedCookie(
4196 GURL("\\\\[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
4197 base::Time(), false /*secure*/, false /*httponly*/,
4198 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4199 false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4200 #if BUILDFLAG(IS_WIN)
4201 EXPECT_TRUE(double_backslash_ipv6_cookie);
4202 EXPECT_TRUE(double_backslash_ipv6_cookie->IsCanonical());
4203 EXPECT_TRUE(status.IsInclude());
4204 #else
4205 EXPECT_FALSE(double_backslash_ipv6_cookie);
4206 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4207 {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4208 #endif
4209
4210 // Confirm multiple error types can be set.
4211 EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4212 GURL(""), "", "", "", "", base::Time(), base::Time(), base::Time::Now(),
4213 true /*secure*/, true /*httponly*/, CookieSameSite::STRICT_MODE,
4214 COOKIE_PRIORITY_DEFAULT, true /*same_party*/,
4215 absl::nullopt /*partition_key*/, &status));
4216 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4217 {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE,
4218 CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN,
4219 CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4220
4221 // Check that RFC6265bis name + value string length limits are enforced.
4222 std::string max_name(ParsedCookie::kMaxCookieNamePlusValueSize, 'a');
4223 std::string max_value(ParsedCookie::kMaxCookieNamePlusValueSize, 'b');
4224 std::string almost_max_name = max_name.substr(1, std::string::npos);
4225 std::string almost_max_value = max_value.substr(1, std::string::npos);
4226
4227 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4228 GURL("http://www.foo.com/foo"), max_name, "", std::string(), "/foo",
4229 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4230 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4231 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4232 absl::nullopt /*partition_key*/, &status));
4233 EXPECT_TRUE(status.IsInclude());
4234 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4235 GURL("http://www.foo.com/foo"), "", max_value, std::string(), "/foo",
4236 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4237 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4238 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4239 absl::nullopt /*partition_key*/, &status));
4240 EXPECT_TRUE(status.IsInclude());
4241 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4242 GURL("http://www.foo.com/foo"), almost_max_name, "b", std::string(),
4243 "/foo", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4244 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4245 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4246 absl::nullopt /*partition_key*/, &status));
4247 EXPECT_TRUE(status.IsInclude());
4248 EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4249 GURL("http://www.foo.com/foo"), "a", almost_max_value, std::string(),
4250 "/foo", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4251 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4252 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4253 absl::nullopt /*partition_key*/, &status));
4254 EXPECT_TRUE(status.IsInclude());
4255
4256 cc = CanonicalCookie::CreateSanitizedCookie(
4257 GURL("http://www.foo.com/foo"), max_name, "X", std::string(), "/foo",
4258 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4259 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4260 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4261 absl::nullopt /*partition_key*/, &status);
4262 EXPECT_FALSE(cc);
4263 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4264 {CookieInclusionStatus::EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE}));
4265
4266 cc = CanonicalCookie::CreateSanitizedCookie(
4267 GURL("http://www.foo.com/foo"), "X", max_value, std::string(), "/foo",
4268 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4269 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4270 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4271 absl::nullopt /*partition_key*/, &status);
4272 EXPECT_FALSE(cc);
4273 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4274 {CookieInclusionStatus::EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE}));
4275
4276 // Check that the RFC6265bis attribute value size limits apply to the Path
4277 // attribute value.
4278 std::string almost_max_path(ParsedCookie::kMaxCookieAttributeValueSize - 1,
4279 'c');
4280 std::string max_path = "/" + almost_max_path;
4281 std::string too_long_path = "/X" + almost_max_path;
4282
4283 cc = CanonicalCookie::CreateSanitizedCookie(
4284 GURL("http://www.foo.com" + max_path), "name", "value", std::string(),
4285 max_path, one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4286 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4287 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4288 absl::nullopt /*partition_key*/, &status);
4289 EXPECT_TRUE(cc);
4290 EXPECT_EQ(max_path, cc->Path());
4291 EXPECT_TRUE(status.IsInclude());
4292
4293 cc = CanonicalCookie::CreateSanitizedCookie(
4294 GURL("http://www.foo.com/path-attr-from-url/"), "name", "value",
4295 std::string(), too_long_path, one_hour_ago, one_hour_from_now,
4296 base::Time(), false /*secure*/, false /*httponly*/,
4297 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4298 false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4299 EXPECT_FALSE(cc);
4300 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4301 {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
4302
4303 // Check that length limits on the Path attribute value are not enforced
4304 // in the case where no Path attribute is specified and the path value is
4305 // implicitly set from the URL.
4306 cc = CanonicalCookie::CreateSanitizedCookie(
4307 GURL("http://www.foo.com" + too_long_path + "/"), "name", "value",
4308 std::string(), std::string(), one_hour_ago, one_hour_from_now,
4309 base::Time(), false /*secure*/, false /*httponly*/,
4310 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4311 false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4312 EXPECT_TRUE(cc);
4313 EXPECT_EQ(too_long_path, cc->Path());
4314 EXPECT_TRUE(status.IsInclude());
4315
4316 // The Path attribute value gets URL-encoded, so ensure that the size
4317 // limit is enforced after this (to avoid setting cookies where the Path
4318 // attribute value would otherwise exceed the lengths specified in the
4319 // RFC).
4320 std::string expanding_path(ParsedCookie::kMaxCookieAttributeValueSize / 2,
4321 '#');
4322 expanding_path = "/" + expanding_path;
4323
4324 cc = CanonicalCookie::CreateSanitizedCookie(
4325 GURL("http://www.foo.com/path-attr-from-url/"), "name", "value",
4326 std::string(), expanding_path, one_hour_ago, one_hour_from_now,
4327 base::Time(), false /*secure*/, false /*httponly*/,
4328 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4329 false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4330 EXPECT_FALSE(cc);
4331 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4332 {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
4333
4334 // Check that the RFC6265bis attribute value size limits apply to the Domain
4335 // attribute value.
4336 std::string max_domain(ParsedCookie::kMaxCookieAttributeValueSize, 'd');
4337 max_domain.replace(ParsedCookie::kMaxCookieAttributeValueSize - 4, 4, ".com");
4338 std::string too_long_domain = "x" + max_domain;
4339
4340 cc = CanonicalCookie::CreateSanitizedCookie(
4341 GURL("http://" + max_domain + "/"), "name", "value", max_domain, "/",
4342 one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4343 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4344 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4345 absl::nullopt /*partition_key*/, &status);
4346 EXPECT_TRUE(cc);
4347 EXPECT_EQ(max_domain, cc->DomainWithoutDot());
4348 EXPECT_TRUE(status.IsInclude());
4349 cc = CanonicalCookie::CreateSanitizedCookie(
4350 GURL("http://www.domain-from-url.com/"), "name", "value", too_long_domain,
4351 "/", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4352 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4353 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4354 absl::nullopt /*partition_key*/, &status);
4355 EXPECT_FALSE(cc);
4356 EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4357 {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
4358 // Check that length limits on the Domain attribute value are not enforced
4359 // in the case where no Domain attribute is specified and the domain value
4360 // is implicitly set from the URL.
4361 cc = CanonicalCookie::CreateSanitizedCookie(
4362 GURL("http://" + too_long_domain + "/"), "name", "value", std::string(),
4363 "/", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4364 false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4365 COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4366 absl::nullopt /*partition_key*/, &status);
4367 EXPECT_TRUE(cc);
4368 EXPECT_EQ(too_long_domain, cc->DomainWithoutDot());
4369 EXPECT_TRUE(status.IsInclude());
4370 }
4371
TEST(CanonicalCookieTest,FromStorage)4372 TEST(CanonicalCookieTest, FromStorage) {
4373 base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
4374 base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
4375 base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
4376
4377 std::unique_ptr<CanonicalCookie> cc = CanonicalCookie::FromStorage(
4378 "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4379 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4380 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4381 false /*same_party*/, absl::nullopt /*partition_key*/,
4382 CookieSourceScheme::kSecure, 87);
4383 EXPECT_TRUE(cc);
4384 EXPECT_EQ("A", cc->Name());
4385 EXPECT_EQ("B", cc->Value());
4386 EXPECT_EQ("www.foo.com", cc->Domain());
4387 EXPECT_EQ("/bar", cc->Path());
4388 EXPECT_EQ(two_hours_ago, cc->CreationDate());
4389 EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
4390 EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
4391 EXPECT_EQ(one_hour_ago, cc->LastUpdateDate());
4392 EXPECT_FALSE(cc->IsSecure());
4393 EXPECT_FALSE(cc->IsHttpOnly());
4394 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite());
4395 EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority());
4396 EXPECT_EQ(CookieSourceScheme::kSecure, cc->SourceScheme());
4397 EXPECT_FALSE(cc->IsDomainCookie());
4398 EXPECT_EQ(cc->SourcePort(), 87);
4399
4400 // Should return nullptr when the cookie is not canonical.
4401 // In this case the cookie is not canonical because its name attribute
4402 // contains a newline character.
4403 EXPECT_FALSE(CanonicalCookie::FromStorage(
4404 "A\n", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4405 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4406 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4407 false /*same_party*/, absl::nullopt /*partition_key*/,
4408 CookieSourceScheme::kSecure, 80));
4409
4410 // If the port information gets corrupted out of the valid range
4411 // FromStorage() should result in a PORT_INVALID.
4412 std::unique_ptr<CanonicalCookie> cc2 = CanonicalCookie::FromStorage(
4413 "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4414 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4415 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4416 false /*same_party*/, absl::nullopt /*partition_key*/,
4417 CookieSourceScheme::kSecure, 80000);
4418
4419 EXPECT_EQ(cc2->SourcePort(), url::PORT_INVALID);
4420
4421 // Test port edge cases: unspecified.
4422 std::unique_ptr<CanonicalCookie> cc3 = CanonicalCookie::FromStorage(
4423 "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4424 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4425 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4426 false /*same_party*/, absl::nullopt /*partition_key*/,
4427 CookieSourceScheme::kSecure, url::PORT_UNSPECIFIED);
4428 EXPECT_EQ(cc3->SourcePort(), url::PORT_UNSPECIFIED);
4429
4430 // Test port edge cases: invalid.
4431 std::unique_ptr<CanonicalCookie> cc4 = CanonicalCookie::FromStorage(
4432 "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4433 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4434 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4435 false /*same_party*/, absl::nullopt /*partition_key*/,
4436 CookieSourceScheme::kSecure, url::PORT_INVALID);
4437 EXPECT_EQ(cc4->SourcePort(), url::PORT_INVALID);
4438 }
4439
TEST(CanonicalCookieTest,IsSetPermittedInContext)4440 TEST(CanonicalCookieTest, IsSetPermittedInContext) {
4441 GURL url("https://www.example.com/test");
4442 GURL insecure_url("http://www.example.com/test");
4443 base::Time current_time = base::Time::Now();
4444
4445 auto cookie_scriptable = CanonicalCookie::CreateUnsafeCookieForTesting(
4446 "A", "2", "www.example.com", "/test", current_time, base::Time(),
4447 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4448 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
4449 auto cookie_httponly = CanonicalCookie::CreateUnsafeCookieForTesting(
4450 "A", "2", "www.example.com", "/test", current_time, base::Time(),
4451 base::Time(), base::Time(), true /*secure*/, true /*httponly*/,
4452 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
4453
4454 CookieOptions context_script;
4455 CookieOptions context_network;
4456 context_network.set_include_httponly();
4457
4458 EXPECT_THAT(
4459 cookie_scriptable->IsSetPermittedInContext(
4460 GURL("file://foo/bar.txt"), context_network,
4461 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4462 false /* delegate_treats_url_as_trustworthy */,
4463 CookieSamePartyStatus::kNoSamePartyEnforcement),
4464 kCookieableSchemes),
4465 MatchesCookieAccessResult(
4466 CookieInclusionStatus::MakeFromReasonsForTesting({
4467 CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME,
4468 CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
4469 }),
4470 _, _, false));
4471
4472 EXPECT_THAT(
4473 cookie_scriptable->IsSetPermittedInContext(
4474 insecure_url, context_network,
4475 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4476 false /* delegate_treats_url_as_trustworthy */,
4477 CookieSamePartyStatus::kNoSamePartyEnforcement),
4478 kCookieableSchemes),
4479 MatchesCookieAccessResult(
4480 CookieInclusionStatus::MakeFromReasonsForTesting(
4481 {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}),
4482 _, _, false));
4483 EXPECT_THAT(
4484 cookie_scriptable->IsSetPermittedInContext(
4485 url, context_network,
4486 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4487 false /* delegate_treats_url_as_trustworthy */,
4488 CookieSamePartyStatus::kNoSamePartyEnforcement),
4489 kCookieableSchemes),
4490 MatchesCookieAccessResult(IsInclude(), _, _, true));
4491 EXPECT_THAT(
4492 cookie_scriptable->IsSetPermittedInContext(
4493 url, context_script,
4494 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4495 false /* delegate_treats_url_as_trustworthy */,
4496 CookieSamePartyStatus::kNoSamePartyEnforcement),
4497 kCookieableSchemes),
4498 MatchesCookieAccessResult(IsInclude(), _, _, true));
4499
4500 EXPECT_THAT(
4501 cookie_httponly->IsSetPermittedInContext(
4502 url, context_network,
4503 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4504 false /* delegate_treats_url_as_trustworthy */,
4505 CookieSamePartyStatus::kNoSamePartyEnforcement),
4506 kCookieableSchemes),
4507 MatchesCookieAccessResult(IsInclude(), _, _, true));
4508 EXPECT_THAT(
4509 cookie_httponly->IsSetPermittedInContext(
4510 url, context_script,
4511 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4512 false /* delegate_treats_url_as_trustworthy */,
4513 CookieSamePartyStatus::kNoSamePartyEnforcement),
4514 kCookieableSchemes),
4515 MatchesCookieAccessResult(
4516 CookieInclusionStatus::MakeFromReasonsForTesting(
4517 {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}),
4518 _, _, true));
4519
4520 CookieOptions context_cross_site;
4521 CookieOptions context_same_site_lax;
4522 context_same_site_lax.set_same_site_cookie_context(
4523 CookieOptions::SameSiteCookieContext(
4524 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
4525 CookieOptions context_same_site_strict;
4526 context_same_site_strict.set_same_site_cookie_context(
4527 CookieOptions::SameSiteCookieContext(
4528 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
4529
4530 CookieOptions context_same_site_strict_to_lax;
4531 context_same_site_strict_to_lax.set_same_site_cookie_context(
4532 CookieOptions::SameSiteCookieContext(
4533 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
4534 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
4535
4536 CookieOptions context_same_site_strict_to_cross;
4537 context_same_site_strict_to_cross.set_same_site_cookie_context(
4538 CookieOptions::SameSiteCookieContext(
4539 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
4540 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
4541
4542 CookieOptions context_same_site_lax_to_cross;
4543 context_same_site_lax_to_cross.set_same_site_cookie_context(
4544 CookieOptions::SameSiteCookieContext(
4545 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
4546 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
4547
4548 {
4549 auto cookie_same_site_unrestricted =
4550 CanonicalCookie::CreateUnsafeCookieForTesting(
4551 "A", "2", "www.example.com", "/test", current_time, base::Time(),
4552 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4553 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
4554
4555 EXPECT_THAT(
4556 cookie_same_site_unrestricted->IsSetPermittedInContext(
4557 url, context_cross_site,
4558 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4559 false /* delegate_treats_url_as_trustworthy */,
4560 CookieSamePartyStatus::kNoSamePartyEnforcement),
4561 kCookieableSchemes),
4562 MatchesCookieAccessResult(IsInclude(), _, _, true));
4563 EXPECT_THAT(
4564 cookie_same_site_unrestricted->IsSetPermittedInContext(
4565 url, context_same_site_lax,
4566 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4567 false /* delegate_treats_url_as_trustworthy */,
4568 CookieSamePartyStatus::kNoSamePartyEnforcement),
4569 kCookieableSchemes),
4570 MatchesCookieAccessResult(IsInclude(), _, _, true));
4571 EXPECT_THAT(
4572 cookie_same_site_unrestricted->IsSetPermittedInContext(
4573 url, context_same_site_strict,
4574 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4575 false /* delegate_treats_url_as_trustworthy */,
4576 CookieSamePartyStatus::kNoSamePartyEnforcement),
4577 kCookieableSchemes),
4578 MatchesCookieAccessResult(IsInclude(), _, _, true));
4579
4580 {
4581 // Schemeful Same-Site disabled.
4582 base::test::ScopedFeatureList feature_list;
4583 feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
4584
4585 EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4586 url, context_same_site_strict_to_lax,
4587 CookieAccessParams(
4588 CookieAccessSemantics::UNKNOWN,
4589 false /* delegate_treats_url_as_trustworthy */,
4590 CookieSamePartyStatus::kNoSamePartyEnforcement),
4591 kCookieableSchemes),
4592 MatchesCookieAccessResult(
4593 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4594 _, _, true));
4595 EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4596 url, context_same_site_strict_to_cross,
4597 CookieAccessParams(
4598 CookieAccessSemantics::UNKNOWN,
4599 false /* delegate_treats_url_as_trustworthy */,
4600 CookieSamePartyStatus::kNoSamePartyEnforcement),
4601 kCookieableSchemes),
4602 MatchesCookieAccessResult(
4603 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4604 _, _, true));
4605 EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4606 url, context_same_site_lax_to_cross,
4607 CookieAccessParams(
4608 CookieAccessSemantics::UNKNOWN,
4609 false /* delegate_treats_url_as_trustworthy */,
4610 CookieSamePartyStatus::kNoSamePartyEnforcement),
4611 kCookieableSchemes),
4612 MatchesCookieAccessResult(
4613 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4614 _, _, true));
4615 }
4616 {
4617 // Schemeful Same-Site enabled.
4618 base::test::ScopedFeatureList feature_list;
4619 feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4620
4621 EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4622 url, context_same_site_strict_to_lax,
4623 CookieAccessParams(
4624 CookieAccessSemantics::UNKNOWN,
4625 false /* delegate_treats_url_as_trustworthy */,
4626 CookieSamePartyStatus::kNoSamePartyEnforcement),
4627 kCookieableSchemes),
4628 MatchesCookieAccessResult(
4629 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4630 _, _, true));
4631 EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4632 url, context_same_site_strict_to_cross,
4633 CookieAccessParams(
4634 CookieAccessSemantics::UNKNOWN,
4635 false /* delegate_treats_url_as_trustworthy */,
4636 CookieSamePartyStatus::kNoSamePartyEnforcement),
4637 kCookieableSchemes),
4638 MatchesCookieAccessResult(
4639 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4640 _, _, true));
4641 EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4642 url, context_same_site_lax_to_cross,
4643 CookieAccessParams(
4644 CookieAccessSemantics::UNKNOWN,
4645 false /* delegate_treats_url_as_trustworthy */,
4646 CookieSamePartyStatus::kNoSamePartyEnforcement),
4647 kCookieableSchemes),
4648 MatchesCookieAccessResult(
4649 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4650 _, _, true));
4651 }
4652 }
4653
4654 {
4655 auto cookie_same_site_lax = CanonicalCookie::CreateUnsafeCookieForTesting(
4656 "A", "2", "www.example.com", "/test", current_time, base::Time(),
4657 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4658 CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false);
4659
4660 EXPECT_THAT(
4661 cookie_same_site_lax->IsSetPermittedInContext(
4662 url, context_cross_site,
4663 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4664 false /* delegate_treats_url_as_trustworthy */,
4665 CookieSamePartyStatus::kNoSamePartyEnforcement),
4666 kCookieableSchemes),
4667 MatchesCookieAccessResult(
4668 CookieInclusionStatus::MakeFromReasonsForTesting(
4669 {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}),
4670 _, _, true));
4671 EXPECT_THAT(
4672 cookie_same_site_lax->IsSetPermittedInContext(
4673 url, context_same_site_lax,
4674 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4675 false /* delegate_treats_url_as_trustworthy */,
4676 CookieSamePartyStatus::kNoSamePartyEnforcement),
4677 kCookieableSchemes),
4678 MatchesCookieAccessResult(IsInclude(), _, _, true));
4679 EXPECT_THAT(
4680 cookie_same_site_lax->IsSetPermittedInContext(
4681 url, context_same_site_strict,
4682 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4683 false /* delegate_treats_url_as_trustworthy */,
4684 CookieSamePartyStatus::kNoSamePartyEnforcement),
4685 kCookieableSchemes),
4686 MatchesCookieAccessResult(IsInclude(), _, _, true));
4687
4688 {
4689 // Schemeful Same-Site disabled.
4690 base::test::ScopedFeatureList feature_list;
4691 feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
4692
4693 EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4694 url, context_same_site_strict_to_lax,
4695 CookieAccessParams(
4696 CookieAccessSemantics::UNKNOWN,
4697 false /* delegate_treats_url_as_trustworthy */,
4698 CookieSamePartyStatus::kNoSamePartyEnforcement),
4699 kCookieableSchemes),
4700 MatchesCookieAccessResult(
4701 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4702 _, _, true));
4703 EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4704 url, context_same_site_strict_to_cross,
4705 CookieAccessParams(
4706 CookieAccessSemantics::UNKNOWN,
4707 false /* delegate_treats_url_as_trustworthy */,
4708 CookieSamePartyStatus::kNoSamePartyEnforcement),
4709 kCookieableSchemes),
4710 MatchesCookieAccessResult(
4711 AllOf(IsInclude(),
4712 HasWarningReason(
4713 CookieInclusionStatus::
4714 WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE)),
4715 _, _, true));
4716 EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4717 url, context_same_site_lax_to_cross,
4718 CookieAccessParams(
4719 CookieAccessSemantics::UNKNOWN,
4720 false /* delegate_treats_url_as_trustworthy */,
4721 CookieSamePartyStatus::kNoSamePartyEnforcement),
4722 kCookieableSchemes),
4723 MatchesCookieAccessResult(
4724 AllOf(IsInclude(),
4725 HasWarningReason(
4726 CookieInclusionStatus::
4727 WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE)),
4728 _, _, true));
4729 }
4730 {
4731 // Schemeful Same-Site enabled.
4732 base::test::ScopedFeatureList feature_list;
4733 feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4734
4735 EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4736 url, context_same_site_strict_to_lax,
4737 CookieAccessParams(
4738 CookieAccessSemantics::UNKNOWN,
4739 false /* delegate_treats_url_as_trustworthy */,
4740 CookieSamePartyStatus::kNoSamePartyEnforcement),
4741 kCookieableSchemes),
4742 MatchesCookieAccessResult(
4743 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4744 _, _, true));
4745 EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4746 url, context_same_site_strict_to_cross,
4747 CookieAccessParams(
4748 CookieAccessSemantics::UNKNOWN,
4749 false /* delegate_treats_url_as_trustworthy */,
4750 CookieSamePartyStatus::kNoSamePartyEnforcement),
4751 kCookieableSchemes),
4752 MatchesCookieAccessResult(
4753 AllOf(Not(IsInclude()),
4754 HasWarningReason(
4755 CookieInclusionStatus::
4756 WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE),
4757 HasExclusionReason(
4758 CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)),
4759 _, _, true));
4760 EXPECT_THAT(
4761 cookie_same_site_lax->IsSetPermittedInContext(
4762 url, context_same_site_lax_to_cross,
4763 CookieAccessParams(
4764 CookieAccessSemantics::UNKNOWN,
4765 false /* delegate_treats_url_as_trustworthy */,
4766 CookieSamePartyStatus::kNoSamePartyEnforcement),
4767 kCookieableSchemes),
4768 MatchesCookieAccessResult(
4769 AllOf(Not(IsInclude()),
4770 HasWarningReason(CookieInclusionStatus::
4771 WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE),
4772 HasExclusionReason(
4773 CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)),
4774 _, _, true));
4775 }
4776 }
4777
4778 {
4779 auto cookie_same_site_strict =
4780 CanonicalCookie::CreateUnsafeCookieForTesting(
4781 "A", "2", "www.example.com", "/test", current_time, base::Time(),
4782 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4783 CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
4784
4785 // TODO(morlovich): Do compatibility testing on whether set of strict in lax
4786 // context really should be accepted.
4787 EXPECT_THAT(
4788 cookie_same_site_strict->IsSetPermittedInContext(
4789 url, context_cross_site,
4790 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4791 false /* delegate_treats_url_as_trustworthy */,
4792 CookieSamePartyStatus::kNoSamePartyEnforcement),
4793 kCookieableSchemes),
4794 MatchesCookieAccessResult(
4795 CookieInclusionStatus::MakeFromReasonsForTesting(
4796 {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT}),
4797 _, _, true));
4798 EXPECT_THAT(
4799 cookie_same_site_strict->IsSetPermittedInContext(
4800 url, context_same_site_lax,
4801 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4802 false /* delegate_treats_url_as_trustworthy */,
4803 CookieSamePartyStatus::kNoSamePartyEnforcement),
4804 kCookieableSchemes),
4805 MatchesCookieAccessResult(IsInclude(), _, _, true));
4806 EXPECT_THAT(
4807 cookie_same_site_strict->IsSetPermittedInContext(
4808 url, context_same_site_strict,
4809 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4810 false /* delegate_treats_url_as_trustworthy */,
4811 CookieSamePartyStatus::kNoSamePartyEnforcement),
4812 kCookieableSchemes),
4813 MatchesCookieAccessResult(IsInclude(), _, _, true));
4814
4815 {
4816 // Schemeful Same-Site disabled.
4817 base::test::ScopedFeatureList feature_list;
4818 feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
4819
4820 EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4821 url, context_same_site_strict_to_lax,
4822 CookieAccessParams(
4823 CookieAccessSemantics::UNKNOWN,
4824 false /* delegate_treats_url_as_trustworthy */,
4825 CookieSamePartyStatus::kNoSamePartyEnforcement),
4826 kCookieableSchemes),
4827 MatchesCookieAccessResult(
4828 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4829 _, _, true));
4830 EXPECT_THAT(
4831 cookie_same_site_strict->IsSetPermittedInContext(
4832 url, context_same_site_strict_to_cross,
4833 CookieAccessParams(
4834 CookieAccessSemantics::UNKNOWN,
4835 false /* delegate_treats_url_as_trustworthy */,
4836 CookieSamePartyStatus::kNoSamePartyEnforcement),
4837 kCookieableSchemes),
4838 MatchesCookieAccessResult(
4839 AllOf(IsInclude(),
4840 HasWarningReason(
4841 CookieInclusionStatus::
4842 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE)),
4843 _, _, true));
4844 EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4845 url, context_same_site_lax_to_cross,
4846 CookieAccessParams(
4847 CookieAccessSemantics::UNKNOWN,
4848 false /* delegate_treats_url_as_trustworthy */,
4849 CookieSamePartyStatus::kNoSamePartyEnforcement),
4850 kCookieableSchemes),
4851 MatchesCookieAccessResult(
4852 AllOf(IsInclude(),
4853 HasWarningReason(
4854 CookieInclusionStatus::
4855 WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE)),
4856 _, _, true));
4857 }
4858 {
4859 // Schemeful Same-Site enabled.
4860 base::test::ScopedFeatureList feature_list;
4861 feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4862
4863 EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4864 url, context_same_site_strict_to_lax,
4865 CookieAccessParams(
4866 CookieAccessSemantics::UNKNOWN,
4867 false /* delegate_treats_url_as_trustworthy */,
4868 CookieSamePartyStatus::kNoSamePartyEnforcement),
4869 kCookieableSchemes),
4870 MatchesCookieAccessResult(
4871 AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4872 _, _, true));
4873 EXPECT_THAT(
4874 cookie_same_site_strict->IsSetPermittedInContext(
4875 url, context_same_site_strict_to_cross,
4876 CookieAccessParams(
4877 CookieAccessSemantics::UNKNOWN,
4878 false /* delegate_treats_url_as_trustworthy */,
4879 CookieSamePartyStatus::kNoSamePartyEnforcement),
4880 kCookieableSchemes),
4881 MatchesCookieAccessResult(
4882 AllOf(Not(IsInclude()),
4883 HasWarningReason(
4884 CookieInclusionStatus::
4885 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE),
4886 HasExclusionReason(
4887 CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)),
4888 _, _, true));
4889 EXPECT_THAT(
4890 cookie_same_site_strict->IsSetPermittedInContext(
4891 url, context_same_site_lax_to_cross,
4892 CookieAccessParams(
4893 CookieAccessSemantics::UNKNOWN,
4894 false /* delegate_treats_url_as_trustworthy */,
4895 CookieSamePartyStatus::kNoSamePartyEnforcement),
4896 kCookieableSchemes),
4897 MatchesCookieAccessResult(
4898 AllOf(Not(IsInclude()),
4899 HasWarningReason(
4900 CookieInclusionStatus::
4901 WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE),
4902 HasExclusionReason(
4903 CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)),
4904 _, _, true));
4905 }
4906
4907 // Even with Schemeful Same-Site enabled, cookies semantics could change the
4908 // inclusion.
4909 {
4910 base::test::ScopedFeatureList feature_list;
4911 feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4912
4913 EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4914 url, context_same_site_strict_to_cross,
4915 CookieAccessParams(
4916 CookieAccessSemantics::UNKNOWN,
4917 false /* delegate_treats_url_as_trustworthy */,
4918 CookieSamePartyStatus::kNoSamePartyEnforcement),
4919 kCookieableSchemes),
4920 MatchesCookieAccessResult(Not(IsInclude()), _, _, true));
4921 EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4922 url, context_same_site_strict_to_cross,
4923 CookieAccessParams(
4924 CookieAccessSemantics::NONLEGACY,
4925 false /* delegate_treats_url_as_trustworthy */,
4926 CookieSamePartyStatus::kNoSamePartyEnforcement),
4927 kCookieableSchemes),
4928 MatchesCookieAccessResult(Not(IsInclude()), _, _, true));
4929 // LEGACY semantics should allow cookies which Schemeful Same-Site would
4930 // normally block.
4931 EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4932 url, context_same_site_strict_to_cross,
4933 CookieAccessParams(
4934 CookieAccessSemantics::LEGACY,
4935 false /* delegate_treats_url_as_trustworthy */,
4936 CookieSamePartyStatus::kNoSamePartyEnforcement),
4937 kCookieableSchemes),
4938 MatchesCookieAccessResult(IsInclude(), _, _, true));
4939 }
4940 }
4941
4942 // Behavior of UNSPECIFIED depends on CookieAccessSemantics.
4943 auto cookie_same_site_unspecified =
4944 CanonicalCookie::CreateUnsafeCookieForTesting(
4945 "A", "2", "www.example.com", "/test", current_time, base::Time(),
4946 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4947 CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
4948
4949 EXPECT_THAT(
4950 cookie_same_site_unspecified->IsSetPermittedInContext(
4951 url, context_cross_site,
4952 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4953 false /* delegate_treats_url_as_trustworthy */,
4954 CookieSamePartyStatus::kNoSamePartyEnforcement),
4955 kCookieableSchemes),
4956 MatchesCookieAccessResult(
4957 HasExactlyExclusionReasonsForTesting(
4958 std::vector<CookieInclusionStatus::ExclusionReason>(
4959 {CookieInclusionStatus::
4960 EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX})),
4961 _, _, true));
4962 EXPECT_THAT(
4963 cookie_same_site_unspecified->IsSetPermittedInContext(
4964 url, context_same_site_lax,
4965 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4966 false /* delegate_treats_url_as_trustworthy */,
4967 CookieSamePartyStatus::kNoSamePartyEnforcement),
4968 kCookieableSchemes),
4969 MatchesCookieAccessResult(IsInclude(), _, _, true));
4970 EXPECT_THAT(
4971 cookie_same_site_unspecified->IsSetPermittedInContext(
4972 url, context_same_site_strict,
4973 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4974 false /* delegate_treats_url_as_trustworthy */,
4975 CookieSamePartyStatus::kNoSamePartyEnforcement),
4976 kCookieableSchemes),
4977 MatchesCookieAccessResult(IsInclude(), _, _, true));
4978 EXPECT_THAT(
4979 cookie_same_site_unspecified->IsSetPermittedInContext(
4980 url, context_cross_site,
4981 CookieAccessParams(CookieAccessSemantics::LEGACY,
4982 false /* delegate_treats_url_as_trustworthy */,
4983 CookieSamePartyStatus::kNoSamePartyEnforcement),
4984 kCookieableSchemes),
4985 MatchesCookieAccessResult(IsInclude(), _, _, true));
4986 EXPECT_THAT(
4987 cookie_same_site_unspecified->IsSetPermittedInContext(
4988 url, context_same_site_lax,
4989 CookieAccessParams(CookieAccessSemantics::LEGACY,
4990 false /* delegate_treats_url_as_trustworthy */,
4991 CookieSamePartyStatus::kNoSamePartyEnforcement),
4992 kCookieableSchemes),
4993 MatchesCookieAccessResult(IsInclude(), _, _, true));
4994 EXPECT_THAT(
4995 cookie_same_site_unspecified->IsSetPermittedInContext(
4996 url, context_same_site_strict,
4997 CookieAccessParams(CookieAccessSemantics::LEGACY,
4998 false /* delegate_treats_url_as_trustworthy */,
4999 CookieSamePartyStatus::kNoSamePartyEnforcement),
5000 kCookieableSchemes),
5001 MatchesCookieAccessResult(IsInclude(), _, _, true));
5002 EXPECT_THAT(
5003 cookie_same_site_unspecified->IsSetPermittedInContext(
5004 url, context_cross_site,
5005 CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5006 false /* delegate_treats_url_as_trustworthy */,
5007 CookieSamePartyStatus::kNoSamePartyEnforcement),
5008 kCookieableSchemes),
5009 MatchesCookieAccessResult(
5010 HasExactlyExclusionReasonsForTesting(
5011 std::vector<CookieInclusionStatus::ExclusionReason>(
5012 {CookieInclusionStatus::
5013 EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX})),
5014 _, _, true));
5015 EXPECT_THAT(
5016 cookie_same_site_unspecified->IsSetPermittedInContext(
5017 url, context_same_site_lax,
5018 CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5019 false /* delegate_treats_url_as_trustworthy */,
5020 CookieSamePartyStatus::kNoSamePartyEnforcement),
5021 kCookieableSchemes),
5022 MatchesCookieAccessResult(IsInclude(), _, _, true));
5023 EXPECT_THAT(
5024 cookie_same_site_unspecified->IsSetPermittedInContext(
5025 url, context_same_site_strict,
5026 CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5027 false /* delegate_treats_url_as_trustworthy */,
5028 CookieSamePartyStatus::kNoSamePartyEnforcement),
5029 kCookieableSchemes),
5030 MatchesCookieAccessResult(IsInclude(), _, _, true));
5031
5032 // Test IsSetPermittedInContext successfully chains warnings by passing
5033 // in a CookieAccessResult and expecting the result to have a
5034 // WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE
5035 CookieInclusionStatus status;
5036 std::string long_path(ParsedCookie::kMaxCookieAttributeValueSize, 'a');
5037
5038 std::unique_ptr<CanonicalCookie> cookie_with_long_path =
5039 CanonicalCookie::Create(url, "A=B; Path=/" + long_path, current_time,
5040 absl::nullopt, absl::nullopt, &status);
5041 CookieAccessResult cookie_access_result(status);
5042 CookieOptions cookie_with_long_path_options;
5043 EXPECT_THAT(
5044 cookie_with_long_path->IsSetPermittedInContext(
5045 url, cookie_with_long_path_options,
5046 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5047 false /* delegate_treats_url_as_trustworthy */,
5048 CookieSamePartyStatus::kNoSamePartyEnforcement),
5049 kCookieableSchemes, cookie_access_result),
5050 MatchesCookieAccessResult(
5051 HasWarningReason(
5052 CookieInclusionStatus::WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE),
5053 _, _, _));
5054 }
5055
TEST(CanonicalCookieTest,IsSetPermittedEffectiveSameSite)5056 TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
5057 GURL url("http://www.example.com/test");
5058 base::Time current_time = base::Time::Now();
5059 CookieOptions options;
5060
5061 // Test IsSetPermitted CookieEffectiveSameSite for
5062 // CanonicalCookie with CookieSameSite::NO_RESTRICTION.
5063 auto cookie_no_restriction = CanonicalCookie::CreateUnsafeCookieForTesting(
5064 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5065 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5066 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
5067
5068 EXPECT_THAT(
5069 cookie_no_restriction->IsSetPermittedInContext(
5070 url, options,
5071 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5072 false /* delegate_treats_url_as_trustworthy */,
5073 CookieSamePartyStatus::kNoSamePartyEnforcement),
5074 kCookieableSchemes),
5075 MatchesCookieAccessResult(_, CookieEffectiveSameSite::NO_RESTRICTION, _,
5076 false));
5077
5078 // Test IsSetPermitted CookieEffectiveSameSite for
5079 // CanonicalCookie with CookieSameSite::LAX_MODE.
5080 auto cookie_lax = CanonicalCookie::CreateUnsafeCookieForTesting(
5081 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5082 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5083 CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false);
5084
5085 EXPECT_THAT(
5086 cookie_lax->IsSetPermittedInContext(
5087 url, options,
5088 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5089 false /* delegate_treats_url_as_trustworthy */,
5090 CookieSamePartyStatus::kNoSamePartyEnforcement),
5091 kCookieableSchemes),
5092 MatchesCookieAccessResult(_, CookieEffectiveSameSite::LAX_MODE, _,
5093 false));
5094
5095 // Test IsSetPermitted CookieEffectiveSameSite for
5096 // CanonicalCookie with CookieSameSite::STRICT_MODE.
5097 auto cookie_strict = CanonicalCookie::CreateUnsafeCookieForTesting(
5098 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5099 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5100 CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
5101
5102 EXPECT_THAT(
5103 cookie_strict->IsSetPermittedInContext(
5104 url, options,
5105 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5106 false /* delegate_treats_url_as_trustworthy */,
5107 CookieSamePartyStatus::kNoSamePartyEnforcement),
5108 kCookieableSchemes),
5109 MatchesCookieAccessResult(_, CookieEffectiveSameSite::STRICT_MODE, _,
5110 false));
5111
5112 // Test IsSetPermitted CookieEffectiveSameSite for
5113 // CanonicalCookie with CookieSameSite::UNSPECIFIED.
5114 base::Time creation_time = base::Time::Now() - (kLaxAllowUnsafeMaxAge * 4);
5115 auto cookie_old_unspecified = CanonicalCookie::CreateUnsafeCookieForTesting(
5116 "A", "2", "www.example.com", "/test", creation_time, base::Time(),
5117 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5118 CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
5119 auto cookie_unspecified = CanonicalCookie::CreateUnsafeCookieForTesting(
5120 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5121 base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5122 CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
5123
5124 EXPECT_THAT(
5125 cookie_old_unspecified->IsSetPermittedInContext(
5126 url, options,
5127 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5128 false /* delegate_treats_url_as_trustworthy */,
5129 CookieSamePartyStatus::kNoSamePartyEnforcement),
5130 kCookieableSchemes),
5131 MatchesCookieAccessResult(_, CookieEffectiveSameSite::LAX_MODE, _,
5132 false));
5133
5134 EXPECT_THAT(
5135 cookie_unspecified->IsSetPermittedInContext(
5136 url, options,
5137 CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5138 false /* delegate_treats_url_as_trustworthy */,
5139 CookieSamePartyStatus::kNoSamePartyEnforcement),
5140 kCookieableSchemes),
5141 MatchesCookieAccessResult(
5142 _, CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, _, false));
5143
5144 EXPECT_THAT(
5145 cookie_unspecified->IsSetPermittedInContext(
5146 url, options,
5147 CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5148 false /* delegate_treats_url_as_trustworthy */,
5149 CookieSamePartyStatus::kNoSamePartyEnforcement),
5150 kCookieableSchemes),
5151 MatchesCookieAccessResult(
5152 _, CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, _, false));
5153
5154 EXPECT_THAT(
5155 cookie_unspecified->IsSetPermittedInContext(
5156 url, options,
5157 CookieAccessParams(CookieAccessSemantics::LEGACY,
5158 false /* delegate_treats_url_as_trustworthy */,
5159 CookieSamePartyStatus::kNoSamePartyEnforcement),
5160 kCookieableSchemes),
5161 MatchesCookieAccessResult(_, CookieEffectiveSameSite::NO_RESTRICTION, _,
5162 false));
5163 }
5164
TEST(CanonicalCookieTest,IsSetPermitted_AllowedToAccessSecureCookies)5165 TEST(CanonicalCookieTest, IsSetPermitted_AllowedToAccessSecureCookies) {
5166 GURL url("https://www.example.com/test");
5167 GURL insecure_url("http://www.example.com/test");
5168 GURL localhost_url("http://localhost/test");
5169 base::Time current_time = base::Time::Now();
5170 CookieOptions options;
5171
5172 for (bool secure : {false, true}) {
5173 for (CookieSameSite same_site : {
5174 CookieSameSite::UNSPECIFIED,
5175 CookieSameSite::NO_RESTRICTION,
5176 CookieSameSite::LAX_MODE,
5177 CookieSameSite::STRICT_MODE,
5178 }) {
5179 for (bool same_party : {false, true}) {
5180 // Skip setting SameParty and SameSite=Strict, since that is invalid.
5181 if (same_party && same_site == CookieSameSite::STRICT_MODE)
5182 continue;
5183 auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
5184 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5185 base::Time(), base::Time(), secure, false /*httponly*/, same_site,
5186 COOKIE_PRIORITY_DEFAULT, same_party);
5187
5188 for (bool delegate_treats_url_as_trustworthy : {false, true}) {
5189 for (CookieAccessSemantics access_semantics : {
5190 CookieAccessSemantics::UNKNOWN,
5191 CookieAccessSemantics::LEGACY,
5192 CookieAccessSemantics::NONLEGACY,
5193 }) {
5194 for (CookieSamePartyStatus same_party_status : {
5195 CookieSamePartyStatus::kNoSamePartyEnforcement,
5196 CookieSamePartyStatus::kEnforceSamePartyInclude,
5197 CookieSamePartyStatus::kEnforceSamePartyExclude,
5198 }) {
5199 // Skip invalid combinations of `same_party` and
5200 // `same_party_status`.
5201 bool has_same_party_enforcement =
5202 same_party_status !=
5203 CookieSamePartyStatus::kNoSamePartyEnforcement;
5204 if (has_same_party_enforcement != same_party) {
5205 continue;
5206 }
5207 EXPECT_THAT(
5208 cookie->IsSetPermittedInContext(
5209 url, options,
5210 CookieAccessParams(access_semantics,
5211 delegate_treats_url_as_trustworthy,
5212 same_party_status),
5213 kCookieableSchemes),
5214 MatchesCookieAccessResult(_, _, _, true));
5215 EXPECT_THAT(
5216 cookie->IsSetPermittedInContext(
5217 insecure_url, options,
5218 CookieAccessParams(access_semantics,
5219 delegate_treats_url_as_trustworthy,
5220 same_party_status),
5221 kCookieableSchemes),
5222 MatchesCookieAccessResult(
5223 _, _, _, delegate_treats_url_as_trustworthy));
5224 EXPECT_THAT(
5225 cookie->IsSetPermittedInContext(
5226 localhost_url, options,
5227 CookieAccessParams(access_semantics,
5228 delegate_treats_url_as_trustworthy,
5229 same_party_status),
5230 kCookieableSchemes),
5231 MatchesCookieAccessResult(_, _, _, true));
5232 }
5233 }
5234 }
5235 }
5236 }
5237 }
5238 }
5239
TEST(CanonicalCookieTest,IsSetPermitted_SameSiteNone_Metrics)5240 TEST(CanonicalCookieTest, IsSetPermitted_SameSiteNone_Metrics) {
5241 using SamePartyContextType = SamePartyContext::Type;
5242
5243 constexpr bool delegate_treats_url_as_trustworthy = false;
5244 const base::Time now = base::Time::Now();
5245 const auto make_cookie = [now](CookieSameSite same_site, bool same_party) {
5246 return CanonicalCookie::CreateUnsafeCookieForTesting(
5247 "A", "1", "www.example.com", "/test", now, base::Time(), base::Time(),
5248 base::Time(), true /* secure */, false /*httponly*/, same_site,
5249 COOKIE_PRIORITY_DEFAULT, same_party);
5250 };
5251 GURL url("https://www.example.com/test");
5252
5253 const std::unique_ptr<CanonicalCookie> same_site_none_cookie =
5254 make_cookie(CookieSameSite::NO_RESTRICTION, false /* same_party */);
5255 const std::unique_ptr<CanonicalCookie> same_party_cookie =
5256 make_cookie(CookieSameSite::NO_RESTRICTION, true /* same_party */);
5257 const std::unique_ptr<CanonicalCookie> same_site_lax_cookie =
5258 make_cookie(CookieSameSite::LAX_MODE, false /* same_party */);
5259 const std::unique_ptr<CanonicalCookie> same_site_strict_cookie =
5260 make_cookie(CookieSameSite::STRICT_MODE, false /* same_party */);
5261 CookieOptions options;
5262
5263 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
5264 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
5265 // Same as default, but just to be explicit:
5266 options.set_same_party_context(
5267 SamePartyContext(SamePartyContext::Type::kCrossParty));
5268 EXPECT_THAT(
5269 same_site_none_cookie->IsSetPermittedInContext(
5270 url, options,
5271 CookieAccessParams(CookieAccessSemantics::LEGACY,
5272 delegate_treats_url_as_trustworthy,
5273 CookieSamePartyStatus::kNoSamePartyEnforcement),
5274 kCookieableSchemes),
5275 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5276 EXPECT_THAT(
5277 same_party_cookie->IsSetPermittedInContext(
5278 url, options,
5279 CookieAccessParams(CookieAccessSemantics::LEGACY,
5280 delegate_treats_url_as_trustworthy,
5281 CookieSamePartyStatus::kEnforceSamePartyExclude),
5282 kCookieableSchemes),
5283 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
5284
5285 // Now tweak the context to allow a SameParty cookie (using the top&resource
5286 // definition) and make sure we get the right warning. (Note: we make the
5287 // "real" same-partyness value match the value computed for the metric, even
5288 // though they would differ unless we changed the real definition.) Then
5289 // check that if we modify the cookie as indicated, the set would be allowed.
5290 options.set_same_party_context(
5291 SamePartyContext(SamePartyContextType::kSameParty));
5292 EXPECT_THAT(
5293 same_site_none_cookie->IsSetPermittedInContext(
5294 url, options,
5295 CookieAccessParams(CookieAccessSemantics::LEGACY,
5296 delegate_treats_url_as_trustworthy,
5297 CookieSamePartyStatus::kNoSamePartyEnforcement),
5298 kCookieableSchemes),
5299 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5300 EXPECT_THAT(
5301 same_party_cookie->IsSetPermittedInContext(
5302 url, options,
5303 CookieAccessParams(CookieAccessSemantics::LEGACY,
5304 delegate_treats_url_as_trustworthy,
5305 CookieSamePartyStatus::kEnforceSamePartyInclude),
5306 kCookieableSchemes),
5307 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5308 EXPECT_THAT(
5309 same_site_lax_cookie->IsSetPermittedInContext(
5310 url, options,
5311 CookieAccessParams(CookieAccessSemantics::LEGACY,
5312 delegate_treats_url_as_trustworthy,
5313 CookieSamePartyStatus::kNoSamePartyEnforcement),
5314 kCookieableSchemes),
5315 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
5316
5317 // Next: allow a SameParty cookie (using both definitions).
5318 options.set_same_party_context(SamePartyContext::MakeInclusive());
5319 EXPECT_THAT(
5320 same_site_none_cookie->IsSetPermittedInContext(
5321 url, options,
5322 CookieAccessParams(CookieAccessSemantics::LEGACY,
5323 delegate_treats_url_as_trustworthy,
5324 CookieSamePartyStatus::kNoSamePartyEnforcement),
5325 kCookieableSchemes),
5326 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5327 EXPECT_THAT(
5328 same_party_cookie->IsSetPermittedInContext(
5329 url, options,
5330 CookieAccessParams(CookieAccessSemantics::LEGACY,
5331 delegate_treats_url_as_trustworthy,
5332 CookieSamePartyStatus::kNoSamePartyEnforcement),
5333 kCookieableSchemes),
5334 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5335 EXPECT_THAT(
5336 same_site_lax_cookie->IsSetPermittedInContext(
5337 url, options,
5338 CookieAccessParams(CookieAccessSemantics::LEGACY,
5339 delegate_treats_url_as_trustworthy,
5340 CookieSamePartyStatus::kNoSamePartyEnforcement),
5341 kCookieableSchemes),
5342 MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
5343
5344 // Next: allow a SameSite=Lax or SameSite=Strict cookie.
5345 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
5346 CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
5347 EXPECT_THAT(
5348 same_site_none_cookie->IsSetPermittedInContext(
5349 url, options,
5350 CookieAccessParams(CookieAccessSemantics::LEGACY,
5351 delegate_treats_url_as_trustworthy,
5352 CookieSamePartyStatus::kNoSamePartyEnforcement),
5353 kCookieableSchemes),
5354 MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5355 EXPECT_THAT(
5356 same_site_lax_cookie->IsSetPermittedInContext(
5357 url, options,
5358 CookieAccessParams(CookieAccessSemantics::LEGACY,
5359 delegate_treats_url_as_trustworthy,
5360 CookieSamePartyStatus::kNoSamePartyEnforcement),
5361 kCookieableSchemes),
5362 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5363 EXPECT_THAT(
5364 same_site_strict_cookie->IsSetPermittedInContext(
5365 url, options,
5366 CookieAccessParams(CookieAccessSemantics::LEGACY,
5367 delegate_treats_url_as_trustworthy,
5368 CookieSamePartyStatus::kNoSamePartyEnforcement),
5369 kCookieableSchemes),
5370 MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5371 }
5372
TEST(CanonicalCookieTest,IsSetPermitted_SameParty)5373 TEST(CanonicalCookieTest, IsSetPermitted_SameParty) {
5374 GURL url("https://www.example.com/test");
5375 base::Time current_time = base::Time::Now();
5376 CookieOptions options;
5377 options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
5378 CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
5379 options.set_same_party_context(
5380 SamePartyContext(SamePartyContext::Type::kSameParty));
5381
5382 {
5383 bool delegate_treats_url_as_trustworthy = false;
5384 auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
5385 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5386 base::Time(), base::Time(), true /* secure */, false /*httponly*/,
5387 CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
5388 true /* same_party */);
5389
5390 // The following access would normally be excluded due to SameSite=Lax, but
5391 // SameParty overrides SameSite.
5392 EXPECT_THAT(
5393 cookie->IsSetPermittedInContext(
5394 url, options,
5395 CookieAccessParams(CookieAccessSemantics::LEGACY,
5396 delegate_treats_url_as_trustworthy,
5397 CookieSamePartyStatus::kEnforceSamePartyExclude),
5398 kCookieableSchemes),
5399 MatchesCookieAccessResult(
5400 CookieInclusionStatus::MakeFromReasonsForTesting(
5401 {CookieInclusionStatus::EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT},
5402 {CookieInclusionStatus::WARN_TREATED_AS_SAMEPARTY}),
5403 _, _, true));
5404 }
5405
5406 for (CookieSameSite same_site : {
5407 CookieSameSite::UNSPECIFIED,
5408 CookieSameSite::NO_RESTRICTION,
5409 CookieSameSite::LAX_MODE,
5410 }) {
5411 auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
5412 "A", "2", "www.example.com", "/test", current_time, base::Time(),
5413 base::Time(), base::Time(), true /* secure */, false /*httponly*/,
5414 same_site, COOKIE_PRIORITY_DEFAULT, true /* same_party */);
5415
5416 for (bool delegate_treats_url_as_trustworthy : {false, true}) {
5417 for (CookieAccessSemantics access_semantics : {
5418 CookieAccessSemantics::UNKNOWN,
5419 CookieAccessSemantics::LEGACY,
5420 CookieAccessSemantics::NONLEGACY,
5421 }) {
5422 EXPECT_THAT(
5423 cookie->IsSetPermittedInContext(
5424 url, options,
5425 CookieAccessParams(
5426 access_semantics, delegate_treats_url_as_trustworthy,
5427 CookieSamePartyStatus::kEnforceSamePartyInclude),
5428 kCookieableSchemes),
5429 MatchesCookieAccessResult(IsInclude(), _, _, true));
5430 }
5431 }
5432 }
5433 }
5434
5435 // Test that the CookieInclusionStatus warning for inclusion changed by
5436 // cross-site redirect context downgrade is applied correctly.
TEST(CanonicalCookieTest,IsSetPermittedInContext_RedirectDowngradeWarning)5437 TEST(CanonicalCookieTest, IsSetPermittedInContext_RedirectDowngradeWarning) {
5438 using Context = CookieOptions::SameSiteCookieContext;
5439 using ContextType = Context::ContextType;
5440
5441 GURL url("https://www.example.test/test");
5442 GURL insecure_url("http://www.example.test/test");
5443
5444 // Test cases to be used with a lax-to-cross context downgrade.
5445 const struct {
5446 ContextType context_type;
5447 CookieSameSite samesite;
5448 bool expect_cross_site_redirect_warning;
5449 } kTestCases[] = {
5450 {ContextType::SAME_SITE_LAX, CookieSameSite::STRICT_MODE, true},
5451 {ContextType::CROSS_SITE, CookieSameSite::STRICT_MODE, true},
5452 {ContextType::SAME_SITE_LAX, CookieSameSite::LAX_MODE, true},
5453 {ContextType::CROSS_SITE, CookieSameSite::LAX_MODE, true},
5454 {ContextType::SAME_SITE_LAX, CookieSameSite::NO_RESTRICTION, false},
5455 {ContextType::CROSS_SITE, CookieSameSite::NO_RESTRICTION, false},
5456 };
5457
5458 for (bool consider_redirects : {true, false}) {
5459 base::test::ScopedFeatureList feature_list;
5460 feature_list.InitWithFeatureState(
5461 features::kCookieSameSiteConsidersRedirectChain, consider_redirects);
5462
5463 for (CookieAccessSemantics semantics :
5464 {CookieAccessSemantics::LEGACY, CookieAccessSemantics::NONLEGACY}) {
5465 // There are no downgrade warnings for undowngraded contexts.
5466 for (ContextType context_type : {ContextType::SAME_SITE_LAX,
5467 ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
5468 ContextType::CROSS_SITE}) {
5469 for (CookieSameSite samesite :
5470 {CookieSameSite::UNSPECIFIED, CookieSameSite::NO_RESTRICTION,
5471 CookieSameSite::LAX_MODE, CookieSameSite::STRICT_MODE}) {
5472 std::unique_ptr<CanonicalCookie> cookie =
5473 CanonicalCookie::CreateUnsafeCookieForTesting(
5474 "A", "1", "www.example.test", "/test", base::Time::Now(),
5475 base::Time(), base::Time(), base::Time(), /*secure=*/true,
5476 /*httponly=*/false, samesite, COOKIE_PRIORITY_DEFAULT,
5477 /*same_party=*/false);
5478
5479 CookieOptions options;
5480 options.set_same_site_cookie_context(Context(context_type));
5481
5482 EXPECT_FALSE(
5483 cookie
5484 ->IsSetPermittedInContext(
5485 url, options,
5486 CookieAccessParams(
5487 semantics,
5488 /*delegate_treats_url_as_trustworthy=*/false,
5489 CookieSamePartyStatus::kNoSamePartyEnforcement),
5490 kCookieableSchemes)
5491 .status.HasWarningReason(
5492 CookieInclusionStatus::
5493 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
5494 }
5495 }
5496
5497 for (const auto& test : kTestCases) {
5498 std::unique_ptr<CanonicalCookie> cookie =
5499 CanonicalCookie::CreateUnsafeCookieForTesting(
5500 "A", "1", "www.example.test", "/test", base::Time::Now(),
5501 base::Time(), base::Time(), base::Time(), /*secure=*/true,
5502 /*httponly=*/false, test.samesite, COOKIE_PRIORITY_DEFAULT,
5503 /*same_party=*/false);
5504
5505 Context::ContextMetadata lax_cross_downgrade_metadata;
5506 lax_cross_downgrade_metadata.cross_site_redirect_downgrade =
5507 Context::ContextMetadata::ContextDowngradeType::kLaxToCross;
5508 CookieOptions options;
5509 options.set_same_site_cookie_context(Context(
5510 test.context_type, test.context_type, lax_cross_downgrade_metadata,
5511 lax_cross_downgrade_metadata));
5512
5513 EXPECT_EQ(
5514 cookie
5515 ->IsSetPermittedInContext(
5516 url, options,
5517 CookieAccessParams(
5518 semantics,
5519 /*delegate_treats_url_as_trustworthy=*/false,
5520 CookieSamePartyStatus::kNoSamePartyEnforcement),
5521 kCookieableSchemes)
5522 .status.HasWarningReason(
5523 CookieInclusionStatus::
5524 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION),
5525 test.expect_cross_site_redirect_warning);
5526
5527 // SameSite warnings not applied if other exclusion reasons apply (e.g.
5528 // non-https with Secure attribute).
5529 EXPECT_FALSE(
5530 cookie
5531 ->IsSetPermittedInContext(
5532 insecure_url, options,
5533 CookieAccessParams(
5534 semantics,
5535 /*delegate_treats_url_as_trustworthy=*/false,
5536 CookieSamePartyStatus::kNoSamePartyEnforcement),
5537 kCookieableSchemes)
5538 .status.HasWarningReason(
5539 CookieInclusionStatus::
5540 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
5541 }
5542 }
5543 }
5544 }
5545
TEST(CanonicalCookieTest,TestIsCanonicalWithInvalidSizeHistograms)5546 TEST(CanonicalCookieTest, TestIsCanonicalWithInvalidSizeHistograms) {
5547 base::HistogramTester histograms;
5548 const char kFromStorageWithValidLengthHistogram[] =
5549 "Cookie.FromStorageWithValidLength";
5550 const base::HistogramBase::Sample kInValid = 0;
5551 const base::HistogramBase::Sample kValid = 1;
5552
5553 base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
5554 base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
5555 base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
5556
5557 // Test a cookie that is canonical and valid size
5558 EXPECT_TRUE(CanonicalCookie::FromStorage(
5559 "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
5560 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
5561 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
5562 false /*same_party*/, absl::nullopt /*partition_key*/,
5563 CookieSourceScheme::kSecure, 87));
5564
5565 histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kInValid,
5566 0);
5567 histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kValid, 1);
5568
5569 // Test loading a couple of cookies which are canonical but with an invalid
5570 // size
5571 const std::string kCookieBig(4096, 'a');
5572 EXPECT_TRUE(CanonicalCookie::FromStorage(
5573 kCookieBig, "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
5574 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
5575 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
5576 false /*same_party*/, absl::nullopt /*partition_key*/,
5577 CookieSourceScheme::kSecure, 87));
5578 EXPECT_TRUE(CanonicalCookie::FromStorage(
5579 "A", kCookieBig, "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
5580 one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
5581 CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
5582 false /*same_party*/, absl::nullopt /*partition_key*/,
5583 CookieSourceScheme::kSecure, 87));
5584
5585 histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kInValid,
5586 2);
5587 histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kValid, 1);
5588 }
5589
TEST(CanonicalCookieTest,TestHasHiddenPrefixName)5590 TEST(CanonicalCookieTest, TestHasHiddenPrefixName) {
5591 const struct {
5592 const char* value;
5593 bool result;
5594 } kTestCases[] = {
5595 {"", false},
5596 {" ", false},
5597 {"foobar=", false},
5598 {"foo=bar", false},
5599 {" \t ", false},
5600 {"\t", false},
5601 {"__Secure=-", false},
5602 {"__Secure=-abc", false},
5603 {"__Secur=e-abc", false},
5604 {"__Secureabc", false},
5605 {"__Host=-", false},
5606 {"__Host=-abc", false},
5607 {"__Hos=t-abc", false},
5608 {"_Host", false},
5609 {"a__Host-abc=123", false},
5610 {"a__Secure-abc=123", false},
5611 {"__Secure-abc", true},
5612 {"__Host-abc", true},
5613 {" __Secure-abc", true},
5614 {"\t__Host-", true},
5615 {"__Host-=", true},
5616 {"__Host-=123", true},
5617 {"__host-=123", true},
5618 {"__HOST-=123", true},
5619 {"__HoSt-=123", true},
5620 {"__Host-abc=", true},
5621 {"__Host-abc=123", true},
5622 {" __Host-abc=123", true},
5623 {" __Host-abc=", true},
5624 {"\t\t\t\t\t__Host-abc=123", true},
5625 {"\t __Host-abc=", true},
5626 {"__Secure-=", true},
5627 {"__Secure-=123", true},
5628 {"__secure-=123", true},
5629 {"__SECURE-=123", true},
5630 {"__SeCuRe-=123", true},
5631 {"__Secure-abc=", true},
5632 {"__Secure-abc=123", true},
5633 {" __Secure-abc=123", true},
5634 {" __Secure-abc=", true},
5635 {"\t\t\t\t\t__Secure-abc=123", true},
5636 {"\t __Secure-abc=", true},
5637 {"__Secure-abc=123=d=4=fg=", true},
5638 };
5639
5640 for (auto test_case : kTestCases) {
5641 EXPECT_EQ(CanonicalCookie::HasHiddenPrefixName(test_case.value),
5642 test_case.result)
5643 << test_case.value << " failed check";
5644 }
5645 }
5646
TEST(CanonicalCookieTest,TestDoubleUnderscorePrefixHistogram)5647 TEST(CanonicalCookieTest, TestDoubleUnderscorePrefixHistogram) {
5648 base::HistogramTester histograms;
5649 const char kDoubleUnderscorePrefixHistogram[] =
5650 "Cookie.DoubleUnderscorePrefixedName";
5651
5652 CanonicalCookie::Create(
5653 GURL("https://www.example.com/"), "__Secure-abc=123; Secure",
5654 base::Time::Now() /* Creation time */, absl::nullopt /* Server Time */,
5655 absl::nullopt /* cookie_partition_key */);
5656
5657 CanonicalCookie::Create(
5658 GURL("https://www.example.com/"), "__Host-abc=123; Secure; Path=/",
5659 base::Time::Now() /* Creation time */, absl::nullopt /* Server Time */,
5660 absl::nullopt /* cookie_partition_key */);
5661
5662 // Cookie prefixes shouldn't count.
5663 histograms.ExpectTotalCount(kDoubleUnderscorePrefixHistogram, 2);
5664 histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, false, 2);
5665
5666 CanonicalCookie::Create(GURL("https://www.example.com/"), "f__oo=bar",
5667 base::Time::Now() /* Creation time */,
5668 absl::nullopt /* Server Time */,
5669 absl::nullopt /* cookie_partition_key */);
5670
5671 CanonicalCookie::Create(GURL("https://www.example.com/"), "foo=__bar",
5672 base::Time::Now() /* Creation time */,
5673 absl::nullopt /* Server Time */,
5674 absl::nullopt /* cookie_partition_key */);
5675
5676 CanonicalCookie::Create(GURL("https://www.example.com/"), "_foo=bar",
5677 base::Time::Now() /* Creation time */,
5678 absl::nullopt /* Server Time */,
5679 absl::nullopt /* cookie_partition_key */);
5680
5681 CanonicalCookie::Create(GURL("https://www.example.com/"), "_f_oo=bar",
5682 base::Time::Now() /* Creation time */,
5683 absl::nullopt /* Server Time */,
5684 absl::nullopt /* cookie_partition_key */);
5685
5686 // These should be counted.
5687 CanonicalCookie::Create(GURL("https://www.example.com/"), "__foo=bar",
5688 base::Time::Now() /* Creation time */,
5689 absl::nullopt /* Server Time */,
5690 absl::nullopt /* cookie_partition_key */);
5691
5692 CanonicalCookie::Create(GURL("https://www.example.com/"), "___foo=bar",
5693 base::Time::Now() /* Creation time */,
5694 absl::nullopt /* Server Time */,
5695 absl::nullopt /* cookie_partition_key */);
5696
5697 histograms.ExpectTotalCount(kDoubleUnderscorePrefixHistogram, 8);
5698 histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, false, 6);
5699 histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, true, 2);
5700 }
5701
5702 } // namespace net
5703