diff options
Diffstat (limited to 'chromium/net/cookies/cookie_inclusion_status.h')
-rw-r--r-- | chromium/net/cookies/cookie_inclusion_status.h | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/chromium/net/cookies/cookie_inclusion_status.h b/chromium/net/cookies/cookie_inclusion_status.h new file mode 100644 index 00000000000..3f38eddb39b --- /dev/null +++ b/chromium/net/cookies/cookie_inclusion_status.h @@ -0,0 +1,275 @@ +// 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. Any information contained in WarningReason + // of an included cookie may be passed to an untrusted renderer. + // 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 is applied to a cookie that may be part of a "double cookie" pair + // used for compatibility reasons. These pairs consist of one cookie that + // has "SameSite=None; Secure" and a duplicate cookie that leaves SameSite + // unspecified to maintain compatibility with browsers that do not support + // the "SameSite=None" attribute. This warning is applied to both + // members of the pair. See cookie_util::IsSameSiteCompatPair(). + // + // If computing this for a cookie access attempt from a non-network context + // (i.e. script), this should not be applied if either member of the pair is + // HttpOnly, to avoid leaking information about the name and value of + // HttpOnly cookies to an untrusted renderer. + // + // This is only relevant if WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT is + // present on the same status or a status for a cookie accessed at the same + // time, so it may not be applied at other times (e.g. when the context is + // same-site). + WARN_SAMESITE_COMPAT_PAIR = 8, + + // 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_ |