123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- // Copyright (c) 2012 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.
- // Brought to you by number 42.
- #ifndef NET_COOKIES_COOKIE_OPTIONS_H_
- #define NET_COOKIES_COOKIE_OPTIONS_H_
- #include <ostream>
- #include "net/base/net_export.h"
- #include "net/cookies/cookie_constants.h"
- #include "net/cookies/cookie_inclusion_status.h"
- #include "net/cookies/same_party_context.h"
- #include "url/gurl.h"
- namespace net {
- class NET_EXPORT CookieOptions {
- public:
- // Relation between the cookie and the navigational environment.
- class NET_EXPORT SameSiteCookieContext {
- public:
- // CROSS_SITE to SAME_SITE_STRICT are ordered from least to most trusted
- // environment. Don't renumber, used in histograms.
- enum class ContextType {
- CROSS_SITE = 0,
- // Same rules as lax but the http method is unsafe.
- SAME_SITE_LAX_METHOD_UNSAFE = 1,
- SAME_SITE_LAX = 2,
- SAME_SITE_STRICT = 3,
- // Keep last, used for histograms.
- COUNT
- };
- // Holds metadata about the factors that went into deciding the ContextType.
- //
- // These values may be used for recording histograms or
- // CookieInclusionStatus warnings, but SHOULD NOT be relied
- // upon for cookie inclusion decisions. Use only the ContextTypes for that.
- //
- // When adding a field, also update CompleteEquivalenceForTesting.
- struct NET_EXPORT ContextMetadata {
- // Possible "downgrades" for the SameSite context type, e.g. from a more
- // trusted context to a less trusted context, as a result of some behavior
- // change affecting the same-site calculation.
- enum class ContextDowngradeType {
- // Context not downgraded.
- kNoDowngrade,
- // Context was originally strictly same-site, was downgraded to laxly
- // same-site.
- kStrictToLax,
- // Context was originally strictly same-site, was downgraded to
- // cross-site.
- kStrictToCross,
- // Context was originally laxly same-site, was downgraded to cross-site.
- kLaxToCross,
- };
- // These values are persisted to logs. Entries should not be renumbered
- // and numeric values should never be reused.
- // This enum is to help collect metrics for https://crbug.com/1221316.
- // Specifically it's to help indicate how many cookies are accessed with a
- // given redirect type in order to provide a denominator for the
- // Cookie.CrossSiteRedirectDowngradeChangesInclusion2.* metrics.
- // Note: for this enum the notation A->B->C means that a navigation from
- // A to B was redirected to C. I.e.: A is the initator of the navigation
- // and C is the final url.
- enum class ContextRedirectTypeBug1221316 {
- kUnset =
- 0, // Indicates this value was unused and shouldn't be read. E.x.:
- // A javascript access means this value is meaningless.
- kNoRedirect = 1, // There weren't any redirects. E.x.: A->B, A->A
- kCrossSiteRedirect =
- 2, // There was a redirect but it didn't start and
- // end at the same site or the redirect was to a different site
- // than the site-for-cookies. E.x.: A->B->C or B->B->B when the
- // site-for-cookies is A.
- kPartialSameSiteRedirect =
- 3, // There was a redirect and the start and
- // end are the same site. E.x.: A->B->A. Only this one could
- // potentially set cross_site_redirect_downgrade.
- kAllSameSiteRedirect = 4, // There was a redirect and all urls are the
- // same site. E.x.:, A->A->A
- kMaxValue = kAllSameSiteRedirect
- };
- // Records the type of any context downgrade due to a cross-site redirect,
- // i.e. whether the spec change in
- // https://github.com/httpwg/http-extensions/pull/1348 changed the result
- // of the context calculation. Note that a lax-to-cross downgrade can only
- // happen for response cookies, because a laxly same-site context only
- // happens for a top-level cross-site request, which cannot be downgraded
- // due to a cross-site redirect to a non-top-level cross-site request.
- // This only records whether the context was downgraded, not whether the
- // cookie's inclusion result was changed.
- ContextDowngradeType cross_site_redirect_downgrade =
- ContextDowngradeType::kNoDowngrade;
- ContextRedirectTypeBug1221316 redirect_type_bug_1221316 =
- ContextRedirectTypeBug1221316::kUnset;
- };
- // The following three constructors apply default values for the metadata
- // members.
- SameSiteCookieContext()
- : SameSiteCookieContext(ContextType::CROSS_SITE,
- ContextType::CROSS_SITE) {}
- explicit SameSiteCookieContext(ContextType same_site_context)
- : SameSiteCookieContext(same_site_context, same_site_context) {}
- SameSiteCookieContext(ContextType same_site_context,
- ContextType schemeful_same_site_context)
- : SameSiteCookieContext(same_site_context,
- schemeful_same_site_context,
- ContextMetadata(),
- ContextMetadata()) {}
- // Schemeful and schemeless context types are consistency-checked against
- // each other, but the metadata is stored as-is (i.e. the values in
- // `metadata` and `schemeful_metadata` may be logically inconsistent), as
- // the metadata is not relied upon for correctness.
- SameSiteCookieContext(ContextType same_site_context,
- ContextType schemeful_same_site_context,
- ContextMetadata metadata,
- ContextMetadata schemeful_metadata)
- : context_(same_site_context),
- schemeful_context_(schemeful_same_site_context),
- metadata_(metadata),
- schemeful_metadata_(schemeful_metadata) {
- DCHECK_LE(schemeful_context_, context_);
- }
- // Convenience method which returns a SameSiteCookieContext with the most
- // inclusive contexts. This allows access to all SameSite cookies.
- static SameSiteCookieContext MakeInclusive();
- // Convenience method which returns a SameSiteCookieContext with the most
- // inclusive contexts for set. This allows setting all SameSite cookies.
- static SameSiteCookieContext MakeInclusiveForSet();
- // Returns the context for determining SameSite cookie inclusion.
- ContextType GetContextForCookieInclusion() const;
- // Returns the metadata describing how this context was calculated, under
- // the currently applicable schemeful/schemeless mode.
- // TODO(chlily): Should take the CookieAccessSemantics as well, to
- // accurately account for the context actually used for a given cookie.
- const ContextMetadata& GetMetadataForCurrentSchemefulMode() const;
- // If you're just trying to determine if a cookie is accessible you likely
- // want to use GetContextForCookieInclusion() which will return the correct
- // context regardless the status of same-site features.
- ContextType context() const { return context_; }
- ContextType schemeful_context() const { return schemeful_context_; }
- // You probably want to use GetMetadataForCurrentSchemefulMode() instead of
- // these getters, since that takes into account the applicable schemeful
- // mode.
- const ContextMetadata& metadata() const { return metadata_; }
- ContextMetadata& metadata() { return metadata_; }
- const ContextMetadata& schemeful_metadata() const {
- return schemeful_metadata_;
- }
- ContextMetadata& schemeful_metadata() { return schemeful_metadata_; }
- // Sets context types. Does not check for consistency between context and
- // schemeful context. Does not touch the metadata.
- void SetContextTypesForTesting(ContextType context_type,
- ContextType schemeful_context_type);
- // Returns whether the context types and all fields of the metadata structs
- // are the same.
- bool CompleteEquivalenceForTesting(
- const SameSiteCookieContext& other) const;
- // Equality operators disregard any metadata! (Only the context types are
- // compared, not how they were computed.)
- NET_EXPORT friend bool operator==(
- const CookieOptions::SameSiteCookieContext& lhs,
- const CookieOptions::SameSiteCookieContext& rhs);
- NET_EXPORT friend bool operator!=(
- const CookieOptions::SameSiteCookieContext& lhs,
- const CookieOptions::SameSiteCookieContext& rhs);
- private:
- ContextType context_;
- ContextType schemeful_context_;
- ContextMetadata metadata_;
- ContextMetadata schemeful_metadata_;
- };
- // Creates a CookieOptions object which:
- //
- // * Excludes HttpOnly cookies
- // * Excludes SameSite cookies
- // * Updates last-accessed time.
- // * Does not report excluded cookies in APIs that can do so.
- // * Excludes SameParty cookies.
- //
- // These settings can be altered by calling:
- //
- // * |set_{include,exclude}_httponly()|
- // * |set_same_site_cookie_context()|
- // * |set_do_not_update_access_time()|
- // * |set_same_party_cookie_context_type()|
- CookieOptions();
- CookieOptions(const CookieOptions& other);
- CookieOptions(CookieOptions&& other);
- ~CookieOptions();
- CookieOptions& operator=(const CookieOptions&);
- CookieOptions& operator=(CookieOptions&&);
- void set_exclude_httponly() { exclude_httponly_ = true; }
- void set_include_httponly() { exclude_httponly_ = false; }
- bool exclude_httponly() const { return exclude_httponly_; }
- // How trusted is the current browser environment when it comes to accessing
- // SameSite cookies. Default is not trusted, e.g. CROSS_SITE.
- void set_same_site_cookie_context(const SameSiteCookieContext& context) {
- same_site_cookie_context_ = context;
- }
- const SameSiteCookieContext& same_site_cookie_context() const {
- return same_site_cookie_context_;
- }
- void set_update_access_time() { update_access_time_ = true; }
- void set_do_not_update_access_time() { update_access_time_ = false; }
- bool update_access_time() const { return update_access_time_; }
- void set_return_excluded_cookies() { return_excluded_cookies_ = true; }
- void unset_return_excluded_cookies() { return_excluded_cookies_ = false; }
- bool return_excluded_cookies() const { return return_excluded_cookies_; }
- void set_same_party_context(const SamePartyContext& context) {
- same_party_context_ = context;
- }
- const SamePartyContext& same_party_context() const {
- return same_party_context_;
- }
- // Getter/setter of |full_party_context_size_| for logging purposes.
- void set_full_party_context_size(uint32_t len) {
- full_party_context_size_ = len;
- }
- uint32_t full_party_context_size() const { return full_party_context_size_; }
- void set_is_in_nontrivial_first_party_set(bool is_member) {
- is_in_nontrivial_first_party_set_ = is_member;
- }
- bool is_in_nontrivial_first_party_set() const {
- return is_in_nontrivial_first_party_set_;
- }
- // Convenience method for where you need a CookieOptions that will
- // work for getting/setting all types of cookies, including HttpOnly and
- // SameSite cookies. Also specifies not to update the access time, because
- // usually this is done to get all the cookies to check that they are correct,
- // including the creation time. This basically makes a CookieOptions that is
- // the opposite of the default CookieOptions.
- static CookieOptions MakeAllInclusive();
- private:
- // Keep default values in sync with
- // content/public/common/cookie_manager.mojom.
- bool exclude_httponly_ = true;
- SameSiteCookieContext same_site_cookie_context_;
- bool update_access_time_ = true;
- bool return_excluded_cookies_ = false;
- SamePartyContext same_party_context_;
- // The size of the isolation_info.party_context plus the top-frame site.
- // Stored for logging purposes.
- uint32_t full_party_context_size_ = 0;
- // Whether the site requesting cookie access (as opposed to e.g. the
- // `site_for_cookies`) is a member (or owner) of a nontrivial First-Party
- // Set.
- // This is included here temporarily, for the purpose of ignoring SameParty
- // for sites that are not participating in the Origin Trial.
- // TODO(https://crbug.com/1163990): remove this field.
- bool is_in_nontrivial_first_party_set_ = false;
- };
- NET_EXPORT bool operator==(
- const CookieOptions::SameSiteCookieContext::ContextMetadata& lhs,
- const CookieOptions::SameSiteCookieContext::ContextMetadata& rhs);
- NET_EXPORT bool operator!=(
- const CookieOptions::SameSiteCookieContext::ContextMetadata& lhs,
- const CookieOptions::SameSiteCookieContext::ContextMetadata& rhs);
- // Allows gtest to print more helpful error messages instead of printing hex.
- // (No need to null-check `os` because we can assume gtest will properly pass a
- // non-null pointer, and it is dereferenced immediately anyway.)
- inline void PrintTo(CookieOptions::SameSiteCookieContext::ContextType ct,
- std::ostream* os) {
- *os << static_cast<int>(ct);
- }
- inline void PrintTo(
- const CookieOptions::SameSiteCookieContext::ContextMetadata& m,
- std::ostream* os) {
- *os << "{";
- *os << " cross_site_redirect_downgrade: "
- << static_cast<int>(m.cross_site_redirect_downgrade);
- *os << ", redirect_type_bug_1221316: "
- << static_cast<int>(m.redirect_type_bug_1221316);
- *os << " }";
- }
- inline void PrintTo(const CookieOptions::SameSiteCookieContext& sscc,
- std::ostream* os) {
- *os << "{ context: ";
- PrintTo(sscc.context(), os);
- *os << ", schemeful_context: ";
- PrintTo(sscc.schemeful_context(), os);
- *os << ", metadata: ";
- PrintTo(sscc.metadata(), os);
- *os << ", schemeful_metadata: ";
- PrintTo(sscc.schemeful_metadata(), os);
- *os << " }";
- }
- } // namespace net
- #endif // NET_COOKIES_COOKIE_OPTIONS_H_
|