0

Refactor CookieOptions::SameSiteCookieContext to carry metadata

Previously, ComputeSameSiteContext() returned a pair<ContextType, bool>,
with the result and a piece of metadata about the factors that went into
the calculation. This CL refactors the pair into a struct, and wraps the
bool in a ContextMetadata struct to make it more extensible for future
changes.

The metadata is to be used for metrics and warnings only, not for
deciding cookie inclusion. Only the existing ContextTypes should be used
for deciding cookie inclusion.

Additionally, add previously missing mojom conversions for the metadata.

Change-Id: I6f68d474005f42661adf83034df6401384d143bc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2971344
Auto-Submit: Lily Chen <chlily@chromium.org>
Reviewed-by: Chris Thompson <cthomp@chromium.org>
Reviewed-by: Steven Bingler <bingler@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Lily Chen <chlily@chromium.org>
Cr-Commit-Position: refs/heads/master@{#896098}
This commit is contained in:
Lily Chen
2021-06-25 17:12:24 +00:00
committed by Chromium LUCI CQ
parent c14c24d52a
commit c321530e7e
8 changed files with 230 additions and 95 deletions

@ -33,10 +33,22 @@ CookieOptions::SameSiteCookieContext::GetContextForCookieInclusion() const {
return context_;
}
const CookieOptions::SameSiteCookieContext::ContextMetadata&
CookieOptions::SameSiteCookieContext::GetMetadataForCurrentSchemefulMode()
const {
return cookie_util::IsSchemefulSameSiteEnabled() ? schemeful_metadata()
: metadata();
}
void CookieOptions::SameSiteCookieContext::SetContextTypesForTesting(
ContextType context_type,
ContextType schemeful_context_type) {
context_ = context_type;
schemeful_context_ = schemeful_context_type;
}
bool CookieOptions::SameSiteCookieContext::AffectedByBugfix1166211() const {
return cookie_util::IsSchemefulSameSiteEnabled()
? schemeful_affected_by_bugfix_1166211_
: affected_by_bugfix_1166211_;
return GetMetadataForCurrentSchemefulMode().affected_by_bugfix_1166211;
}
void CookieOptions::SameSiteCookieContext::
@ -58,6 +70,17 @@ void CookieOptions::SameSiteCookieContext::
"Cookie.SameSiteCookieInclusionChangedByBugfix1166211", changed);
}
bool CookieOptions::SameSiteCookieContext::CompleteEquivalenceForTesting(
const SameSiteCookieContext& other) const {
bool metadata_equal = metadata_.affected_by_bugfix_1166211 ==
other.metadata().affected_by_bugfix_1166211;
bool schemeful_metadata_equal =
schemeful_metadata_.affected_by_bugfix_1166211 ==
other.schemeful_metadata().affected_by_bugfix_1166211;
return *this == other && metadata_equal && schemeful_metadata_equal;
}
bool operator==(const CookieOptions::SameSiteCookieContext& lhs,
const CookieOptions::SameSiteCookieContext& rhs) {
return std::tie(lhs.context_, lhs.schemeful_context_) ==
@ -71,11 +94,8 @@ bool operator!=(const CookieOptions::SameSiteCookieContext& lhs,
// Keep default values in sync with content/public/common/cookie_manager.mojom.
CookieOptions::CookieOptions()
: exclude_httponly_(true),
same_site_cookie_context_(SameSiteCookieContext(
SameSiteCookieContext::ContextType::CROSS_SITE)),
update_access_time_(true),
return_excluded_cookies_(false) {}
: same_site_cookie_context_(SameSiteCookieContext(
SameSiteCookieContext::ContextType::CROSS_SITE)) {}
CookieOptions::CookieOptions(const CookieOptions& other) = default;
CookieOptions::CookieOptions(CookieOptions&& other) = default;

@ -37,16 +37,48 @@ class NET_EXPORT CookieOptions {
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 {
// Whether the ContextType calculation was affected by the bugfix for
// crbug.com/1166211.
// TODO(crbug.com/1166211): Remove once no longer needed.
bool affected_by_bugfix_1166211 = false;
};
// 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) {
schemeful_context_(schemeful_same_site_context),
metadata_(metadata),
schemeful_metadata_(schemeful_metadata) {
DCHECK_LE(schemeful_context_, context_);
}
@ -61,27 +93,38 @@ class NET_EXPORT CookieOptions {
// 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_; }
void set_context(ContextType context) { context_ = context; }
void set_context(std::pair<ContextType, bool> context) {
context_ = context.first;
affected_by_bugfix_1166211_ = context.second;
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_; }
const ContextMetadata& schemeful_metadata() const {
return schemeful_metadata_;
}
ContextType schemeful_context() const { return schemeful_context_; }
void set_schemeful_context(ContextType schemeful_context) {
schemeful_context_ = schemeful_context;
}
void set_schemeful_context(std::pair<ContextType, bool> schemeful_context) {
schemeful_context_ = schemeful_context.first;
schemeful_affected_by_bugfix_1166211_ = schemeful_context.second;
}
// 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);
// Whether the request was affected by the bugfix, either schemefully or
// schemelessly.
// schemelessly. This only takes the current Schemeful Same-Site Feature
// status into account, and does not take into account the access semantics
// used to access the cookie. (This is fine, because the call sites only
// look at cookies which were actually excluded due to SameSite=Lax or
// unspecified-Lax, which means that cookies with access semantics not
// matching the Feature state will be ignored.)
// TODO(crbug.com/1166211): Remove once no longer needed.
bool AffectedByBugfix1166211() const;
@ -92,6 +135,13 @@ class NET_EXPORT CookieOptions {
void MaybeApplyBugfix1166211WarningToStatusAndLogHistogram(
CookieInclusionStatus& status) const;
// 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);
@ -103,15 +153,8 @@ class NET_EXPORT CookieOptions {
ContextType context_;
ContextType schemeful_context_;
// Record whether the ContextType calculation was affected by the bugfix for
// crbug.com/1166211. These are for the purpose of recording histograms and
// adding warnings to CookieInclusionStatus.
// Note: These are not preserved when serializing/deserializing for mojo, as
// these are only used in URLRequestHttpJob, which does not make mojo calls
// with this struct (it is only relevant for HTTP requests).
// TODO(crbug.com/1166211): Remove once no longer needed.
bool affected_by_bugfix_1166211_ = false;
bool schemeful_affected_by_bugfix_1166211_ = false;
ContextMetadata metadata_;
ContextMetadata schemeful_metadata_;
};
// Computed in URLRequestHttpJob for every cookie access attempt but is only
@ -152,11 +195,11 @@ class NET_EXPORT CookieOptions {
// 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(SameSiteCookieContext context) {
void set_same_site_cookie_context(const SameSiteCookieContext& context) {
same_site_cookie_context_ = context;
}
SameSiteCookieContext same_site_cookie_context() const {
const SameSiteCookieContext& same_site_cookie_context() const {
return same_site_cookie_context_;
}
@ -200,9 +243,11 @@ class NET_EXPORT CookieOptions {
static CookieOptions MakeAllInclusive();
private:
bool exclude_httponly_;
// 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_;
bool update_access_time_ = true;
bool return_excluded_cookies_ = false;
SamePartyCookieContextType same_party_cookie_context_type_ =

@ -28,6 +28,7 @@
#include "net/cookies/cookie_access_delegate.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_options.h"
#include "net/http/http_util.h"
#include "url/gurl.h"
#include "url/url_constants.h"
@ -38,6 +39,7 @@ namespace cookie_util {
namespace {
using ContextType = CookieOptions::SameSiteCookieContext::ContextType;
using ContextMetadata = CookieOptions::SameSiteCookieContext::ContextMetadata;
base::Time MinNonNullTime() {
return base::Time::FromInternalValue(1);
@ -86,6 +88,19 @@ bool SaturatedTimeFromUTCExploded(const base::Time::Exploded& exploded,
return false;
}
struct ComputeSameSiteContextResult {
ContextType context_type = ContextType::CROSS_SITE;
ContextMetadata metadata;
};
CookieOptions::SameSiteCookieContext MakeSameSiteCookieContext(
const ComputeSameSiteContextResult& result,
const ComputeSameSiteContextResult& schemeful_result) {
return CookieOptions::SameSiteCookieContext(
result.context_type, schemeful_result.context_type, result.metadata,
schemeful_result.metadata);
}
// This function consolidates the common logic for computing SameSite cookie
// access context in various situations (HTTP vs JS; get vs set).
//
@ -96,14 +111,9 @@ bool SaturatedTimeFromUTCExploded(const base::Time::Exploded& exploded,
// schemeful_context, i.e. whether scheme should be considered when comparing
// two sites.
//
// The bool in the return value is whether the ContextType return value was
// affected by bugfix 1166211, used for CookieInclusionStatus warnings and
// histogramming.
// TODO(crbug.com/1166211): Remove when no longer needed.
//
// See documentation of `ComputeSameSiteContextForRequest` for explanations of
// other parameters.
std::pair<ContextType, bool> ComputeSameSiteContext(
ComputeSameSiteContextResult ComputeSameSiteContext(
const std::vector<GURL>& url_chain,
const SiteForCookies& site_for_cookies,
const absl::optional<url::Origin>& initiator,
@ -129,8 +139,11 @@ std::pair<ContextType, bool> ComputeSameSiteContext(
site_for_cookies.IsNull());
DCHECK(!is_main_frame_navigation || !request_url.SchemeIsWSOrWSS());
// Defaults to a cross-site context type.
ComputeSameSiteContextResult result;
if (!site_for_cookies_is_same_site)
return {ContextType::CROSS_SITE, false};
return result;
// Create a SiteForCookies object from the initiator so that we can reuse
// IsFirstPartyWithSchemefulMode().
@ -151,7 +164,8 @@ std::pair<ContextType, bool> ComputeSameSiteContext(
(!base::FeatureList::IsEnabled(
features::kCookieSameSiteConsidersRedirectChain) ||
same_site_redirect_chain)) {
return {ContextType::SAME_SITE_STRICT, false};
result.context_type = ContextType::SAME_SITE_STRICT;
return result;
}
if (is_http) {
@ -160,13 +174,19 @@ std::pair<ContextType, bool> ComputeSameSiteContext(
}
// Preserve old behavior if the bugfix is disabled.
if (!base::FeatureList::IsEnabled(features::kSameSiteCookiesBugfix1166211))
return {ContextType::SAME_SITE_LAX, false};
if (!base::FeatureList::IsEnabled(features::kSameSiteCookiesBugfix1166211)) {
result.context_type = ContextType::SAME_SITE_LAX;
return result;
}
if (!is_http || is_main_frame_navigation)
return {ContextType::SAME_SITE_LAX, false};
if (!is_http || is_main_frame_navigation) {
result.context_type = ContextType::SAME_SITE_LAX;
return result;
}
return {ContextType::CROSS_SITE, true};
// Defaults to a cross-site context type.
result.metadata.affected_by_bugfix_1166211 = true;
return result;
}
CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSet(
@ -177,21 +197,21 @@ CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSet(
bool is_main_frame_navigation) {
CookieOptions::SameSiteCookieContext same_site_context;
same_site_context.set_context(ComputeSameSiteContext(
ComputeSameSiteContextResult result = ComputeSameSiteContext(
url_chain, site_for_cookies, initiator, is_http, is_main_frame_navigation,
false /* compute_schemefully */));
same_site_context.set_schemeful_context(ComputeSameSiteContext(
false /* compute_schemefully */);
ComputeSameSiteContextResult schemeful_result = ComputeSameSiteContext(
url_chain, site_for_cookies, initiator, is_http, is_main_frame_navigation,
true /* compute_schemefully */));
true /* compute_schemefully */);
// Setting any SameSite={Strict,Lax} cookie only requires a LAX context, so
// normalize any strictly same-site contexts to Lax for cookie writes.
if (same_site_context.context() == ContextType::SAME_SITE_STRICT)
same_site_context.set_context(ContextType::SAME_SITE_LAX);
if (same_site_context.schemeful_context() == ContextType::SAME_SITE_STRICT)
same_site_context.set_schemeful_context(ContextType::SAME_SITE_LAX);
if (result.context_type == ContextType::SAME_SITE_STRICT)
result.context_type = ContextType::SAME_SITE_LAX;
if (schemeful_result.context_type == ContextType::SAME_SITE_STRICT)
schemeful_result.context_type = ContextType::SAME_SITE_LAX;
return same_site_context;
return MakeSameSiteCookieContext(result, schemeful_result);
}
bool CookieWithAccessResultSorter(const CookieWithAccessResult& a,
@ -576,28 +596,23 @@ CookieOptions::SameSiteCookieContext ComputeSameSiteContextForRequest(
if (force_ignore_site_for_cookies)
return CookieOptions::SameSiteCookieContext::MakeInclusive();
CookieOptions::SameSiteCookieContext same_site_context;
same_site_context.set_context(ComputeSameSiteContext(
ComputeSameSiteContextResult result = ComputeSameSiteContext(
url_chain, site_for_cookies, initiator, true /* is_http */,
is_main_frame_navigation, false /* compute_schemefully */));
same_site_context.set_schemeful_context(ComputeSameSiteContext(
is_main_frame_navigation, false /* compute_schemefully */);
ComputeSameSiteContextResult schemeful_result = ComputeSameSiteContext(
url_chain, site_for_cookies, initiator, true /* is_http */,
is_main_frame_navigation, true /* compute_schemefully */));
is_main_frame_navigation, true /* compute_schemefully */);
// If the method is safe, the context is Lax. Otherwise, make a note that
// the method is unsafe.
if (!net::HttpUtil::IsMethodSafe(http_method)) {
if (same_site_context.context() == ContextType::SAME_SITE_LAX) {
same_site_context.set_context(ContextType::SAME_SITE_LAX_METHOD_UNSAFE);
}
if (same_site_context.schemeful_context() == ContextType::SAME_SITE_LAX) {
same_site_context.set_schemeful_context(
ContextType::SAME_SITE_LAX_METHOD_UNSAFE);
}
if (result.context_type == ContextType::SAME_SITE_LAX)
result.context_type = ContextType::SAME_SITE_LAX_METHOD_UNSAFE;
if (schemeful_result.context_type == ContextType::SAME_SITE_LAX)
schemeful_result.context_type = ContextType::SAME_SITE_LAX_METHOD_UNSAFE;
}
return same_site_context;
return MakeSameSiteCookieContext(result, schemeful_result);
}
NET_EXPORT CookieOptions::SameSiteCookieContext
@ -608,18 +623,16 @@ ComputeSameSiteContextForScriptGet(const GURL& url,
if (force_ignore_site_for_cookies)
return CookieOptions::SameSiteCookieContext::MakeInclusive();
CookieOptions::SameSiteCookieContext same_site_context;
// We don't check the redirect chain for script access to cookies (only the
// URL itself).
same_site_context.set_context(ComputeSameSiteContext(
ComputeSameSiteContextResult result = ComputeSameSiteContext(
{url}, site_for_cookies, initiator, false /* is_http */,
false /* is_main_frame_navigation */, false /* compute_schemefully */));
same_site_context.set_schemeful_context(ComputeSameSiteContext(
false /* is_main_frame_navigation */, false /* compute_schemefully */);
ComputeSameSiteContextResult schemeful_result = ComputeSameSiteContext(
{url}, site_for_cookies, initiator, false /* is_http */,
false /* is_main_frame_navigation */, true /* compute_schemefully */));
false /* is_main_frame_navigation */, true /* compute_schemefully */);
return same_site_context;
return MakeSameSiteCookieContext(result, schemeful_result);
}
CookieOptions::SameSiteCookieContext ComputeSameSiteContextForResponse(

@ -299,6 +299,15 @@ bool EnumTraits<network::mojom::CookieChangeCause, net::CookieChangeCause>::
return false;
}
bool StructTraits<network::mojom::CookieSameSiteContextMetadataDataView,
net::CookieOptions::SameSiteCookieContext::ContextMetadata>::
Read(network::mojom::CookieSameSiteContextMetadataDataView data,
net::CookieOptions::SameSiteCookieContext::ContextMetadata* out) {
out->affected_by_bugfix_1166211 = data.affected_by_bugfix_1166211();
return true;
}
bool StructTraits<network::mojom::CookieSameSiteContextDataView,
net::CookieOptions::SameSiteCookieContext>::
Read(network::mojom::CookieSameSiteContextDataView mojo_context,
@ -315,8 +324,16 @@ bool StructTraits<network::mojom::CookieSameSiteContextDataView,
if (schemeful_context > context_type)
return false;
*context = net::CookieOptions::SameSiteCookieContext(context_type,
schemeful_context);
net::CookieOptions::SameSiteCookieContext::ContextMetadata metadata;
if (!mojo_context.ReadMetadata(&metadata))
return false;
net::CookieOptions::SameSiteCookieContext::ContextMetadata schemeful_metadata;
if (!mojo_context.ReadSchemefulMetadata(&schemeful_metadata))
return false;
*context = net::CookieOptions::SameSiteCookieContext(
context_type, schemeful_context, metadata, schemeful_metadata);
return true;
}

@ -77,19 +77,42 @@ struct EnumTraits<network::mojom::CookieChangeCause, net::CookieChangeCause> {
net::CookieChangeCause* output);
};
template <>
struct StructTraits<
network::mojom::CookieSameSiteContextMetadataDataView,
net::CookieOptions::SameSiteCookieContext::ContextMetadata> {
static bool affected_by_bugfix_1166211(
const net::CookieOptions::SameSiteCookieContext::ContextMetadata& m) {
return m.affected_by_bugfix_1166211;
}
static bool Read(network::mojom::CookieSameSiteContextMetadataDataView,
net::CookieOptions::SameSiteCookieContext::ContextMetadata*);
};
template <>
struct StructTraits<network::mojom::CookieSameSiteContextDataView,
net::CookieOptions::SameSiteCookieContext> {
static net::CookieOptions::SameSiteCookieContext::ContextType context(
net::CookieOptions::SameSiteCookieContext& s) {
const net::CookieOptions::SameSiteCookieContext& s) {
return s.context();
}
static net::CookieOptions::SameSiteCookieContext::ContextType
schemeful_context(net::CookieOptions::SameSiteCookieContext& s) {
schemeful_context(const net::CookieOptions::SameSiteCookieContext& s) {
return s.schemeful_context();
}
static const net::CookieOptions::SameSiteCookieContext::ContextMetadata&
metadata(const net::CookieOptions::SameSiteCookieContext& s) {
return s.metadata();
}
static const net::CookieOptions::SameSiteCookieContext::ContextMetadata&
schemeful_metadata(const net::CookieOptions::SameSiteCookieContext& s) {
return s.schemeful_metadata();
}
static bool Read(network::mojom::CookieSameSiteContextDataView mojo_options,
net::CookieOptions::SameSiteCookieContext* context);
};

@ -289,21 +289,27 @@ TEST(CookieManagerTraitsTest, Roundtrips_CookieSameSiteContext) {
ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_STRICT};
for (ContextType context_type : all_context_types) {
for (ContextType schemeful_context_type : all_context_types) {
net::CookieOptions::SameSiteCookieContext context_in, copy;
// We want to test malformed SameSiteCookieContexts. Since the constructor
// will DCHECK for these use the setters to bypass it.
context_in.set_context(context_type);
context_in.set_schemeful_context(schemeful_context_type);
for (bool metadata_affected_by_bugfix_1166211 : {true, false}) {
net::CookieOptions::SameSiteCookieContext::ContextMetadata metadata;
metadata.affected_by_bugfix_1166211 = metadata_affected_by_bugfix_1166211;
for (ContextType context_type : all_context_types) {
for (ContextType schemeful_context_type : all_context_types) {
net::CookieOptions::SameSiteCookieContext copy;
net::CookieOptions::SameSiteCookieContext context_in(
context_type, context_type, metadata, metadata);
// We want to test malformed SameSiteCookieContexts. Since the
// constructor will DCHECK for these use this setter to bypass it.
context_in.SetContextTypesForTesting(context_type,
schemeful_context_type);
EXPECT_EQ(
mojo::test::SerializeAndDeserialize<mojom::CookieSameSiteContext>(
context_in, copy),
schemeful_context_type <= context_type);
EXPECT_EQ(
mojo::test::SerializeAndDeserialize<mojom::CookieSameSiteContext>(
context_in, copy),
schemeful_context_type <= context_type);
if (schemeful_context_type <= context_type)
EXPECT_EQ(context_in, copy);
if (schemeful_context_type <= context_type)
EXPECT_TRUE(context_in.CompleteEquivalenceForTesting(copy));
}
}
}
}

@ -679,6 +679,10 @@ mojom("cookies_mojom") {
mojom = "network.mojom.CookieEffectiveSameSite"
cpp = "::net::CookieEffectiveSameSite"
},
{
mojom = "network.mojom.CookieSameSiteContextMetadata"
cpp = "::net::CookieOptions::SameSiteCookieContext::ContextMetadata"
},
{
mojom = "network.mojom.CookieSameSiteContext"
cpp = "::net::CookieOptions::SameSiteCookieContext"

@ -95,10 +95,17 @@ enum ContextType {
SAME_SITE_STRICT
};
// Keep defaults here in sync with net/cookies/cookie_options.h.
struct CookieSameSiteContextMetadata {
bool affected_by_bugfix_1166211 = false;
};
// Keep defaults here in sync with net/cookies/cookie_options.h.
struct CookieSameSiteContext {
ContextType context = CROSS_SITE;
ContextType schemeful_context = CROSS_SITE;
CookieSameSiteContextMetadata metadata;
CookieSameSiteContextMetadata schemeful_metadata;
};
// Computed for every cookie access attempt but is only relevant for SameParty