• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cookies/cookie_inclusion_status.h"
6 
7 #include "testing/gtest/include/gtest/gtest.h"
8 
9 namespace net {
10 
TEST(CookieInclusionStatusTest,IncludeStatus)11 TEST(CookieInclusionStatusTest, IncludeStatus) {
12   int num_exclusion_reasons =
13       static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
14   int num_warning_reasons =
15       static_cast<int>(CookieInclusionStatus::NUM_WARNING_REASONS);
16   // Zero-argument constructor
17   CookieInclusionStatus status;
18   EXPECT_TRUE(status.IsInclude());
19   for (int i = 0; i < num_exclusion_reasons; ++i) {
20     EXPECT_FALSE(status.HasExclusionReason(
21         static_cast<CookieInclusionStatus::ExclusionReason>(i)));
22   }
23   for (int i = 0; i < num_warning_reasons; ++i) {
24     EXPECT_FALSE(status.HasWarningReason(
25         static_cast<CookieInclusionStatus::WarningReason>(i)));
26   }
27   EXPECT_FALSE(
28       status.HasExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
29 }
30 
TEST(CookieInclusionStatusTest,ExcludeStatus)31 TEST(CookieInclusionStatusTest, ExcludeStatus) {
32   int num_exclusion_reasons =
33       static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
34   // Test exactly one exclusion reason and multiple (two) exclusion reasons.
35   for (int i = 0; i < num_exclusion_reasons; ++i) {
36     auto reason1 = static_cast<CookieInclusionStatus::ExclusionReason>(i);
37     CookieInclusionStatus status_one_reason(reason1);
38     EXPECT_FALSE(status_one_reason.IsInclude());
39     EXPECT_TRUE(status_one_reason.HasExclusionReason(reason1));
40     EXPECT_TRUE(status_one_reason.HasOnlyExclusionReason(reason1));
41 
42     for (int j = 0; j < num_exclusion_reasons; ++j) {
43       if (i == j)
44         continue;
45       auto reason2 = static_cast<CookieInclusionStatus::ExclusionReason>(j);
46 
47       EXPECT_FALSE(status_one_reason.HasExclusionReason(reason2));
48       EXPECT_FALSE(status_one_reason.HasOnlyExclusionReason(reason2));
49 
50       CookieInclusionStatus status_two_reasons = status_one_reason;
51       status_two_reasons.AddExclusionReason(reason2);
52       EXPECT_FALSE(status_two_reasons.IsInclude());
53 
54       if (reason1 != CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT &&
55           reason2 != CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT) {
56         EXPECT_TRUE(status_two_reasons.HasExclusionReason(reason1));
57         EXPECT_TRUE(status_two_reasons.HasExclusionReason(reason2));
58       }
59     }
60   }
61 }
62 
TEST(CookieInclusionStatusTest,ExcludeStatus_MaybeClearThirdPartyPhaseoutReason)63 TEST(CookieInclusionStatusTest,
64      ExcludeStatus_MaybeClearThirdPartyPhaseoutReason) {
65   int num_exclusion_reasons =
66       static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
67   CookieInclusionStatus::ExclusionReason reason1 =
68       CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT;
69   const CookieInclusionStatus status_one_reason(reason1);
70   ASSERT_FALSE(status_one_reason.IsInclude());
71   ASSERT_TRUE(status_one_reason.HasOnlyExclusionReason(reason1));
72 
73   for (int j = 0; j < num_exclusion_reasons; ++j) {
74     auto reason2 = static_cast<CookieInclusionStatus::ExclusionReason>(j);
75     if (reason1 == reason2) {
76       continue;
77     }
78     EXPECT_FALSE(status_one_reason.HasExclusionReason(reason2)) << reason2;
79 
80     CookieInclusionStatus status_two_reasons = status_one_reason;
81     status_two_reasons.AddExclusionReason(reason2);
82     EXPECT_FALSE(status_two_reasons.IsInclude());
83 
84     if (reason2 == CookieInclusionStatus::
85                        EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET) {
86       EXPECT_TRUE(status_two_reasons.HasExclusionReason(reason1));
87       EXPECT_TRUE(status_two_reasons.HasExclusionReason(reason2));
88     } else {
89       EXPECT_TRUE(status_two_reasons.HasOnlyExclusionReason(reason2));
90     }
91   }
92 }
93 
TEST(CookieInclusionStatusTest,AddExclusionReason_MaybeClearThirdPartyPhaseoutReason)94 TEST(CookieInclusionStatusTest,
95      AddExclusionReason_MaybeClearThirdPartyPhaseoutReason) {
96   CookieInclusionStatus status;
97   status.AddWarningReason(CookieInclusionStatus::WARN_THIRD_PARTY_PHASEOUT);
98   ASSERT_TRUE(status.ShouldWarn());
99   ASSERT_TRUE(status.HasExactlyWarningReasonsForTesting(
100       {CookieInclusionStatus::WARN_THIRD_PARTY_PHASEOUT}));
101   // Adding an exclusion reason should clear 3PCD warning reason.
102   status.AddExclusionReason(
103       CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT);
104   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
105       {CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT}));
106   EXPECT_FALSE(status.ShouldWarn());
107 
108   status.AddExclusionReason(
109       CookieInclusionStatus::
110           EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET);
111   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
112       {CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT,
113        CookieInclusionStatus::
114            EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET}));
115   // Adding an exclusion reason unrelated with 3PCD should clear 3PCD related
116   // exclusion reasons.
117   status.AddExclusionReason(
118       CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE);
119   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
120       {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE,
121        // TODO(crbug.com/1516673): This should also be removed.
122        CookieInclusionStatus::
123            EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET}));
124   EXPECT_FALSE(status.IsInclude());
125 }
126 
TEST(CookieInclusionStatusTest,AddExclusionReason)127 TEST(CookieInclusionStatusTest, AddExclusionReason) {
128   CookieInclusionStatus status;
129   status.AddWarningReason(
130       CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
131   status.AddExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
132   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
133       {CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR}));
134   // Adding an exclusion reason other than
135   // EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX or
136   // EXCLUDE_SAMESITE_NONE_INSECURE should clear any SameSite warning.
137   EXPECT_FALSE(status.ShouldWarn());
138 
139   status = CookieInclusionStatus();
140   status.AddWarningReason(
141       CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
142   status.AddExclusionReason(
143       CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
144   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
145       {CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
146   EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
147       {CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT}));
148 }
149 
TEST(CookieInclusionStatusTest,CheckEachWarningReason)150 TEST(CookieInclusionStatusTest, CheckEachWarningReason) {
151   CookieInclusionStatus status;
152 
153   int num_warning_reasons =
154       static_cast<int>(CookieInclusionStatus::NUM_WARNING_REASONS);
155   EXPECT_FALSE(status.ShouldWarn());
156   for (int i = 0; i < num_warning_reasons; ++i) {
157     auto reason = static_cast<CookieInclusionStatus::WarningReason>(i);
158     status.AddWarningReason(reason);
159     EXPECT_TRUE(status.IsInclude());
160     EXPECT_TRUE(status.ShouldWarn());
161     EXPECT_TRUE(status.HasWarningReason(reason));
162     for (int j = 0; j < num_warning_reasons; ++j) {
163       if (i == j)
164         continue;
165       EXPECT_FALSE(status.HasWarningReason(
166           static_cast<CookieInclusionStatus::WarningReason>(j)));
167     }
168     status.RemoveWarningReason(reason);
169     EXPECT_FALSE(status.ShouldWarn());
170   }
171 }
172 
TEST(CookieInclusionStatusTest,RemoveExclusionReason)173 TEST(CookieInclusionStatusTest, RemoveExclusionReason) {
174   CookieInclusionStatus status(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
175   ASSERT_TRUE(
176       status.HasExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
177 
178   status.RemoveExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
179   EXPECT_FALSE(
180       status.HasExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
181 
182   // Removing a nonexistent exclusion reason doesn't do anything.
183   ASSERT_FALSE(
184       status.HasExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS));
185   status.RemoveExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
186   EXPECT_FALSE(
187       status.HasExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS));
188 }
189 
TEST(CookieInclusionStatusTest,RemoveWarningReason)190 TEST(CookieInclusionStatusTest, RemoveWarningReason) {
191   CookieInclusionStatus status(
192       CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
193       CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
194   EXPECT_TRUE(status.ShouldWarn());
195   ASSERT_TRUE(status.HasWarningReason(
196       CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE));
197 
198   status.RemoveWarningReason(
199       CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
200   EXPECT_FALSE(status.ShouldWarn());
201   EXPECT_FALSE(status.HasWarningReason(
202       CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE));
203 
204   // Removing a nonexistent warning reason doesn't do anything.
205   ASSERT_FALSE(status.HasWarningReason(
206       CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
207   status.RemoveWarningReason(
208       CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
209   EXPECT_FALSE(status.ShouldWarn());
210   EXPECT_FALSE(status.HasWarningReason(
211       CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
212 }
213 
TEST(CookieInclusionStatusTest,HasSchemefulDowngradeWarning)214 TEST(CookieInclusionStatusTest, HasSchemefulDowngradeWarning) {
215   std::vector<CookieInclusionStatus::WarningReason> downgrade_warnings = {
216       CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
217       CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
218       CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
219       CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
220       CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
221   };
222 
223   CookieInclusionStatus empty_status;
224   EXPECT_FALSE(empty_status.HasSchemefulDowngradeWarning());
225 
226   CookieInclusionStatus not_downgrade;
227   not_downgrade.AddWarningReason(
228       CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
229   EXPECT_FALSE(not_downgrade.HasSchemefulDowngradeWarning());
230 
231   for (auto warning : downgrade_warnings) {
232     CookieInclusionStatus status;
233     status.AddWarningReason(warning);
234     CookieInclusionStatus::WarningReason reason;
235 
236     EXPECT_TRUE(status.HasSchemefulDowngradeWarning(&reason));
237     EXPECT_EQ(warning, reason);
238   }
239 }
240 
TEST(CookieInclusionStatusTest,ShouldRecordDowngradeMetrics)241 TEST(CookieInclusionStatusTest, ShouldRecordDowngradeMetrics) {
242   EXPECT_TRUE(CookieInclusionStatus::MakeFromReasonsForTesting({})
243                   .ShouldRecordDowngradeMetrics());
244 
245   EXPECT_TRUE(CookieInclusionStatus::MakeFromReasonsForTesting(
246                   {
247                       CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT,
248                   })
249                   .ShouldRecordDowngradeMetrics());
250 
251   EXPECT_TRUE(CookieInclusionStatus::MakeFromReasonsForTesting(
252                   {
253                       CookieInclusionStatus::EXCLUDE_SAMESITE_LAX,
254                   })
255                   .ShouldRecordDowngradeMetrics());
256 
257   EXPECT_TRUE(CookieInclusionStatus::MakeFromReasonsForTesting(
258                   {
259                       CookieInclusionStatus::
260                           EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
261                   })
262                   .ShouldRecordDowngradeMetrics());
263 
264   // Note: the following cases cannot occur under normal circumstances.
265   EXPECT_TRUE(CookieInclusionStatus::MakeFromReasonsForTesting(
266                   {
267                       CookieInclusionStatus::
268                           EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
269                       CookieInclusionStatus::EXCLUDE_SAMESITE_LAX,
270                   })
271                   .ShouldRecordDowngradeMetrics());
272   EXPECT_FALSE(CookieInclusionStatus::MakeFromReasonsForTesting(
273                    {
274                        CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE,
275                        CookieInclusionStatus::EXCLUDE_SAMESITE_LAX,
276                    })
277                    .ShouldRecordDowngradeMetrics());
278 }
279 
TEST(CookieInclusionStatusTest,RemoveExclusionReasons)280 TEST(CookieInclusionStatusTest, RemoveExclusionReasons) {
281   CookieInclusionStatus status =
282       CookieInclusionStatus::MakeFromReasonsForTesting({
283           CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
284           CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT,
285           CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
286       });
287   ASSERT_TRUE(status.HasExactlyExclusionReasonsForTesting({
288       CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
289       CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT,
290       CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
291   }));
292 
293   status.RemoveExclusionReasons(
294       {CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
295        CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
296        CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT});
297   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({
298       CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
299   }));
300 
301   // Removing a nonexistent exclusion reason doesn't do anything.
302   ASSERT_FALSE(
303       status.HasExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS));
304   status.RemoveExclusionReasons({CookieInclusionStatus::NUM_EXCLUSION_REASONS});
305   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({
306       CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
307   }));
308 }
309 
TEST(CookieInclusionStatusTest,ValidateExclusionAndWarningFromWire)310 TEST(CookieInclusionStatusTest, ValidateExclusionAndWarningFromWire) {
311   uint32_t exclusion_reasons = 0ul;
312   uint32_t warning_reasons = 0ul;
313 
314   EXPECT_TRUE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
315       exclusion_reasons, warning_reasons));
316 
317   exclusion_reasons = static_cast<uint32_t>(~0ul);
318   warning_reasons = static_cast<uint32_t>(~0ul);
319   EXPECT_FALSE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
320       exclusion_reasons, warning_reasons));
321   EXPECT_FALSE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
322       exclusion_reasons, 0u));
323   EXPECT_FALSE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
324       0u, warning_reasons));
325 
326   exclusion_reasons = (1u << CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH);
327   warning_reasons = (1u << CookieInclusionStatus::WARN_PORT_MISMATCH);
328   EXPECT_TRUE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
329       exclusion_reasons, warning_reasons));
330 
331   exclusion_reasons = (1u << CookieInclusionStatus::NUM_EXCLUSION_REASONS);
332   warning_reasons = (1u << CookieInclusionStatus::NUM_WARNING_REASONS);
333   EXPECT_FALSE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
334       exclusion_reasons, warning_reasons));
335 
336   exclusion_reasons =
337       (1u << (CookieInclusionStatus::NUM_EXCLUSION_REASONS - 1));
338   warning_reasons = (1u << (CookieInclusionStatus::NUM_WARNING_REASONS - 1));
339   EXPECT_TRUE(CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
340       exclusion_reasons, warning_reasons));
341 }
342 
TEST(CookieInclusionStatusTest,ExcludedByUserPreferences)343 TEST(CookieInclusionStatusTest, ExcludedByUserPreferences) {
344   CookieInclusionStatus status =
345       CookieInclusionStatus::MakeFromReasonsForTesting(
346           {CookieInclusionStatus::ExclusionReason::EXCLUDE_USER_PREFERENCES});
347   EXPECT_TRUE(status.ExcludedByUserPreferences());
348 
349   status = CookieInclusionStatus::MakeFromReasonsForTesting({
350       CookieInclusionStatus::ExclusionReason::EXCLUDE_USER_PREFERENCES,
351       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE,
352   });
353   EXPECT_FALSE(status.ExcludedByUserPreferences());
354 
355   status = CookieInclusionStatus::MakeFromReasonsForTesting({
356       CookieInclusionStatus::ExclusionReason::EXCLUDE_USER_PREFERENCES,
357       CookieInclusionStatus::ExclusionReason::
358           EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET,
359   });
360   EXPECT_TRUE(status.ExcludedByUserPreferences());
361 
362   status = CookieInclusionStatus::MakeFromReasonsForTesting({
363       CookieInclusionStatus::ExclusionReason::
364           EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET,
365   });
366   EXPECT_FALSE(status.ExcludedByUserPreferences());
367 
368   status = CookieInclusionStatus::MakeFromReasonsForTesting({
369       CookieInclusionStatus::ExclusionReason::
370           EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET,
371       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE,
372   });
373   EXPECT_FALSE(status.ExcludedByUserPreferences());
374 
375   status = CookieInclusionStatus::MakeFromReasonsForTesting({
376       CookieInclusionStatus::ExclusionReason::EXCLUDE_USER_PREFERENCES,
377       CookieInclusionStatus::ExclusionReason::
378           EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET,
379       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE,
380   });
381   EXPECT_FALSE(status.ExcludedByUserPreferences());
382 }
383 
384 }  // namespace net
385