blob: 46342570471fbf4a046c78e7ebe9b0f1fd7dde37 [file] [log] [blame]
Jihwan Marc Kim3e132f12020-05-20 17:33:191// Copyright 2020 The Chromium Authors. All rights reserved.
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
Peter Vargaec193052021-12-01 10:25:057#include <initializer_list>
8#include <utility>
9
Jihwan Marc Kim3e132f12020-05-20 17:33:1910#include "base/strings/strcat.h"
11#include "url/gurl.h"
12
13namespace net {
14
cfredric2c5cfa62020-11-16 19:59:2515CookieInclusionStatus::CookieInclusionStatus() = default;
Jihwan Marc Kim3e132f12020-05-20 17:33:1916
Matt Reichhoff4b2311eef2021-10-01 20:56:5917CookieInclusionStatus::CookieInclusionStatus(ExclusionReason reason) {
18 exclusion_reasons_[reason] = true;
19}
Jihwan Marc Kim3e132f12020-05-20 17:33:1920
21CookieInclusionStatus::CookieInclusionStatus(ExclusionReason reason,
Matt Reichhoff4b2311eef2021-10-01 20:56:5922 WarningReason warning) {
23 exclusion_reasons_[reason] = true;
24 warning_reasons_[warning] = true;
25}
Jihwan Marc Kim3e132f12020-05-20 17:33:1926
Matt Reichhoff4b2311eef2021-10-01 20:56:5927CookieInclusionStatus::CookieInclusionStatus(WarningReason warning) {
28 warning_reasons_[warning] = true;
29}
30
31CookieInclusionStatus::CookieInclusionStatus(
32 const CookieInclusionStatus& other) = default;
33
34CookieInclusionStatus& CookieInclusionStatus::operator=(
35 const CookieInclusionStatus& other) = default;
cfredric362c4a02021-07-09 22:40:4036
Jihwan Marc Kim3e132f12020-05-20 17:33:1937bool CookieInclusionStatus::operator==(
38 const CookieInclusionStatus& other) const {
39 return exclusion_reasons_ == other.exclusion_reasons_ &&
40 warning_reasons_ == other.warning_reasons_;
41}
42
43bool CookieInclusionStatus::operator!=(
44 const CookieInclusionStatus& other) const {
45 return !operator==(other);
46}
47
48bool CookieInclusionStatus::IsInclude() const {
Matt Reichhoff4b2311eef2021-10-01 20:56:5949 return exclusion_reasons_.none();
Jihwan Marc Kim3e132f12020-05-20 17:33:1950}
51
52bool CookieInclusionStatus::HasExclusionReason(ExclusionReason reason) const {
Matt Reichhoff4b2311eef2021-10-01 20:56:5953 return exclusion_reasons_[reason];
Jihwan Marc Kim3e132f12020-05-20 17:33:1954}
55
Lily Chen70c537a2020-07-20 18:02:0956bool CookieInclusionStatus::HasOnlyExclusionReason(
57 ExclusionReason reason) const {
Matt Reichhoff4b2311eef2021-10-01 20:56:5958 return exclusion_reasons_[reason] && exclusion_reasons_.count() == 1;
Lily Chen70c537a2020-07-20 18:02:0959}
60
Jihwan Marc Kim3e132f12020-05-20 17:33:1961void CookieInclusionStatus::AddExclusionReason(ExclusionReason reason) {
Matt Reichhoff4b2311eef2021-10-01 20:56:5962 exclusion_reasons_[reason] = true;
Jihwan Marc Kim3e132f12020-05-20 17:33:1963 // If the cookie would be excluded for reasons other than the new SameSite
64 // rules, don't bother warning about it.
65 MaybeClearSameSiteWarning();
66}
67
68void CookieInclusionStatus::RemoveExclusionReason(ExclusionReason reason) {
Matt Reichhoff4b2311eef2021-10-01 20:56:5969 exclusion_reasons_[reason] = false;
Jihwan Marc Kim3e132f12020-05-20 17:33:1970}
71
cfredric05c78ac2021-01-06 18:10:2672void CookieInclusionStatus::RemoveExclusionReasons(
73 const std::vector<ExclusionReason>& reasons) {
74 exclusion_reasons_ = ExclusionReasonsWithout(reasons);
75}
76
Matt Reichhoff4b2311eef2021-10-01 20:56:5977CookieInclusionStatus::ExclusionReasonBitset
78CookieInclusionStatus::ExclusionReasonsWithout(
cfredric2c5cfa62020-11-16 19:59:2579 const std::vector<ExclusionReason>& reasons) const {
Matt Reichhoff4b2311eef2021-10-01 20:56:5980 CookieInclusionStatus::ExclusionReasonBitset result(exclusion_reasons_);
cfredric2c5cfa62020-11-16 19:59:2581 for (const ExclusionReason reason : reasons) {
Matt Reichhoff4b2311eef2021-10-01 20:56:5982 result[reason] = false;
cfredric2c5cfa62020-11-16 19:59:2583 }
Matt Reichhoff4b2311eef2021-10-01 20:56:5984 return result;
cfredric2c5cfa62020-11-16 19:59:2585}
86
Jihwan Marc Kim3e132f12020-05-20 17:33:1987void CookieInclusionStatus::MaybeClearSameSiteWarning() {
cfredric2c5cfa62020-11-16 19:59:2588 if (ExclusionReasonsWithout({
89 EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
90 EXCLUDE_SAMESITE_NONE_INSECURE,
91 }) != 0u) {
Lily Chen2db3a422021-07-20 18:02:2592 RemoveWarningReason(WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
93 RemoveWarningReason(WARN_SAMESITE_NONE_INSECURE);
94 RemoveWarningReason(WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
Jihwan Marc Kim3e132f12020-05-20 17:33:1995 }
96
cfredric2c5cfa62020-11-16 19:59:2597 if (!ShouldRecordDowngradeMetrics()) {
Lily Chen2db3a422021-07-20 18:02:2598 RemoveWarningReason(WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
99 RemoveWarningReason(WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
100 RemoveWarningReason(WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
101 RemoveWarningReason(WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
102 RemoveWarningReason(WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
103
104 RemoveWarningReason(WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION);
Jihwan Marc Kim3e132f12020-05-20 17:33:19105 }
106}
107
108bool CookieInclusionStatus::ShouldRecordDowngradeMetrics() const {
cfredric2c5cfa62020-11-16 19:59:25109 return ExclusionReasonsWithout({
110 EXCLUDE_SAMESITE_STRICT,
111 EXCLUDE_SAMESITE_LAX,
112 EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
113 }) == 0u;
Jihwan Marc Kim3e132f12020-05-20 17:33:19114}
115
116bool CookieInclusionStatus::ShouldWarn() const {
Matt Reichhoff4b2311eef2021-10-01 20:56:59117 return warning_reasons_.any();
Jihwan Marc Kim3e132f12020-05-20 17:33:19118}
119
120bool CookieInclusionStatus::HasWarningReason(WarningReason reason) const {
Matt Reichhoff4b2311eef2021-10-01 20:56:59121 return warning_reasons_[reason];
Jihwan Marc Kim3e132f12020-05-20 17:33:19122}
123
124bool CookieInclusionStatus::HasDowngradeWarning(
125 CookieInclusionStatus::WarningReason* reason) const {
126 if (!ShouldWarn())
127 return false;
128
129 const CookieInclusionStatus::WarningReason kDowngradeWarnings[] = {
130 WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
131 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
132 WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
133 WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
134 WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
135 };
136
137 for (auto warning : kDowngradeWarnings) {
138 if (!HasWarningReason(warning))
139 continue;
140
141 if (reason)
142 *reason = warning;
143
144 return true;
145 }
146
147 return false;
148}
149
150void CookieInclusionStatus::AddWarningReason(WarningReason reason) {
Matt Reichhoff4b2311eef2021-10-01 20:56:59151 warning_reasons_[reason] = true;
Jihwan Marc Kim3e132f12020-05-20 17:33:19152}
153
154void CookieInclusionStatus::RemoveWarningReason(WarningReason reason) {
Matt Reichhoff4b2311eef2021-10-01 20:56:59155 warning_reasons_[reason] = false;
Jihwan Marc Kim3e132f12020-05-20 17:33:19156}
157
158CookieInclusionStatus::ContextDowngradeMetricValues
159CookieInclusionStatus::GetBreakingDowngradeMetricsEnumValue(
160 const GURL& url) const {
161 bool url_is_secure = url.SchemeIsCryptographic();
162
163 // Start the |reason| as something other than the downgrade warnings.
164 WarningReason reason = WarningReason::NUM_WARNING_REASONS;
165
166 // Don't bother checking the return value because the default switch case
167 // will handle if no reason was found.
168 HasDowngradeWarning(&reason);
169
170 switch (reason) {
171 case WarningReason::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE:
172 return url_is_secure
173 ? ContextDowngradeMetricValues::STRICT_LAX_STRICT_SECURE
174 : ContextDowngradeMetricValues::STRICT_LAX_STRICT_INSECURE;
175 case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE:
176 return url_is_secure
177 ? ContextDowngradeMetricValues::STRICT_CROSS_STRICT_SECURE
178 : ContextDowngradeMetricValues::STRICT_CROSS_STRICT_INSECURE;
179 case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE:
180 return url_is_secure
181 ? ContextDowngradeMetricValues::STRICT_CROSS_LAX_SECURE
182 : ContextDowngradeMetricValues::STRICT_CROSS_LAX_INSECURE;
183 case WarningReason::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE:
184 return url_is_secure
185 ? ContextDowngradeMetricValues::LAX_CROSS_STRICT_SECURE
186 : ContextDowngradeMetricValues::LAX_CROSS_STRICT_INSECURE;
187 case WarningReason::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE:
188 return url_is_secure
189 ? ContextDowngradeMetricValues::LAX_CROSS_LAX_SECURE
190 : ContextDowngradeMetricValues::LAX_CROSS_LAX_INSECURE;
191 default:
192 return url_is_secure
193 ? ContextDowngradeMetricValues::NO_DOWNGRADE_SECURE
194 : ContextDowngradeMetricValues::NO_DOWNGRADE_INSECURE;
195 }
196}
197
198std::string CookieInclusionStatus::GetDebugString() const {
199 std::string out;
200
Jihwan Marc Kim3e132f12020-05-20 17:33:19201 if (IsInclude())
202 base::StrAppend(&out, {"INCLUDE, "});
cfredrica50e8532021-06-29 19:44:56203 for (const auto& reason :
204 std::initializer_list<std::pair<ExclusionReason, std::string>>{
205 {EXCLUDE_UNKNOWN_ERROR, "EXCLUDE_UNKNOWN_ERROR"},
206 {EXCLUDE_HTTP_ONLY, "EXCLUDE_HTTP_ONLY"},
207 {EXCLUDE_SECURE_ONLY, "EXCLUDE_SECURE_ONLY"},
208 {EXCLUDE_DOMAIN_MISMATCH, "EXCLUDE_DOMAIN_MISMATCH"},
209 {EXCLUDE_NOT_ON_PATH, "EXCLUDE_NOT_ON_PATH"},
210 {EXCLUDE_SAMESITE_STRICT, "EXCLUDE_SAMESITE_STRICT"},
211 {EXCLUDE_SAMESITE_LAX, "EXCLUDE_SAMESITE_LAX"},
212 {EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
213 "EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX"},
214 {EXCLUDE_SAMESITE_NONE_INSECURE, "EXCLUDE_SAMESITE_NONE_INSECURE"},
215 {EXCLUDE_USER_PREFERENCES, "EXCLUDE_USER_PREFERENCES"},
216 {EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT,
217 "EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT"},
218 {EXCLUDE_FAILURE_TO_STORE, "EXCLUDE_FAILURE_TO_STORE"},
219 {EXCLUDE_NONCOOKIEABLE_SCHEME, "EXCLUDE_NONCOOKIEABLE_SCHEME"},
220 {EXCLUDE_OVERWRITE_SECURE, "EXCLUDE_OVERWRITE_SECURE"},
221 {EXCLUDE_OVERWRITE_HTTP_ONLY, "EXCLUDE_OVERWRITE_HTTP_ONLY"},
222 {EXCLUDE_INVALID_DOMAIN, "EXCLUDE_INVALID_DOMAIN"},
223 {EXCLUDE_INVALID_PREFIX, "EXCLUDE_INVALID_PREFIX"},
224 {EXCLUDE_INVALID_SAMEPARTY, "EXCLUDE_INVALID_SAMEPARTY"},
Dylan Cutler01ca8e32021-07-16 18:01:35225 {EXCLUDE_INVALID_PARTITIONED, "EXCLUDE_INVALID_PARTITIONED"},
Andrew Williamse320767e02021-09-10 04:38:00226 {EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE,
227 "EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE"},
228 {EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE,
229 "EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE"},
cfredrica50e8532021-06-29 19:44:56230 }) {
231 if (HasExclusionReason(reason.first))
232 base::StrAppend(&out, {reason.second, ", "});
233 }
Jihwan Marc Kim3e132f12020-05-20 17:33:19234
235 // Add warning
236 if (!ShouldWarn()) {
237 base::StrAppend(&out, {"DO_NOT_WARN"});
238 return out;
239 }
240
cfredrica50e8532021-06-29 19:44:56241 for (const auto& reason :
242 std::initializer_list<std::pair<WarningReason, std::string>>{
243 {WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT,
244 "WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT"},
245 {WARN_SAMESITE_NONE_INSECURE, "WARN_SAMESITE_NONE_INSECURE"},
246 {WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE,
247 "WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE"},
248 {WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
249 "WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE"},
250 {WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
251 "WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE"},
252 {WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
253 "WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE"},
254 {WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
255 "WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE"},
256 {WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
257 "WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE"},
258 {WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC,
259 "WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC"},
260 {WARN_SAMEPARTY_EXCLUSION_OVERRULED_SAMESITE,
261 "WARN_SAMEPARTY_EXCLUSION_OVERRULED_SAMESITE"},
262 {WARN_SAMEPARTY_INCLUSION_OVERRULED_SAMESITE,
263 "WARN_SAMEPARTY_INCLUSION_OVERRULED_SAMESITE"},
cfredric362c4a02021-07-09 22:40:40264 {WARN_SAMESITE_NONE_REQUIRED, "WARN_SAMESITE_NONE_REQUIRED"},
265 {WARN_SAMESITE_NONE_INCLUDED_BY_SAMEPARTY_TOP_RESOURCE,
266 "WARN_SAMESITE_NONE_INCLUDED_BY_SAMEPARTY_TOP_RESOURCE"},
267 {WARN_SAMESITE_NONE_INCLUDED_BY_SAMEPARTY_ANCESTORS,
268 "WARN_SAMESITE_NONE_INCLUDED_BY_SAMEPARTY_ANCESTORS"},
269 {WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_LAX,
270 "WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_LAX"},
271 {WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_STRICT,
272 "WARN_SAMESITE_NONE_INCLUDED_BY_SAMESITE_STRICT"},
Lily Chen2db3a422021-07-20 18:02:25273 {WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION,
274 "WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION"},
Jonathan Njeunjea9eee5f2021-09-15 14:24:45275 {WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE,
276 "WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE"},
cfredrica50e8532021-06-29 19:44:56277 }) {
278 if (HasWarningReason(reason.first))
279 base::StrAppend(&out, {reason.second, ", "});
Lily Chenef77a172021-02-22 22:42:26280 }
Jihwan Marc Kim3e132f12020-05-20 17:33:19281
282 // Strip trailing comma and space.
283 out.erase(out.end() - 2, out.end());
284
285 return out;
286}
287
Jihwan Marc Kim3e132f12020-05-20 17:33:19288bool CookieInclusionStatus::HasExactlyExclusionReasonsForTesting(
289 std::vector<CookieInclusionStatus::ExclusionReason> reasons) const {
290 CookieInclusionStatus expected = MakeFromReasonsForTesting(reasons);
291 return expected.exclusion_reasons_ == exclusion_reasons_;
292}
293
294bool CookieInclusionStatus::HasExactlyWarningReasonsForTesting(
295 std::vector<WarningReason> reasons) const {
296 CookieInclusionStatus expected = MakeFromReasonsForTesting({}, reasons);
297 return expected.warning_reasons_ == warning_reasons_;
298}
299
300// static
Matt Reichhoff4b2311eef2021-10-01 20:56:59301bool CookieInclusionStatus::ValidateExclusionAndWarningFromWire(
302 uint32_t exclusion_reasons,
303 uint32_t warning_reasons) {
304 uint32_t exclusion_mask =
305 static_cast<uint32_t>(~0ul << ExclusionReason::NUM_EXCLUSION_REASONS);
306 uint32_t warning_mask =
307 static_cast<uint32_t>(~0ul << WarningReason::NUM_WARNING_REASONS);
308 return (exclusion_reasons & exclusion_mask) == 0 &&
309 (warning_reasons & warning_mask) == 0;
310}
311
Jihwan Marc Kim3e132f12020-05-20 17:33:19312CookieInclusionStatus CookieInclusionStatus::MakeFromReasonsForTesting(
313 std::vector<ExclusionReason> reasons,
314 std::vector<WarningReason> warnings) {
315 CookieInclusionStatus status;
316 for (ExclusionReason reason : reasons) {
317 status.AddExclusionReason(reason);
318 }
319 for (WarningReason warning : warnings) {
320 status.AddWarningReason(warning);
321 }
322 return status;
323}
324
325} // namespace net