Unnest CanonicalCookie::CookieInclusionStatus
The nesting of CookieInclusionStatus inside CanonicalCookie is a
holdover from when it was just an enum.
There's really no great reason to keep it that way,
so we should unnest it and move it to its own file.
[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
TBRing reviewers:
boliu: Please review changes to android_webview/
avi: Please review changes to chrome/
droger: Please review changes to component/signin/
alexmos: Please review changes to content/
ajgo: Please review changes to fuchsia/
mrefaat: Please review changes to ios/
agl: Please review changes to net/
blundell: Please review changes to services/
Bug: 1080767
Change-Id: Ieb9570ceeecd9ae3c2025ad46387aaef820995e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2203171
Reviewed-by: David Roger <[email protected]>
Reviewed-by: Bo <[email protected]>
Reviewed-by: Avi Drissman <[email protected]>
Reviewed-by: Alex Gough <[email protected]>
Reviewed-by: Lily Chen <[email protected]>
Commit-Queue: Lily Chen <[email protected]>
Cr-Commit-Position: refs/heads/master@{#770652}
diff --git a/net/cookies/cookie_inclusion_status.h b/net/cookies/cookie_inclusion_status.h
new file mode 100644
index 0000000..8f958a4
--- /dev/null
+++ b/net/cookies/cookie_inclusion_status.h
@@ -0,0 +1,256 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
+#define NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
+
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+
+class GURL;
+
+namespace net {
+
+// This class represents if a cookie was included or excluded in a cookie get or
+// set operation, and if excluded why. It holds a vector of reasons for
+// exclusion, where cookie inclusion is represented by the absence of any
+// exclusion reasons. Also marks whether a cookie should be warned about, e.g.
+// for deprecation or intervention reasons.
+class NET_EXPORT CookieInclusionStatus {
+ public:
+ // Types of reasons why a cookie might be excluded.
+ // If adding a ExclusionReason, please also update the GetDebugString()
+ // method.
+ enum ExclusionReason {
+ EXCLUDE_UNKNOWN_ERROR = 0,
+
+ EXCLUDE_HTTP_ONLY = 1,
+ EXCLUDE_SECURE_ONLY = 2,
+ EXCLUDE_DOMAIN_MISMATCH = 3,
+ EXCLUDE_NOT_ON_PATH = 4,
+ EXCLUDE_SAMESITE_STRICT = 5,
+ EXCLUDE_SAMESITE_LAX = 6,
+
+ // The following two are used for the SameSiteByDefaultCookies experiment,
+ // where if the SameSite attribute is not specified, it will be treated as
+ // SameSite=Lax by default.
+ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX = 7,
+ // This is used if SameSite=None is specified, but the cookie is not
+ // Secure.
+ EXCLUDE_SAMESITE_NONE_INSECURE = 8,
+ EXCLUDE_USER_PREFERENCES = 9,
+
+ // Statuses specific to setting cookies
+ EXCLUDE_FAILURE_TO_STORE = 10,
+ EXCLUDE_NONCOOKIEABLE_SCHEME = 11,
+ EXCLUDE_OVERWRITE_SECURE = 12,
+ EXCLUDE_OVERWRITE_HTTP_ONLY = 13,
+ EXCLUDE_INVALID_DOMAIN = 14,
+ EXCLUDE_INVALID_PREFIX = 15,
+
+ // This should be kept last.
+ NUM_EXCLUSION_REASONS
+ };
+
+ // Reason to warn about a cookie. If you add one, please update
+ // GetDebugString().
+ enum WarningReason {
+ // Of the following 3 SameSite warnings, there will be, at most, a single
+ // active one.
+
+ // Warn if a cookie with unspecified SameSite attribute is used in a
+ // cross-site context.
+ WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT = 0,
+ // Warn if a cookie with SameSite=None is not Secure.
+ WARN_SAMESITE_NONE_INSECURE = 1,
+ // Warn if a cookie with unspecified SameSite attribute is defaulted into
+ // Lax and is sent on a request with unsafe method, only because it is new
+ // enough to activate the Lax-allow-unsafe intervention.
+ WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE = 2,
+
+ // The following warnings indicate that an included cookie with an effective
+ // SameSite is experiencing a SameSiteCookieContext::|context| ->
+ // SameSiteCookieContext::|schemeful_context| downgrade that will prevent
+ // its access schemefully.
+ // This situation means that a cookie is accessible when the
+ // SchemefulSameSite feature is disabled but not when it's enabled,
+ // indicating changed behavior and potential breakage.
+ //
+ // For example, a Strict to Lax downgrade for an effective SameSite=Strict
+ // cookie:
+ // This cookie would be accessible in the Strict context as its SameSite
+ // value is Strict. However its context for schemeful same-site becomes Lax.
+ // A strict cookie cannot be accessed in a Lax context and therefore the
+ // behavior has changed.
+ // As a counterexample, a Strict to Lax downgrade for an effective
+ // SameSite=Lax cookie: A Lax cookie can be accessed in both Strict and Lax
+ // contexts so there is no behavior change (and we don't warn about it).
+ //
+ // The warnings are in the following format:
+ // WARN_{context}_{schemeful_context}_DOWNGRADE_{samesite_value}_SAMESITE
+ //
+ // Of the following 5 SameSite warnings, there will be, at most, a single
+ // active one.
+
+ // Strict to Lax downgrade for an effective SameSite=Strict cookie.
+ // This warning is only applicable for cookies being sent because a Strict
+ // cookie will be set in both Strict and Lax Contexts so the downgrade will
+ // not affect it.
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE = 3,
+ // Strict to Cross-site downgrade for an effective SameSite=Strict cookie.
+ // This also applies to Strict to Lax Unsafe downgrades due to Lax Unsafe
+ // behaving like Cross-site.
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE = 4,
+ // Strict to Cross-site downgrade for an effective SameSite=Lax cookie.
+ // This also applies to Strict to Lax Unsafe downgrades due to Lax Unsafe
+ // behaving like Cross-site.
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE = 5,
+ // Lax to Cross-site downgrade for an effective SameSite=Strict cookie.
+ // This warning is only applicable for cookies being set because a Strict
+ // cookie will not be sent in a Lax context so the downgrade would not
+ // affect it.
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE = 6,
+ // Lax to Cross-site downgrade for an effective SameSite=Lax cookie.
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE = 7,
+
+ // This should be kept last.
+ NUM_WARNING_REASONS
+ };
+
+ // These enums encode the context downgrade warnings + the secureness of the
+ // url sending/setting the cookie. They're used for metrics only. The format
+ // is {context}_{schemeful_context}_{samesite_value}_{securness}.
+ // NO_DOWNGRADE_{securness} indicates that a cookie didn't have a breaking
+ // context downgrade and was A) included B) excluded only due to insufficient
+ // same-site context. I.e. the cookie wasn't excluded due to other reasons
+ // such as third-party cookie blocking. Keep this in line with
+ // SameSiteCookieContextBreakingDowngradeWithSecureness in enums.xml.
+ enum ContextDowngradeMetricValues {
+ NO_DOWNGRADE_INSECURE = 0,
+ NO_DOWNGRADE_SECURE = 1,
+
+ STRICT_LAX_STRICT_INSECURE = 2,
+ STRICT_CROSS_STRICT_INSECURE = 3,
+ STRICT_CROSS_LAX_INSECURE = 4,
+ LAX_CROSS_STRICT_INSECURE = 5,
+ LAX_CROSS_LAX_INSECURE = 6,
+
+ STRICT_LAX_STRICT_SECURE = 7,
+ STRICT_CROSS_STRICT_SECURE = 8,
+ STRICT_CROSS_LAX_SECURE = 9,
+ LAX_CROSS_STRICT_SECURE = 10,
+ LAX_CROSS_LAX_SECURE = 11,
+
+ // Keep last.
+ kMaxValue = LAX_CROSS_LAX_SECURE
+ };
+ // Makes a status that says include and should not warn.
+ CookieInclusionStatus();
+
+ // Make a status that contains the given exclusion reason.
+ explicit CookieInclusionStatus(ExclusionReason reason);
+ // Makes a status that contains the given exclusion reason and warning.
+ CookieInclusionStatus(ExclusionReason reason, WarningReason warning);
+
+ bool operator==(const CookieInclusionStatus& other) const;
+ bool operator!=(const CookieInclusionStatus& other) const;
+
+ // Whether the status is to include the cookie, and has no other reasons for
+ // exclusion.
+ bool IsInclude() const;
+
+ // Whether the given reason for exclusion is present.
+ bool HasExclusionReason(ExclusionReason status_type) const;
+
+ // Add an exclusion reason.
+ void AddExclusionReason(ExclusionReason status_type);
+
+ // Remove an exclusion reason.
+ void RemoveExclusionReason(ExclusionReason reason);
+
+ // If the cookie would have been excluded for reasons other than
+ // SAMESITE_UNSPECIFIED_TREATED_AS_LAX or SAMESITE_NONE_INSECURE, don't bother
+ // warning about it (clear the warning).
+ void MaybeClearSameSiteWarning();
+
+ // Whether to record the breaking downgrade metrics if the cookie is included
+ // or if it's only excluded because of insufficient same-site context.
+ bool ShouldRecordDowngradeMetrics() const;
+
+ // Whether the cookie should be warned about.
+ bool ShouldWarn() const;
+
+ // Whether the given reason for warning is present.
+ bool HasWarningReason(WarningReason reason) const;
+
+ // Whether a schemeful downgrade warning is present.
+ // A schemeful downgrade means that an included cookie with an effective
+ // SameSite is experiencing a SameSiteCookieContext::|context| ->
+ // SameSiteCookieContext::|schemeful_context| downgrade that will prevent its
+ // access schemefully. If the function returns true and |reason| is valid then
+ // |reason| will contain which warning was found.
+ bool HasDowngradeWarning(
+ CookieInclusionStatus::WarningReason* reason = nullptr) const;
+
+ // Add an warning reason.
+ void AddWarningReason(WarningReason reason);
+
+ // Remove an warning reason.
+ void RemoveWarningReason(WarningReason reason);
+
+ // Used for serialization/deserialization.
+ uint32_t exclusion_reasons() const { return exclusion_reasons_; }
+ void set_exclusion_reasons(uint32_t exclusion_reasons) {
+ exclusion_reasons_ = exclusion_reasons;
+ }
+
+ uint32_t warning_reasons() const { return warning_reasons_; }
+ void set_warning_reasons(uint32_t warning_reasons) {
+ warning_reasons_ = warning_reasons;
+ }
+
+ ContextDowngradeMetricValues GetBreakingDowngradeMetricsEnumValue(
+ const GURL& url) const;
+
+ // Get exclusion reason(s) and warning in string format.
+ std::string GetDebugString() const;
+
+ // Checks that the underlying bit vector representation doesn't contain any
+ // extraneous bits that are not mapped to any enum values. Does not check
+ // for reasons which semantically cannot coexist.
+ bool IsValid() const;
+
+ // Checks whether the exclusion reasons are exactly the set of exclusion
+ // reasons in the vector. (Ignores warnings.)
+ bool HasExactlyExclusionReasonsForTesting(
+ std::vector<ExclusionReason> reasons) const;
+
+ // Checks whether the warning reasons are exactly the set of warning
+ // reasons in the vector. (Ignores exclusions.)
+ bool HasExactlyWarningReasonsForTesting(
+ std::vector<WarningReason> reasons) const;
+
+ // Makes a status that contains the given exclusion reasons and warning.
+ static CookieInclusionStatus MakeFromReasonsForTesting(
+ std::vector<ExclusionReason> reasons,
+ std::vector<WarningReason> warnings = std::vector<WarningReason>());
+
+ private:
+ // A bit vector of the applicable exclusion reasons.
+ uint32_t exclusion_reasons_ = 0u;
+
+ // A bit vector of the applicable warning reasons.
+ uint32_t warning_reasons_ = 0u;
+};
+
+NET_EXPORT inline std::ostream& operator<<(std::ostream& os,
+ const CookieInclusionStatus status) {
+ return os << status.GetDebugString();
+}
+
+} // namespace net
+
+#endif // NET_COOKIES_COOKIE_INCLUSION_STATUS_H_