summaryrefslogtreecommitdiff
path: root/chromium/net/cookies
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-06 12:48:11 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:33:43 +0000
commit7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (patch)
treefa14ba0ca8d2683ba2efdabd246dc9b18a1229c6 /chromium/net/cookies
parent79b4f909db1049fca459c07cca55af56a9b54fe3 (diff)
downloadqtwebengine-chromium-7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3.tar.gz
BASELINE: Update Chromium to 84.0.4147.141
Change-Id: Ib85eb4cfa1cbe2b2b81e5022c8cad5c493969535 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/cookies')
-rw-r--r--chromium/net/cookies/canonical_cookie.cc410
-rw-r--r--chromium/net/cookies/canonical_cookie.h173
-rw-r--r--chromium/net/cookies/canonical_cookie_unittest.cc407
-rw-r--r--chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc2
-rw-r--r--chromium/net/cookies/cookie_constants.cc2
-rw-r--r--chromium/net/cookies/cookie_deletion_info.cc8
-rw-r--r--chromium/net/cookies/cookie_monster.cc86
-rw-r--r--chromium/net/cookies/cookie_monster.h6
-rw-r--r--chromium/net/cookies/cookie_monster_perftest.cc2
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc545
-rw-r--r--chromium/net/cookies/cookie_options.cc48
-rw-r--r--chromium/net/cookies/cookie_options.h82
-rw-r--r--chromium/net/cookies/cookie_store.h4
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.cc4
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.h2
-rw-r--r--chromium/net/cookies/cookie_store_unittest.h64
-rw-r--r--chromium/net/cookies/cookie_util.cc216
-rw-r--r--chromium/net/cookies/cookie_util.h40
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc785
-rw-r--r--chromium/net/cookies/parse_cookie_line_fuzzer.cc2
-rw-r--r--chromium/net/cookies/site_for_cookies.cc114
-rw-r--r--chromium/net/cookies/site_for_cookies.h74
-rw-r--r--chromium/net/cookies/site_for_cookies_unittest.cc260
-rw-r--r--chromium/net/cookies/static_cookie_policy.cc2
-rw-r--r--chromium/net/cookies/test_cookie_access_delegate.cc2
25 files changed, 2269 insertions, 1071 deletions
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index fb17243ed6a..e87937435d9 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -115,20 +115,99 @@ uint32_t GetWarningBitmask(
return 1u << static_cast<uint32_t>(reason);
}
+// Captures Strict -> Lax context downgrade with Strict cookie
+bool IsBreakingStrictToLaxDowngrade(
+ CookieOptions::SameSiteCookieContext::ContextType context,
+ CookieOptions::SameSiteCookieContext::ContextType schemeful_context,
+ CookieEffectiveSameSite effective_same_site,
+ bool is_cookie_being_set) {
+ if (context ==
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT &&
+ schemeful_context ==
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX &&
+ effective_same_site == CookieEffectiveSameSite::STRICT_MODE) {
+ // This downgrade only applies when a SameSite=Strict cookie is being sent.
+ // A Strict -> Lax downgrade will not affect a Strict cookie which is being
+ // set because it will be set in either context.
+ return !is_cookie_being_set;
+ }
+
+ return false;
+}
+
+// Captures Strict -> Cross-site context downgrade with {Strict, Lax} cookie
+// Captures Strict -> Lax Unsafe context downgrade with {Strict, Lax} cookie.
+// This is treated as a cross-site downgrade due to the Lax Unsafe context
+// behaving like cross-site.
+bool IsBreakingStrictToCrossDowngrade(
+ CookieOptions::SameSiteCookieContext::ContextType context,
+ CookieOptions::SameSiteCookieContext::ContextType schemeful_context,
+ CookieEffectiveSameSite effective_same_site) {
+ bool breaking_schemeful_context =
+ schemeful_context ==
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE ||
+ schemeful_context == CookieOptions::SameSiteCookieContext::ContextType::
+ SAME_SITE_LAX_METHOD_UNSAFE;
+
+ bool strict_lax_enforcement =
+ effective_same_site == CookieEffectiveSameSite::STRICT_MODE ||
+ effective_same_site == CookieEffectiveSameSite::LAX_MODE ||
+ // Treat LAX_MODE_ALLOW_UNSAFE the same as LAX_MODE for the purposes of
+ // our SameSite enforcement check.
+ effective_same_site == CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE;
+
+ if (context ==
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT &&
+ breaking_schemeful_context && strict_lax_enforcement) {
+ return true;
+ }
+
+ return false;
+}
+
+// Captures Lax -> Cross context downgrade with {Strict, Lax} cookies.
+// Ignores Lax Unsafe context.
+bool IsBreakingLaxToCrossDowngrade(
+ CookieOptions::SameSiteCookieContext::ContextType context,
+ CookieOptions::SameSiteCookieContext::ContextType schemeful_context,
+ CookieEffectiveSameSite effective_same_site,
+ bool is_cookie_being_set) {
+ bool lax_enforcement =
+ effective_same_site == CookieEffectiveSameSite::LAX_MODE ||
+ // Treat LAX_MODE_ALLOW_UNSAFE the same as LAX_MODE for the purposes of
+ // our SameSite enforcement check.
+ effective_same_site == CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE;
+
+ if (context ==
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX &&
+ schemeful_context ==
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE) {
+ // For SameSite=Strict cookies this downgrade only applies when it is being
+ // set. A Lax -> Cross downgrade will not affect a Strict cookie which is
+ // being sent because it wouldn't be sent in either context.
+ return effective_same_site == CookieEffectiveSameSite::STRICT_MODE
+ ? is_cookie_being_set
+ : lax_enforcement;
+ }
+
+ return false;
+}
+
void ApplySameSiteCookieWarningToStatus(
CookieSameSite samesite,
CookieEffectiveSameSite effective_samesite,
bool is_secure,
CookieOptions::SameSiteCookieContext same_site_context,
- CanonicalCookie::CookieInclusionStatus* status) {
+ CanonicalCookie::CookieInclusionStatus* status,
+ bool is_cookie_being_set) {
if (samesite == CookieSameSite::UNSPECIFIED &&
- same_site_context.context <
+ same_site_context.GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
}
if (effective_samesite == CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE &&
- same_site_context.context ==
+ same_site_context.GetContextForCookieInclusion() ==
CookieOptions::SameSiteCookieContext::ContextType::
SAME_SITE_LAX_METHOD_UNSAFE) {
// This warning is more specific so remove the previous, more general,
@@ -143,34 +222,49 @@ void ApplySameSiteCookieWarningToStatus(
status->AddWarningReason(
CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
}
+
+ // Add a warning if the cookie would be accessible in
+ // |same_site_context|::context but not in
+ // |same_site_context|::schemeful_context.
+ if (IsBreakingStrictToLaxDowngrade(same_site_context.context(),
+ same_site_context.schemeful_context(),
+ effective_samesite, is_cookie_being_set)) {
+ status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
+ } else if (IsBreakingStrictToCrossDowngrade(
+ same_site_context.context(),
+ same_site_context.schemeful_context(), effective_samesite)) {
+ // Which warning to apply depends on the SameSite value.
+ if (effective_samesite == CookieEffectiveSameSite::STRICT_MODE) {
+ status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ } else {
+ // LAX_MODE or LAX_MODE_ALLOW_UNSAFE.
+ status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
+ }
+
+ } else if (IsBreakingLaxToCrossDowngrade(
+ same_site_context.context(),
+ same_site_context.schemeful_context(), effective_samesite,
+ is_cookie_being_set)) {
+ // Which warning to apply depends on the SameSite value.
+ if (effective_samesite == CookieEffectiveSameSite::STRICT_MODE) {
+ status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ } else {
+ // LAX_MODE or LAX_MODE_ALLOW_UNSAFE.
+ // This warning applies to both set/send.
+ status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
+ }
+ }
+
// If there are reasons to exclude the cookie other than the new SameSite
// rules, don't warn about the cookie at all.
status->MaybeClearSameSiteWarning();
}
-// This function is used to indicate if the same-site context of a cookie should
-// recorded for the histograms SameSiteDifferentSchemeRequest and
-// SameSiteDifferentSchemeResponse. It returns true if the context is
-// cross-scheme but not cross-site and there is an effective same-site. It
-// should be removed when the histrograms are removed.
-// TODO(https://crbug.com/1066231)
-bool ShouldLogCrossSchemeForHistograms(
- const CookieOptions::SameSiteCookieContext& context,
- const CookieEffectiveSameSite effective_same_site) {
- bool correct_context =
- context.cross_schemeness !=
- CookieOptions::SameSiteCookieContext::CrossSchemeness::NONE &&
- context.context !=
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE;
-
- bool correct_effective_same_site =
- effective_same_site == CookieEffectiveSameSite::LAX_MODE ||
- effective_same_site == CookieEffectiveSameSite::STRICT_MODE ||
- effective_same_site == CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE;
-
- return correct_context && correct_effective_same_site;
-}
-
} // namespace
// Keep defaults here in sync with content/public/common/cookie_manager.mojom.
@@ -421,11 +515,32 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::CreateSanitizedCookie(
return cc;
}
+std::string CanonicalCookie::DomainWithoutDot() const {
+ return cookie_util::CookieDomainAsHost(domain_);
+}
+
bool CanonicalCookie::IsEquivalentForSecureCookieMatching(
- const CanonicalCookie& ecc) const {
- return (name_ == ecc.Name() && (ecc.IsDomainMatch(DomainWithoutDot()) ||
- IsDomainMatch(ecc.DomainWithoutDot())) &&
- ecc.IsOnPath(Path()));
+ const CanonicalCookie& secure_cookie) const {
+ // Names must be the same
+ bool same_name = name_ == secure_cookie.Name();
+
+ // They should domain-match in one direction or the other. (See RFC 6265bis
+ // section 5.1.3.)
+ // TODO(chlily): This does not check for the IP address case. This is bad due
+ // to https://crbug.com/1069935.
+ bool domain_match =
+ IsSubdomainOf(DomainWithoutDot(), secure_cookie.DomainWithoutDot()) ||
+ IsSubdomainOf(secure_cookie.DomainWithoutDot(), DomainWithoutDot());
+
+ bool path_match = secure_cookie.IsOnPath(Path());
+
+ bool equivalent_for_secure_cookie_matching =
+ same_name && domain_match && path_match;
+
+ // IsEquivalent() is a stricter check than this.
+ DCHECK(!IsEquivalent(secure_cookie) || equivalent_for_secure_cookie_matching);
+
+ return equivalent_for_secure_cookie_matching;
}
bool CanonicalCookie::IsOnPath(const std::string& url_path) const {
@@ -498,24 +613,24 @@ CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
}
UMA_HISTOGRAM_ENUMERATION(
"Cookie.RequestSameSiteContext",
- options.same_site_cookie_context().context,
+ options.same_site_cookie_context().GetContextForCookieInclusion(),
CookieOptions::SameSiteCookieContext::ContextType::COUNT);
switch (effective_same_site) {
case CookieEffectiveSameSite::STRICT_MODE:
- if (options.same_site_cookie_context().context <
+ if (options.same_site_cookie_context().GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT) {
status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT);
}
break;
case CookieEffectiveSameSite::LAX_MODE:
- if (options.same_site_cookie_context().context <
+ if (options.same_site_cookie_context().GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
// Log metrics for a cookie that would have been included under the
// "Lax-allow-unsafe" intervention, had it been new enough.
if (SameSite() == CookieSameSite::UNSPECIFIED &&
- options.same_site_cookie_context().context ==
+ options.same_site_cookie_context().GetContextForCookieInclusion() ==
CookieOptions::SameSiteCookieContext::ContextType::
SAME_SITE_LAX_METHOD_UNSAFE) {
UMA_HISTOGRAM_CUSTOM_TIMES(
@@ -533,13 +648,14 @@ CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
// TODO(crbug.com/990439): Add a browsertest for this behavior.
case CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE:
DCHECK(SameSite() == CookieSameSite::UNSPECIFIED);
- if (options.same_site_cookie_context().context <
+ if (options.same_site_cookie_context().GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::
SAME_SITE_LAX_METHOD_UNSAFE) {
// TODO(chlily): Do we need a separate CookieInclusionStatus for this?
status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
- } else if (options.same_site_cookie_context().context ==
+ } else if (options.same_site_cookie_context()
+ .GetContextForCookieInclusion() ==
CookieOptions::SameSiteCookieContext::ContextType::
SAME_SITE_LAX_METHOD_UNSAFE) {
// Log metrics for cookies that activate the "Lax-allow-unsafe"
@@ -567,25 +683,20 @@ CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
// TODO(chlily): Apply warning if SameSite-by-default is enabled but
// access_semantics is LEGACY?
- ApplySameSiteCookieWarningToStatus(
- SameSite(), effective_same_site, IsSecure(),
- options.same_site_cookie_context(), &status);
+ ApplySameSiteCookieWarningToStatus(SameSite(), effective_same_site,
+ IsSecure(),
+ options.same_site_cookie_context(),
+ &status, false /* is_cookie_being_set */);
if (status.IsInclude()) {
UMA_HISTOGRAM_ENUMERATION("Cookie.IncludedRequestEffectiveSameSite",
effective_same_site,
CookieEffectiveSameSite::COUNT);
+ }
- if (ShouldLogCrossSchemeForHistograms(options.same_site_cookie_context(),
- effective_same_site)) {
- // TODO(https://crbug.com/1066231)
- UMA_HISTOGRAM_ENUMERATION(
- "Cookie.SameSiteDifferentSchemeRequest",
- options.same_site_cookie_context().ConvertToMetricsValue(),
- CookieOptions::SameSiteCookieContext::MetricCount());
- AddSameSiteCrossSchemeWarning(&status,
- options.same_site_cookie_context());
- }
+ if (status.ShouldRecordDowngradeMetrics()) {
+ UMA_HISTOGRAM_ENUMERATION("Cookie.SameSiteContextDowngradeRequest",
+ status.GetBreakingDowngradeMetricsEnumValue(url));
}
// TODO(chlily): Log metrics.
@@ -633,7 +744,7 @@ void CanonicalCookie::IsSetPermittedInContext(
// This intentionally checks for `< SAME_SITE_LAX`, as we allow
// `SameSite=Strict` cookies to be set for top-level navigations that
// qualify for receipt of `SameSite=Lax` cookies.
- if (options.same_site_cookie_context().context <
+ if (options.same_site_cookie_context().GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "Trying to set a `SameSite=Strict` cookie from a "
@@ -644,7 +755,7 @@ void CanonicalCookie::IsSetPermittedInContext(
break;
case CookieEffectiveSameSite::LAX_MODE:
case CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE:
- if (options.same_site_cookie_context().context <
+ if (options.same_site_cookie_context().GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
if (SameSite() == CookieSameSite::UNSPECIFIED) {
DVLOG(net::cookie_util::kVlogSetCookies)
@@ -665,26 +776,15 @@ void CanonicalCookie::IsSetPermittedInContext(
break;
}
- ApplySameSiteCookieWarningToStatus(
- SameSite(), effective_same_site, IsSecure(),
- options.same_site_cookie_context(), status);
+ ApplySameSiteCookieWarningToStatus(SameSite(), effective_same_site,
+ IsSecure(),
+ options.same_site_cookie_context(), status,
+ true /* is_cookie_being_set */);
if (status->IsInclude()) {
UMA_HISTOGRAM_ENUMERATION("Cookie.IncludedResponseEffectiveSameSite",
effective_same_site,
CookieEffectiveSameSite::COUNT);
-
- if (ShouldLogCrossSchemeForHistograms(options.same_site_cookie_context(),
- effective_same_site)) {
- // TODO(crbug.com/1034014): Change enum to one with less confusing
- // phrasing.
- // TODO(https://crbug.com/1066231)
- UMA_HISTOGRAM_ENUMERATION(
- "Cookie.SameSiteDifferentSchemeResponse",
- options.same_site_cookie_context().ConvertToMetricsValue(),
- CookieOptions::SameSiteCookieContext::MetricCount());
- AddSameSiteCrossSchemeWarning(status, options.same_site_cookie_context());
- }
}
// TODO(chlily): Log metrics.
@@ -776,55 +876,6 @@ std::string CanonicalCookie::BuildCookieLine(
return cookie_line;
}
-void net::CanonicalCookie::AddSameSiteCrossSchemeWarning(
- CookieInclusionStatus* status,
- CookieOptions::SameSiteCookieContext same_site_context) const {
- if (same_site_context.cross_schemeness ==
- CookieOptions::SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE) {
- switch (same_site_context.context) {
- case CookieOptions::SameSiteCookieContext::ContextType::
- SAME_SITE_LAX_METHOD_UNSAFE:
- status->AddWarningReason(
- CookieInclusionStatus::
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_SECURE_URL);
- break;
- case CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX:
- status->AddWarningReason(
- CookieInclusionStatus::WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL);
- break;
- case CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT:
- status->AddWarningReason(
- CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL);
- break;
- default:
- break;
- }
- } else if (same_site_context.cross_schemeness ==
- CookieOptions::SameSiteCookieContext::CrossSchemeness::
- SECURE_INSECURE) {
- switch (same_site_context.context) {
- case CookieOptions::SameSiteCookieContext::ContextType::
- SAME_SITE_LAX_METHOD_UNSAFE:
- status->AddWarningReason(
- CookieInclusionStatus::
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_INSECURE_URL);
- break;
- case CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX:
- status->AddWarningReason(
- CookieInclusionStatus::WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL);
- break;
- case CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT:
- status->AddWarningReason(
- CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL);
- break;
- default:
- break;
- }
- }
-}
-
// static
CanonicalCookie::CookiePrefix CanonicalCookie::GetCookiePrefix(
const std::string& name) {
@@ -922,12 +973,6 @@ bool CanonicalCookie::IsRecentlyCreated(base::TimeDelta age_threshold) const {
return (base::Time::Now() - creation_date_) <= age_threshold;
}
-std::string CanonicalCookie::DomainWithoutDot() const {
- if (domain_.empty() || domain_[0] != '.')
- return domain_;
- return domain_.substr(1);
-}
-
CanonicalCookie::CookieInclusionStatus::CookieInclusionStatus()
: exclusion_reasons_(0u), warning_reasons_(0u) {}
@@ -986,6 +1031,33 @@ void CanonicalCookie::CookieInclusionStatus::MaybeClearSameSiteWarning() {
RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
}
+
+ uint32_t context_reasons_mask =
+ GetExclusionBitmask(EXCLUDE_SAMESITE_STRICT) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_LAX) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+ if (exclusion_reasons_ & ~context_reasons_mask) {
+ RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
+ RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
+ }
+}
+
+bool CanonicalCookie::CookieInclusionStatus::ShouldRecordDowngradeMetrics()
+ const {
+ uint32_t context_reasons_mask =
+ GetExclusionBitmask(EXCLUDE_SAMESITE_STRICT) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_LAX) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+
+ return (exclusion_reasons_ & ~context_reasons_mask) == 0u;
}
bool CanonicalCookie::CookieInclusionStatus::ShouldWarn() const {
@@ -997,24 +1069,27 @@ bool CanonicalCookie::CookieInclusionStatus::HasWarningReason(
return warning_reasons_ & GetWarningBitmask(reason);
}
-bool net::CanonicalCookie::CookieInclusionStatus::HasCrossSchemeWarning(
+bool net::CanonicalCookie::CookieInclusionStatus::HasDowngradeWarning(
CookieInclusionStatus::WarningReason* reason) const {
if (!ShouldWarn())
return false;
- const CookieInclusionStatus::WarningReason cross_scheme_warnings[] = {
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_SECURE_URL,
- WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL,
- WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL,
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_INSECURE_URL,
- WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL,
- WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL};
- for (const auto warning : cross_scheme_warnings) {
- if (HasWarningReason(warning)) {
- if (reason)
- *reason = warning;
- return true;
- }
+ const CookieInclusionStatus::WarningReason kDowngradeWarnings[] = {
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
+ };
+
+ for (auto warning : kDowngradeWarnings) {
+ if (!HasWarningReason(warning))
+ continue;
+
+ if (reason)
+ *reason = warning;
+
+ return true;
}
return false;
@@ -1030,6 +1105,46 @@ void CanonicalCookie::CookieInclusionStatus::RemoveWarningReason(
warning_reasons_ &= ~(GetWarningBitmask(reason));
}
+CanonicalCookie::CookieInclusionStatus::ContextDowngradeMetricValues
+CanonicalCookie::CookieInclusionStatus::GetBreakingDowngradeMetricsEnumValue(
+ const GURL& url) const {
+ bool url_is_secure = url.SchemeIsCryptographic();
+
+ // Start the |reason| as something other than the downgrade warnings.
+ WarningReason reason = WarningReason::NUM_WARNING_REASONS;
+
+ // Don't bother checking the return value because the default switch case
+ // will handle if no reason was found.
+ HasDowngradeWarning(&reason);
+
+ switch (reason) {
+ case WarningReason::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::STRICT_LAX_STRICT_SECURE
+ : ContextDowngradeMetricValues::STRICT_LAX_STRICT_INSECURE;
+ case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::STRICT_CROSS_STRICT_SECURE
+ : ContextDowngradeMetricValues::STRICT_CROSS_STRICT_INSECURE;
+ case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::STRICT_CROSS_LAX_SECURE
+ : ContextDowngradeMetricValues::STRICT_CROSS_LAX_INSECURE;
+ case WarningReason::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::LAX_CROSS_STRICT_SECURE
+ : ContextDowngradeMetricValues::LAX_CROSS_STRICT_INSECURE;
+ case WarningReason::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::LAX_CROSS_LAX_SECURE
+ : ContextDowngradeMetricValues::LAX_CROSS_LAX_INSECURE;
+ default:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::NO_DOWNGRADE_SECURE
+ : ContextDowngradeMetricValues::NO_DOWNGRADE_INSECURE;
+ }
+}
+
std::string CanonicalCookie::CookieInclusionStatus::GetDebugString() const {
std::string out;
@@ -1081,21 +1196,16 @@ std::string CanonicalCookie::CookieInclusionStatus::GetDebugString() const {
base::StrAppend(&out, {"WARN_SAMESITE_NONE_INSECURE, "});
if (HasWarningReason(WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE))
base::StrAppend(&out, {"WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE, "});
- if (HasWarningReason(WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_SECURE_URL))
- base::StrAppend(
- &out, {"WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_SECURE_URL, "});
- if (HasWarningReason(WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL))
- base::StrAppend(&out, {"WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL, "});
- if (HasWarningReason(WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL))
- base::StrAppend(&out, {"WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL, "});
- if (HasWarningReason(
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_INSECURE_URL))
- base::StrAppend(
- &out, {"WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_INSECURE_URL, "});
- if (HasWarningReason(WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL))
- base::StrAppend(&out, {"WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL, "});
- if (HasWarningReason(WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL))
- base::StrAppend(&out, {"WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL, "});
+ if (HasWarningReason(WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE))
+ base::StrAppend(&out, {"WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE, "});
+ if (HasWarningReason(WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE))
+ base::StrAppend(&out, {"WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE, "});
+ if (HasWarningReason(WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE))
+ base::StrAppend(&out, {"WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE, "});
+ if (HasWarningReason(WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE))
+ base::StrAppend(&out, {"WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE, "});
+ if (HasWarningReason(WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE))
+ base::StrAppend(&out, {"WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE, "});
// Strip trailing comma and space.
out.erase(out.end() - 2, out.end());
diff --git a/chromium/net/cookies/canonical_cookie.h b/chromium/net/cookies/canonical_cookie.h
index 8bd8b2eaccb..10b66c661b2 100644
--- a/chromium/net/cookies/canonical_cookie.h
+++ b/chromium/net/cookies/canonical_cookie.h
@@ -106,6 +106,10 @@ class NET_EXPORT CanonicalCookie {
const std::string& Name() const { return name_; }
const std::string& Value() const { return value_; }
+ // We represent the cookie's host-only-flag as the absence of a leading dot in
+ // Domain(). See IsDomainCookie() and IsHostCookie() below.
+ // If you want the "cookie's domain" as described in RFC 6265bis, use
+ // DomainWithoutDot().
const std::string& Domain() const { return domain_; }
const std::string& Path() const { return path_; }
const base::Time& CreationDate() const { return creation_date_; }
@@ -124,6 +128,10 @@ class NET_EXPORT CanonicalCookie {
return !domain_.empty() && domain_[0] == '.'; }
bool IsHostCookie() const { return !IsDomainCookie(); }
+ // Returns the cookie's domain, with the leading dot removed, if present.
+ // This corresponds to the "cookie's domain" as described in RFC 6265bis.
+ std::string DomainWithoutDot() const;
+
bool IsExpired(const base::Time& current) const {
return !expiry_date_.is_null() && current >= expiry_date_;
}
@@ -137,7 +145,7 @@ class NET_EXPORT CanonicalCookie {
bool IsEquivalent(const CanonicalCookie& ecc) const {
// It seems like it would make sense to take secure, httponly, and samesite
// into account, but the RFC doesn't specify this.
- // NOTE: Keep this logic in-sync with TrimDuplicateCookiesForHost().
+ // NOTE: Keep this logic in-sync with TrimDuplicateCookiesForKey().
return (name_ == ecc.Name() && domain_ == ecc.Domain()
&& path_ == ecc.Path());
}
@@ -149,18 +157,40 @@ class NET_EXPORT CanonicalCookie {
}
// Checks a looser set of equivalency rules than 'IsEquivalent()' in order
- // to support the stricter 'Secure' behaviors specified in
+ // to support the stricter 'Secure' behaviors specified in Step 12 of
+ // https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-05#section-5.4
+ // which originated from the proposal in
// https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone#section-3
//
- // Returns 'true' if this cookie's name matches |ecc|, and this cookie is
- // a domain-match for |ecc| (or vice versa), and |ecc|'s path is "on" this
- // cookie's path (as per 'IsOnPath()').
+ // Returns 'true' if this cookie's name matches |secure_cookie|, and this
+ // cookie is a domain-match for |secure_cookie| (or vice versa), and
+ // |secure_cookie|'s path is "on" this cookie's path (as per 'IsOnPath()').
//
// Note that while the domain-match cuts both ways (e.g. 'example.com'
// matches 'www.example.com' in either direction), the path-match is
// unidirectional (e.g. '/login/en' matches '/login' and '/', but
// '/login' and '/' do not match '/login/en').
- bool IsEquivalentForSecureCookieMatching(const CanonicalCookie& ecc) const;
+ //
+ // Conceptually:
+ // If new_cookie.IsEquivalentForSecureCookieMatching(secure_cookie) is true,
+ // this means that new_cookie would "shadow" secure_cookie: they would would
+ // be indistinguishable when serialized into a Cookie header. This is
+ // important because, if an attacker is attempting to set new_cookie, it
+ // should not be allowed to mislead the server into using new_cookie's value
+ // instead of secure_cookie's.
+ //
+ // The reason for the asymmetric path comparison ("cookie1=bad; path=/a/b"
+ // from an insecure source is not allowed if "cookie1=good; secure; path=/a"
+ // exists, but "cookie2=bad; path=/a" from an insecure source is allowed if
+ // "cookie2=good; secure; path=/a/b" exists) is because cookies in the Cookie
+ // header are serialized with longer path first. (See CookieSorter in
+ // cookie_monster.cc.) That is, they would be serialized as "Cookie:
+ // cookie1=bad; cookie1=good" in one case, and "Cookie: cookie2=good;
+ // cookie2=bad" in the other case. The first scenario is not allowed because
+ // the attacker injects the bad value, whereas the second scenario is ok
+ // because the good value is still listed first.
+ bool IsEquivalentForSecureCookieMatching(
+ const CanonicalCookie& secure_cookie) const;
void SetSourceScheme(CookieSourceScheme source_scheme) {
source_scheme_ = source_scheme;
@@ -170,12 +200,28 @@ class NET_EXPORT CanonicalCookie {
}
void SetCreationDate(const base::Time& date) { creation_date_ = date; }
- // Returns true if the given |url_path| path-matches the cookie-path as
- // described in section 5.1.4 in RFC 6265.
+ // Returns true if the given |url_path| path-matches this cookie's cookie-path
+ // as described in section 5.1.4 in RFC 6265. This returns true if |path_| and
+ // |url_path| are identical, or if |url_path| is a subdirectory of |path_|.
bool IsOnPath(const std::string& url_path) const;
- // Returns true if the cookie domain matches the given |host| as described in
- // section 5.1.3 of RFC 6265.
+ // This returns true if this cookie's |domain_| indicates that it can be
+ // accessed by |host|.
+ //
+ // In the case where |domain_| has no leading dot, this is a host cookie and
+ // will only domain match if |host| is identical to |domain_|.
+ //
+ // In the case where |domain_| has a leading dot, this is a domain cookie. It
+ // will match |host| if |domain_| is a suffix of |host|, or if |domain_| is
+ // exactly equal to |host| plus a leading dot.
+ //
+ // Note that this isn't quite the same as the "domain-match" algorithm in RFC
+ // 6265bis, since our implementation uses the presence of a leading dot in the
+ // |domain_| string in place of the spec's host-only-flag. That is, if
+ // |domain_| has no leading dot, then we only consider it matching if |host|
+ // is identical (which reflects the intended behavior when the cookie has a
+ // host-only-flag), whereas the RFC also treats them as domain-matching if
+ // |domain_| is a subdomain of |host|.
bool IsDomainMatch(const std::string& host) const;
// Returns if the cookie should be included (and if not, why) for the given
@@ -265,12 +311,6 @@ class NET_EXPORT CanonicalCookie {
COOKIE_PREFIX_LAST
};
- // Applies the appropriate warning for the given cross-scheme
- // SameSiteCookieContext.
- void AddSameSiteCrossSchemeWarning(
- CookieInclusionStatus* status,
- const CookieOptions::SameSiteCookieContext context) const;
-
// Returns the CookiePrefix (or COOKIE_PREFIX_NONE if none) that
// applies to the given cookie |name|.
static CookiePrefix GetCookiePrefix(const std::string& name);
@@ -304,9 +344,6 @@ class NET_EXPORT CanonicalCookie {
// Returns whether the cookie was created at most |age_threshold| ago.
bool IsRecentlyCreated(base::TimeDelta age_threshold) const;
- // Returns the cookie's domain, with the leading dot removed, if present.
- std::string DomainWithoutDot() const;
-
std::string name_;
std::string value_;
std::string domain_;
@@ -379,20 +416,82 @@ class NET_EXPORT CanonicalCookie::CookieInclusionStatus {
// enough to activate the Lax-allow-unsafe intervention.
WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE = 2,
- // The following warnings indicate that a SameSite cookie is being sent/set
- // across schemes and with what same-site context.
- // See CookieOptions::SameSiteCookieContext.
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_SECURE_URL = 3,
- WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL = 4,
- WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL = 5,
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_INSECURE_URL = 6,
- WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL = 7,
- WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL = 8,
+ // 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();
@@ -422,16 +521,23 @@ class NET_EXPORT CanonicalCookie::CookieInclusionStatus {
// 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 cross-scheme warning is present.
- // If the function returns true and |reason| is valid then |reason| will
- // contain which warning was found.
- bool HasCrossSchemeWarning(
+ // 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.
@@ -451,6 +557,9 @@ class NET_EXPORT CanonicalCookie::CookieInclusionStatus {
warning_reasons_ = warning_reasons;
}
+ ContextDowngradeMetricValues GetBreakingDowngradeMetricsEnumValue(
+ const GURL& url) const;
+
// Get exclusion reason(s) and warning in string format.
std::string GetDebugString() const;
diff --git a/chromium/net/cookies/canonical_cookie_unittest.cc b/chromium/net/cookies/canonical_cookie_unittest.cc
index 493af3f415b..68548deed97 100644
--- a/chromium/net/cookies/canonical_cookie_unittest.cc
+++ b/chromium/net/cookies/canonical_cookie_unittest.cc
@@ -396,6 +396,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
creation_time, expiration_time, base::Time(), secure, httponly, same_site,
COOKIE_PRIORITY_MEDIUM);
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
+ // The path comparison is asymmetric
EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -408,6 +409,56 @@ TEST(CanonicalCookieTest, IsEquivalent) {
EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
}
+TEST(CanonicalCookieTest, IsEquivalentForSecureCookieMatching) {
+ struct {
+ struct {
+ const char* name;
+ const char* domain;
+ const char* path;
+ } cookie, secure_cookie;
+ bool equivalent;
+ bool is_symmetric; // Whether the reverse comparison has the same result.
+ } kTests[] = {
+ // Equivalent to itself
+ {{"A", "a.foo.com", "/"}, {"A", "a.foo.com", "/"}, true, true},
+ {{"A", ".a.foo.com", "/"}, {"A", ".a.foo.com", "/"}, true, true},
+ // Names are different
+ {{"A", "a.foo.com", "/"}, {"B", "a.foo.com", "/"}, false, true},
+ // Host cookie and domain cookie with same hostname match
+ {{"A", "a.foo.com", "/"}, {"A", ".a.foo.com", "/"}, true, true},
+ // Subdomains and superdomains match
+ {{"A", "a.foo.com", "/"}, {"A", ".foo.com", "/"}, true, true},
+ {{"A", ".a.foo.com", "/"}, {"A", ".foo.com", "/"}, true, true},
+ {{"A", "a.foo.com", "/"}, {"A", "foo.com", "/"}, true, true},
+ {{"A", ".a.foo.com", "/"}, {"A", "foo.com", "/"}, true, true},
+ // Different domains don't match
+ {{"A", "a.foo.com", "/"}, {"A", "b.foo.com", "/"}, false, true},
+ {{"A", "a.foo.com", "/"}, {"A", "ba.foo.com", "/"}, false, true},
+ // Path attribute matches if it is a subdomain, but not vice versa.
+ {{"A", "a.foo.com", "/sub"}, {"A", "a.foo.com", "/"}, true, false},
+ // Different paths don't match
+ {{"A", "a.foo.com", "/sub"}, {"A", "a.foo.com", "/other"}, false, true},
+ {{"A", "a.foo.com", "/a/b"}, {"A", "a.foo.com", "/a/c"}, false, true},
+ };
+
+ for (auto test : kTests) {
+ auto cookie = std::make_unique<CanonicalCookie>(
+ test.cookie.name, "value1", test.cookie.domain, test.cookie.path,
+ base::Time(), base::Time(), base::Time(), false /* secure */, false,
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_MEDIUM);
+ auto secure_cookie = std::make_unique<CanonicalCookie>(
+ test.secure_cookie.name, "value2", test.secure_cookie.domain,
+ test.secure_cookie.path, base::Time(), base::Time(), base::Time(),
+ true /* secure */, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_MEDIUM);
+
+ EXPECT_EQ(test.equivalent,
+ cookie->IsEquivalentForSecureCookieMatching(*secure_cookie));
+ EXPECT_EQ(test.equivalent == test.is_symmetric,
+ secure_cookie->IsEquivalentForSecureCookieMatching(*cookie));
+ }
+}
+
TEST(CanonicalCookieTest, IsDomainMatch) {
GURL url("http://www.example.com/test/foo.html");
base::Time creation_time = base::Time::Now();
@@ -712,6 +763,8 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
// Test cases that are the same regardless of feature status or access
// semantics:
+ // TODO(https://crbug.com/1030938): This test will need to consider
+ // SchemefulSameSite when it is added to CanonicalCookie.
std::vector<IncludeForRequestURLTestCase> common_test_cases = {
// Strict cookies:
{"Common=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
@@ -735,129 +788,112 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
CanonicalCookie::CookieInclusionStatus()},
+ // Strict cookies with downgrade:
{"Common=5;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
std::vector<
CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
{CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL})},
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
{"Common=6;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<
+ CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
+ {CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
+ {"Common=7;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
std::vector<
CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
{CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL})},
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
// Lax cookies:
- {"Common=7;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
CanonicalCookie::CookieInclusionStatus(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
- {"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
CanonicalCookie::CookieInclusionStatus(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
- {"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=10;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
CanonicalCookie::CookieInclusionStatus()},
- {"Common=10;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=11;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
CanonicalCookie::CookieInclusionStatus()},
- {"Common=11;SameSite=Lax", CookieSameSite::LAX_MODE,
+ // Lax cookies with downgrade:
+ {"Common=12;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL})},
- {"Common=12;SameSite=Lax", CookieSameSite::LAX_MODE,
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ CanonicalCookie::CookieInclusionStatus()},
+ {"Common=13;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
std::vector<
CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
{CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL})},
- {"Common=13;SameSite=Lax", CookieSameSite::LAX_MODE,
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ {"Common=14;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
std::vector<
CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
{CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL})},
- {"Common=14;SameSite=Lax", CookieSameSite::LAX_MODE,
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ {"Common=15;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
std::vector<
CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
{CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL})},
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
// None and Secure cookies:
- {"Common=15;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ {"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
CanonicalCookie::CookieInclusionStatus()},
- {"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ {"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
CanonicalCookie::CookieInclusionStatus()},
- {"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
- CookieEffectiveSameSite::NO_RESTRICTION,
- SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus()},
{"Common=18;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
CanonicalCookie::CookieInclusionStatus()},
{"Common=19;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- CanonicalCookie::CookieInclusionStatus()},
- {"Common=20;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
- CookieEffectiveSameSite::NO_RESTRICTION,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- CanonicalCookie::CookieInclusionStatus()},
- {"Common=21;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
- CookieEffectiveSameSite::NO_RESTRICTION,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- CanonicalCookie::CookieInclusionStatus()},
- {"Common=22;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
- CookieEffectiveSameSite::NO_RESTRICTION,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
CanonicalCookie::CookieInclusionStatus()}};
// Test cases where the default is None (either access semantics is LEGACY, or
@@ -2008,30 +2044,24 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
context_same_site_strict.set_same_site_cookie_context(
CookieOptions::SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
- CookieOptions context_same_site_lax_to_secure;
- context_same_site_lax_to_secure.set_same_site_cookie_context(
+
+ CookieOptions context_same_site_strict_to_lax;
+ context_same_site_strict_to_lax.set_same_site_cookie_context(
CookieOptions::SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- CookieOptions::SameSiteCookieContext::CrossSchemeness::
- INSECURE_SECURE));
- CookieOptions context_same_site_strict_to_secure;
- context_same_site_strict_to_secure.set_same_site_cookie_context(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
+
+ CookieOptions context_same_site_strict_to_cross;
+ context_same_site_strict_to_cross.set_same_site_cookie_context(
CookieOptions::SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- CookieOptions::SameSiteCookieContext::CrossSchemeness::
- INSECURE_SECURE));
- CookieOptions context_same_site_lax_to_insecure;
- context_same_site_lax_to_insecure.set_same_site_cookie_context(
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
+
+ CookieOptions context_same_site_lax_to_cross;
+ context_same_site_lax_to_cross.set_same_site_cookie_context(
CookieOptions::SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- CookieOptions::SameSiteCookieContext::CrossSchemeness::
- SECURE_INSECURE));
- CookieOptions context_same_site_strict_to_insecure;
- context_same_site_strict_to_insecure.set_same_site_cookie_context(
- CookieOptions::SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- CookieOptions::SameSiteCookieContext::CrossSchemeness::
- SECURE_INSECURE));
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
{
CanonicalCookie cookie_same_site_unrestricted(
@@ -2048,19 +2078,22 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(cookie_same_site_unrestricted
.IsSetPermittedInContext(context_same_site_strict)
.IsInclude());
- EXPECT_TRUE(cookie_same_site_unrestricted
- .IsSetPermittedInContext(context_same_site_lax_to_secure)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unrestricted
- .IsSetPermittedInContext(context_same_site_strict_to_secure)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unrestricted
- .IsSetPermittedInContext(context_same_site_lax_to_insecure)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unrestricted
- .IsSetPermittedInContext(context_same_site_strict_to_insecure)
- .IsInclude());
+
+ CanonicalCookie::CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_unrestricted.IsSetPermittedInContext(
+ context_same_site_strict_to_lax);
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CanonicalCookie::CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_unrestricted.IsSetPermittedInContext(
+ context_same_site_strict_to_cross);
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_FALSE(status_strict_to_cross.HasDowngradeWarning());
+ CanonicalCookie::CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_unrestricted.IsSetPermittedInContext(
+ context_same_site_lax_to_cross);
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_FALSE(status_lax_to_cross.HasDowngradeWarning());
}
{
@@ -2079,19 +2112,26 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(
cookie_same_site_lax.IsSetPermittedInContext(context_same_site_strict)
.IsInclude());
- EXPECT_TRUE(cookie_same_site_lax
- .IsSetPermittedInContext(context_same_site_lax_to_secure)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_lax
- .IsSetPermittedInContext(context_same_site_strict_to_secure)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_lax
- .IsSetPermittedInContext(context_same_site_lax_to_insecure)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_lax
- .IsSetPermittedInContext(context_same_site_strict_to_insecure)
- .IsInclude());
+
+ CanonicalCookie::CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_lax.IsSetPermittedInContext(
+ context_same_site_strict_to_lax);
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CanonicalCookie::CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_lax.IsSetPermittedInContext(
+ context_same_site_strict_to_cross);
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
+ CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE));
+ CanonicalCookie::CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_lax.IsSetPermittedInContext(
+ context_same_site_lax_to_cross);
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
+ CanonicalCookie::CookieInclusionStatus::
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE));
}
{
@@ -2113,19 +2153,26 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(cookie_same_site_strict
.IsSetPermittedInContext(context_same_site_strict)
.IsInclude());
- EXPECT_TRUE(cookie_same_site_strict
- .IsSetPermittedInContext(context_same_site_lax_to_secure)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_strict
- .IsSetPermittedInContext(context_same_site_strict_to_secure)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_strict
- .IsSetPermittedInContext(context_same_site_lax_to_insecure)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_strict
- .IsSetPermittedInContext(context_same_site_strict_to_insecure)
- .IsInclude());
+
+ CanonicalCookie::CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_strict.IsSetPermittedInContext(
+ context_same_site_strict_to_lax);
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CanonicalCookie::CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_strict.IsSetPermittedInContext(
+ context_same_site_strict_to_cross);
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
+ CanonicalCookie::CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ CanonicalCookie::CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_strict.IsSetPermittedInContext(
+ context_same_site_lax_to_cross);
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
+ CanonicalCookie::CookieInclusionStatus::
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE));
}
// Behavior of UNSPECIFIED depends on an experiment and CookieAccessSemantics.
@@ -2151,23 +2198,6 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CookieAccessSemantics::UNKNOWN)
.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_secure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_secure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_insecure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_insecure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::LEGACY)
.IsInclude());
@@ -2180,23 +2210,6 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CookieAccessSemantics::LEGACY)
.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_secure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_secure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_insecure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_insecure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::NONLEGACY)
.HasExactlyExclusionReasonsForTesting(
@@ -2210,23 +2223,6 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::NONLEGACY)
.IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_secure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_secure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_insecure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_insecure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
}
{
@@ -2248,23 +2244,6 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CookieAccessSemantics::UNKNOWN)
.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_secure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_secure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_insecure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_insecure,
- CookieAccessSemantics::UNKNOWN)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::LEGACY)
.IsInclude());
@@ -2277,23 +2256,6 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CookieAccessSemantics::LEGACY)
.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_secure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_secure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_insecure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_insecure,
- CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::NONLEGACY)
.HasExactlyExclusionReasonsForTesting(
@@ -2307,23 +2269,6 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::NONLEGACY)
.IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_secure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_secure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_lax_to_insecure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
- EXPECT_TRUE(
- cookie_same_site_unspecified
- .IsSetPermittedInContext(context_same_site_strict_to_insecure,
- CookieAccessSemantics::NONLEGACY)
- .IsInclude());
}
}
@@ -2503,39 +2448,37 @@ TEST(CookieInclusionStatusTest, RemoveWarningReason) {
WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
}
-TEST(CookieInclusionStatusTest, HasCrossSchemeWarning) {
+TEST(CookieInclusionStatusTest, HasDowngradeWarning) {
std::vector<CanonicalCookie::CookieInclusionStatus::WarningReason>
- cross_scheme_warnings = {
+ downgrade_warnings = {
CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_SECURE_URL,
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_LAX_CROSS_SCHEME_SECURE_URL,
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_SECURE_URL,
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_LAX_METHOD_UNSAFE_CROSS_SCHEME_INSECURE_URL,
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_LAX_CROSS_SCHEME_INSECURE_URL,
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_STRICT_CROSS_SCHEME_INSECURE_URL};
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
+ };
CanonicalCookie::CookieInclusionStatus empty_status;
- EXPECT_FALSE(empty_status.HasCrossSchemeWarning());
+ EXPECT_FALSE(empty_status.HasDowngradeWarning());
- CanonicalCookie::CookieInclusionStatus not_cross_scheme;
- not_cross_scheme.AddWarningReason(
+ CanonicalCookie::CookieInclusionStatus not_downgrade;
+ not_downgrade.AddWarningReason(
CanonicalCookie::CookieInclusionStatus::
WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
- EXPECT_FALSE(not_cross_scheme.HasCrossSchemeWarning());
+ EXPECT_FALSE(not_downgrade.HasDowngradeWarning());
- for (auto warning : cross_scheme_warnings) {
+ for (auto warning : downgrade_warnings) {
CanonicalCookie::CookieInclusionStatus status;
status.AddWarningReason(warning);
CanonicalCookie::CookieInclusionStatus::WarningReason reason;
- EXPECT_TRUE(status.HasCrossSchemeWarning(&reason));
+ EXPECT_TRUE(status.HasDowngradeWarning(&reason));
EXPECT_EQ(warning, reason);
}
}
-
} // namespace net
diff --git a/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc b/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc
index 0db6daaa5e8..3419e6653fe 100644
--- a/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc
+++ b/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc
@@ -4,7 +4,7 @@
#include "net/cookies/cookie_change_dispatcher_test_helpers.h"
-#include "base/logging.h"
+#include "base/notreached.h"
namespace net {
diff --git a/chromium/net/cookies/cookie_constants.cc b/chromium/net/cookies/cookie_constants.cc
index 95adeef96e9..bf8dd08c555 100644
--- a/chromium/net/cookies/cookie_constants.cc
+++ b/chromium/net/cookies/cookie_constants.cc
@@ -4,8 +4,8 @@
#include "net/cookies/cookie_constants.h"
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/notreached.h"
#include "base/strings/string_util.h"
namespace net {
diff --git a/chromium/net/cookies/cookie_deletion_info.cc b/chromium/net/cookies/cookie_deletion_info.cc
index 73a11949b2b..b451dc2350f 100644
--- a/chromium/net/cookies/cookie_deletion_info.cc
+++ b/chromium/net/cookies/cookie_deletion_info.cc
@@ -28,12 +28,8 @@ bool DomainMatchesDomains(const net::CanonicalCookie& cookie,
// If the cookie's domain is is not parsed as belonging to a registry
// (e.g. for IP addresses or internal hostnames) an empty string will be
// returned. In this case, use the domain in the cookie.
- if (effective_domain.empty()) {
- if (cookie.IsDomainCookie())
- effective_domain = cookie.Domain().substr(1);
- else
- effective_domain = cookie.Domain();
- }
+ if (effective_domain.empty())
+ effective_domain = cookie.DomainWithoutDot();
return match_domains.count(effective_domain) != 0;
}
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index 783485c013d..533cc97ba71 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -303,7 +303,8 @@ bool IsHttpSameSiteContextAtLeast(
const CookieOptions& options,
CookieOptions::SameSiteCookieContext::ContextType same_site_requirement) {
return !options.exclude_httponly() &&
- options.same_site_cookie_context().context >= same_site_requirement;
+ options.same_site_cookie_context().GetContextForCookieInclusion() >=
+ same_site_requirement;
}
} // namespace
@@ -368,7 +369,7 @@ void CookieMonster::SetAllCookiesAsync(const CookieList& list,
void CookieMonster::SetCanonicalCookieAsync(
std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback) {
DCHECK(cookie->IsCanonical());
@@ -380,8 +381,7 @@ void CookieMonster::SetCanonicalCookieAsync(
// the callback on |*this|, so the callback will not outlive
// the object.
&CookieMonster::SetCanonicalCookie, base::Unretained(this),
- std::move(cookie), std::move(source_scheme), options,
- std::move(callback)),
+ std::move(cookie), source_url, options, std::move(callback)),
domain);
}
@@ -904,7 +904,7 @@ void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key,
dupes.erase(dupes.begin());
LOG(ERROR) << base::StringPrintf(
- "Found %d duplicate cookies for host='%s', "
+ "Found %d duplicate cookies for key='%s', "
"with {name='%s', domain='%s', path='%s'}",
static_cast<int>(dupes.size()), key.c_str(),
std::get<0>(signature).c_str(), std::get<1>(signature).c_str(),
@@ -998,68 +998,72 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY));
bool found_equivalent_cookie = false;
- CookieMap::iterator maybe_delete_it = cookies_.end();
- CanonicalCookie* cc_skipped_secure = nullptr;
+ CookieMap::iterator deletion_candidate_it = cookies_.end();
+ CanonicalCookie* skipped_secure_cookie = nullptr;
// Check every cookie matching this domain key for equivalence.
CookieMapItPair range_its = cookies_.equal_range(key);
for (auto cur_it = range_its.first; cur_it != range_its.second; ++cur_it) {
- CanonicalCookie* cc = cur_it->second.get();
+ CanonicalCookie* cur_existing_cookie = cur_it->second.get();
// Evaluate "Leave Secure Cookies Alone":
- // If the cookie is being set from an insecure scheme, then if a cookie
- // already exists with the same name and it is Secure, then the cookie
- // should *not* be updated if they domain-match and ignoring the path
- // attribute. This notion of equivalence is slightly more inclusive than the
- // usual IsEquivalent() check.
+ // If the cookie is being set from an insecure source, then if an
+ // "equivalent" Secure cookie already exists, then the cookie should *not*
+ // be updated.
+ //
+ // "Equivalent" means they are the same by
+ // IsEquivalentForSecureCookieMatching(). See the comment there for
+ // details. (Note this is not a symmetric comparison.) This notion of
+ // equivalence is slightly more inclusive than the usual IsEquivalent() one.
//
// See: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone
- if (cc->IsSecure() && !source_secure &&
- cookie_being_set.IsEquivalentForSecureCookieMatching(*cc)) {
+ if (cur_existing_cookie->IsSecure() && !source_secure &&
+ cookie_being_set.IsEquivalentForSecureCookieMatching(
+ *cur_existing_cookie)) {
// Hold onto this for additional Netlogging later if we end up preserving
// a would-have-been-deleted cookie because of this.
- cc_skipped_secure = cc;
+ skipped_secure_cookie = cur_existing_cookie;
net_log_.AddEvent(NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_SECURE,
[&](NetLogCaptureMode capture_mode) {
return NetLogCookieMonsterCookieRejectedSecure(
- cc_skipped_secure, &cookie_being_set,
+ skipped_secure_cookie, &cookie_being_set,
capture_mode);
});
status->AddExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE);
}
- if (cookie_being_set.IsEquivalent(*cc)) {
+ if (cookie_being_set.IsEquivalent(*cur_existing_cookie)) {
// We should never have more than one equivalent cookie, since they should
// overwrite each other.
CHECK(!found_equivalent_cookie)
<< "Duplicate equivalent cookies found, cookie store is corrupted.";
- DCHECK(maybe_delete_it == cookies_.end());
+ DCHECK(deletion_candidate_it == cookies_.end());
found_equivalent_cookie = true;
// The |cookie_being_set| is rejected for trying to overwrite an httponly
// cookie when it should not be able to.
- if (skip_httponly && cc->IsHttpOnly()) {
+ if (skip_httponly && cur_existing_cookie->IsHttpOnly()) {
net_log_.AddEvent(
NetLogEventType::COOKIE_STORE_COOKIE_REJECTED_HTTPONLY,
[&](NetLogCaptureMode capture_mode) {
return NetLogCookieMonsterCookieRejectedHttponly(
- cc, &cookie_being_set, capture_mode);
+ cur_existing_cookie, &cookie_being_set, capture_mode);
});
status->AddExclusionReason(CanonicalCookie::CookieInclusionStatus::
EXCLUDE_OVERWRITE_HTTP_ONLY);
} else {
- maybe_delete_it = cur_it;
+ deletion_candidate_it = cur_it;
}
}
}
- if (maybe_delete_it != cookies_.end()) {
- CanonicalCookie* maybe_delete_cc = maybe_delete_it->second.get();
- if (maybe_delete_cc->Value() == cookie_being_set.Value())
- *creation_date_to_inherit = maybe_delete_cc->CreationDate();
+ if (deletion_candidate_it != cookies_.end()) {
+ CanonicalCookie* deletion_candidate = deletion_candidate_it->second.get();
+ if (deletion_candidate->Value() == cookie_being_set.Value())
+ *creation_date_to_inherit = deletion_candidate->CreationDate();
if (status->IsInclude()) {
- InternalDeleteCookie(maybe_delete_it, true,
+ InternalDeleteCookie(deletion_candidate_it, true /* sync_to_store */,
already_expired ? DELETE_COOKIE_EXPIRED_OVERWRITE
: DELETE_COOKIE_OVERWRITE);
} else if (status->HasExclusionReason(
@@ -1067,14 +1071,14 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
EXCLUDE_OVERWRITE_SECURE)) {
// Log that we preserved a cookie that would have been deleted due to
// Leave Secure Cookies Alone. This arbitrarily only logs the last
- // |cc_skipped_secure| that we were left with after the for loop, even if
- // there were multiple matching Secure cookies that were left alone.
- DCHECK(cc_skipped_secure);
+ // |skipped_secure_cookie| that we were left with after the for loop, even
+ // if there were multiple matching Secure cookies that were left alone.
+ DCHECK(skipped_secure_cookie);
net_log_.AddEvent(
NetLogEventType::COOKIE_STORE_COOKIE_PRESERVED_SKIPPED_SECURE,
[&](NetLogCaptureMode capture_mode) {
return NetLogCookieMonsterCookiePreservedSkippedSecure(
- cc_skipped_secure, maybe_delete_cc, &cookie_being_set,
+ skipped_secure_cookie, deletion_candidate, &cookie_being_set,
capture_mode);
});
}
@@ -1145,15 +1149,14 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
}
void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
CanonicalCookie::CookieInclusionStatus status;
- std::string scheme_lower = base::ToLowerASCII(source_scheme);
- bool secure_source = GURL::SchemeIsCryptographic(scheme_lower);
+ bool secure_source = source_url.SchemeIsCryptographic();
cc->SetSourceScheme(secure_source ? CookieSourceScheme::kSecure
: CookieSourceScheme::kNonSecure);
if ((cc->IsSecure() && !secure_source)) {
@@ -1161,7 +1164,7 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY);
}
- if (!IsCookieableScheme(scheme_lower)) {
+ if (!IsCookieableScheme(source_url.scheme())) {
status.AddExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME);
}
@@ -1199,6 +1202,15 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
"insecure scheme";
}
+ // Now that IsSetPermittedInContext() and
+ // MaybeDeleteEquivalentCookieAndUpdateStatus() have had a chance to set
+ // cookie warnings/exclusions, record the downgrade metric.
+ if (status.ShouldRecordDowngradeMetrics()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.SameSiteContextDowngradeResponse",
+ status.GetBreakingDowngradeMetricsEnumValue(source_url));
+ }
+
if (status.IsInclude()) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() key: " << key << " cc: " << cc->DebugString();
@@ -1658,9 +1670,7 @@ std::string CookieMonster::GetKey(base::StringPiece domain) {
if (effective_domain.empty())
effective_domain = std::string(domain);
- if (!effective_domain.empty() && effective_domain[0] == '.')
- return effective_domain.substr(1);
- return effective_domain;
+ return cookie_util::CookieDomainAsHost(effective_domain);
}
bool CookieMonster::HasCookieableScheme(const GURL& url) {
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index 431fab884a5..46001bd4e4e 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -158,7 +158,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
// CookieStore implementation.
void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback) override;
void GetCookieListWithOptionsAsync(const GURL& url,
@@ -306,14 +306,14 @@ class NET_EXPORT CookieMonster : public CookieStore {
static const int kRecordStatisticsIntervalSeconds = 10 * 60;
// Sets a canonical cookie, deletes equivalents and performs garbage
- // collection. |source_scheme| indicates what scheme the cookie is being set
+ // collection. |source_url| indicates what URL the cookie is being set
// from; secure cookies cannot be altered from insecure schemes, and some
// schemes may not be authorized.
//
// |options| indicates if this setting operation is allowed
// to affect http_only or same-site cookies.
void SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback);
diff --git a/chromium/net/cookies/cookie_monster_perftest.cc b/chromium/net/cookies/cookie_monster_perftest.cc
index 8ac5ec1ffd0..6966a8a9e4b 100644
--- a/chromium/net/cookies/cookie_monster_perftest.cc
+++ b/chromium/net/cookies/cookie_monster_perftest.cc
@@ -99,7 +99,7 @@ class SetCookieCallback : public CookieTestCallback {
auto cookie = CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(),
base::nullopt /* server_time */);
cm->SetCanonicalCookieAsync(
- std::move(cookie), gurl.scheme(), options_,
+ std::move(cookie), gurl, options_,
base::BindOnce(&SetCookieCallback::Run, base::Unretained(this)));
WaitForCallback();
}
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index 477961d177e..82877bcb54b 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -51,6 +51,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+#include "url/url_constants.h"
namespace net {
@@ -163,8 +164,7 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
cm->SetCanonicalCookieAsync(
CanonicalCookie::Create(url, cookie_line, creation_time,
base::nullopt /* server_time */),
- url.scheme(), CookieOptions::MakeAllInclusive(),
- callback.MakeCallback());
+ url, CookieOptions::MakeAllInclusive(), callback.MakeCallback());
callback.WaitUntilDone();
return callback.result().IsInclude();
}
@@ -208,119 +208,84 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
// * Two domain path cookies (.c.b.a/dir1, .c.b.a/dir1/dir2)
// * Two host path cookies (w.c.b.a/dir1, w.c.b.a/dir1/dir2)
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies;
+
// Domain cookies
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "dom_1", "A", ".harvard.edu", "/", base::Time(), base::Time(),
- base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "dom_2", "B", ".math.harvard.edu", "/", base::Time(), base::Time(),
- base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "dom_3", "C", ".bourbaki.math.harvard.edu", "/", base::Time(),
- base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "dom_1", "A", ".harvard.edu", "/", base::Time(), base::Time(),
+ base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "dom_2", "B", ".math.harvard.edu", "/", base::Time(), base::Time(),
+ base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "dom_3", "C", ".bourbaki.math.harvard.edu", "/", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
// Host cookies
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "host_1", "A", url_top_level_domain_plus_1, "/", base::Time(),
- base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "host_2", "B", url_top_level_domain_plus_2, "/", base::Time(),
- base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "host_3", "C", url_top_level_domain_plus_3, "/", base::Time(),
- base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "host_1", "A", url_top_level_domain_plus_1, "/", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "host_2", "B", url_top_level_domain_plus_2, "/", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "host_3", "C", url_top_level_domain_plus_3, "/", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
// http_only cookie
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "httpo_check", "A", url_top_level_domain_plus_2, "/", base::Time(),
- base::Time(), base::Time(), false, true, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "httpo_check", "A", url_top_level_domain_plus_2, "/", base::Time(),
+ base::Time(), base::Time(), false, true, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
// same-site cookie
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "firstp_check", "A", url_top_level_domain_plus_2, "/", base::Time(),
- base::Time(), base::Time(), false, false,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "firstp_check", "A", url_top_level_domain_plus_2, "/", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::STRICT_MODE,
+ COOKIE_PRIORITY_DEFAULT));
// Secure cookies
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "sec_dom", "A", ".math.harvard.edu", "/", base::Time(),
- base::Time(), base::Time(), true, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
- "https", true /*modify_httponly*/));
-
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "sec_host", "B", url_top_level_domain_plus_2, "/", base::Time(),
- base::Time(), base::Time(), true, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
- "https", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "sec_dom", "A", ".math.harvard.edu", "/", base::Time(), base::Time(),
+ base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "sec_host", "B", url_top_level_domain_plus_2, "/", base::Time(),
+ base::Time(), base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_DEFAULT));
// Domain path cookies
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "dom_path_1", "A", ".math.harvard.edu", "/dir1", base::Time(),
- base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "dom_path_2", "B", ".math.harvard.edu", "/dir1/dir2", base::Time(),
- base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "dom_path_1", "A", ".math.harvard.edu", "/dir1", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "dom_path_2", "B", ".math.harvard.edu", "/dir1/dir2", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
// Host path cookies
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "host_path_1", "A", url_top_level_domain_plus_2, "/dir1",
- base::Time(), base::Time(), base::Time(), false, false,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
-
- EXPECT_TRUE(this->SetCanonicalCookie(
- cm,
- std::make_unique<CanonicalCookie>(
- "host_path_2", "B", url_top_level_domain_plus_2, "/dir1/dir2",
- base::Time(), base::Time(), base::Time(), false, false,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "host_path_1", "A", url_top_level_domain_plus_2, "/dir1", base::Time(),
+ base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT));
+ cookies.push_back(std::make_unique<CanonicalCookie>(
+ "host_path_2", "B", url_top_level_domain_plus_2, "/dir1/dir2",
+ base::Time(), base::Time(), base::Time(), false, false,
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT));
+
+ for (auto& cookie : cookies) {
+ GURL source_url = cookie_util::SimulatedCookieSource(
+ *cookie, cookie->IsSecure() ? "https" : "http");
+ EXPECT_TRUE(this->SetCanonicalCookie(cm, std::move(cookie), source_url,
+ true /* modify_httponly */));
+ }
EXPECT_EQ(14U, this->GetAllCookies(cm).size());
}
@@ -825,7 +790,8 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
creation_time /* last_access */, true /* secure */,
false /* http_only */, CookieSameSite::NO_RESTRICTION,
COOKIE_PRIORITY_DEFAULT));
- cm->SetCanonicalCookieAsync(std::move(cc), "https",
+ GURL source_url = cookie_util::SimulatedCookieSource(*cc, "https");
+ cm->SetCanonicalCookieAsync(std::move(cc), source_url,
CookieOptions::MakeAllInclusive(),
CookieStore::SetCookiesCallback());
}
@@ -970,7 +936,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
base::nullopt /* server_time */),
- http_www_foo_.url().scheme(), CookieOptions::MakeAllInclusive(),
+ http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
call1.MakeCallback());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(call1.was_run());
@@ -984,7 +950,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "X=Y", base::Time::Now(),
base::nullopt /* server_time */),
- http_www_foo_.url().scheme(), CookieOptions::MakeAllInclusive(),
+ http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
call2.MakeCallback());
ASSERT_TRUE(call2.was_run());
EXPECT_TRUE(call2.result().IsInclude());
@@ -1245,7 +1211,7 @@ TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
base::nullopt /* server_time */),
- http_www_foo_.url().scheme(), CookieOptions::MakeAllInclusive(),
+ http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
set_cookies_callback.MakeCallback());
// Nothing happened yet, before loads are done.
@@ -1475,7 +1441,7 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
EXPECT_TRUE(SetCanonicalCookieReturnStatus(
cm.get(),
CanonicalCookie::Create(http_url, "y=1", now, server_time),
- "http", false /*modify_httponly*/)
+ http_url, false /*modify_httponly*/)
.IsInclude());
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), foo_url, "x=1")
@@ -1485,7 +1451,7 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
EXPECT_TRUE(SetCanonicalCookieReturnStatus(
cm.get(),
CanonicalCookie::Create(foo_url, "y=1", now, server_time),
- "foo", false /*modify_httponly*/)
+ foo_url, false /*modify_httponly*/)
.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::
EXCLUDE_NONCOOKIEABLE_SCHEME}));
@@ -1495,7 +1461,7 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
EXPECT_TRUE(SetCanonicalCookieReturnStatus(
cm_foo.get(),
CanonicalCookie::Create(foo_url, "y=1", now, server_time),
- "foo", false /*modify_httponly*/)
+ foo_url, false /*modify_httponly*/)
.IsInclude());
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm_foo.get(), http_url, "x=1")
@@ -1505,7 +1471,7 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
EXPECT_TRUE(SetCanonicalCookieReturnStatus(
cm_foo.get(),
CanonicalCookie::Create(http_url, "y=1", now, server_time),
- "http", false /*modify_httponly*/)
+ http_url, false /*modify_httponly*/)
.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::
EXCLUDE_NONCOOKIEABLE_SCHEME}));
@@ -2005,7 +1971,7 @@ TEST_F(CookieMonsterTest, BackingStoreCommunication) {
cookie.name, cookie.value, cookie.domain, cookie.path,
base::Time(), cookie.expiration_time, base::Time(), cookie.secure,
cookie.http_only, cookie.same_site, cookie.priority),
- cookie.url.scheme(), true /*modify_httponly*/));
+ cookie.url, true /*modify_httponly*/));
}
EXPECT_TRUE(FindAndDeleteCookie(cmout.get(),
@@ -2225,7 +2191,7 @@ TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
base::nullopt /* server_time */);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
set_cookie_callback;
- cm->SetCanonicalCookieAsync(std::move(cookie), kUrl.scheme(),
+ cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback());
@@ -2314,7 +2280,7 @@ TEST_F(CookieMonsterTest, WhileLoadingGetAllSetGetAll) {
base::nullopt /* server_time */);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
set_cookie_callback;
- cm->SetCanonicalCookieAsync(std::move(cookie), kUrl.scheme(),
+ cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback());
@@ -2365,8 +2331,8 @@ TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
cm->GetAllCookiesAsync(base::BindOnce(
&RunClosureOnAllCookiesReceived,
base::BindOnce(&CookieStore::SetCanonicalCookieAsync,
- base::Unretained(cm.get()), std::move(cookie),
- kUrl.scheme(), CookieOptions::MakeAllInclusive(),
+ base::Unretained(cm.get()), std::move(cookie), kUrl,
+ CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback())));
// Get cookie task. Queued before the delete task is executed, so should not
@@ -2548,13 +2514,13 @@ TEST_F(CookieMonsterTest, HistogramCheck) {
std::unique_ptr<base::HistogramSamples> samples1(
expired_histogram->SnapshotSamples());
- ASSERT_TRUE(SetCanonicalCookie(
- cm.get(),
- std::make_unique<CanonicalCookie>(
- "a", "b", "a.url", "/", base::Time(),
- base::Time::Now() + base::TimeDelta::FromMinutes(59), base::Time(),
- true, false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
- "https", true /*modify_httponly*/));
+ auto cookie = std::make_unique<CanonicalCookie>(
+ "a", "b", "a.url", "/", base::Time(),
+ base::Time::Now() + base::TimeDelta::FromMinutes(59), base::Time(), true,
+ false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
+ ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
+ true /*modify_httponly*/));
std::unique_ptr<base::HistogramSamples> samples2(
expired_histogram->SnapshotSamples());
@@ -2764,7 +2730,8 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
base::nullopt /* server_time */);
CanonicalCookie::CookieInclusionStatus status =
SetCanonicalCookieReturnStatus(cm.get(), std::move(preexisting_cookie),
- "https", true /* can_modify_httponly */);
+ https_www_foo_.url(),
+ true /* can_modify_httponly */);
ASSERT_TRUE(status.IsInclude());
// Set a new cookie with a different name. Should work because cookies with
@@ -2782,8 +2749,9 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
base::nullopt /* server_time */);
// Allow modifying HttpOnly, so that we don't skip preexisting cookies for
// being HttpOnly.
- status = SetCanonicalCookieReturnStatus(
- cm.get(), std::move(bad_cookie), "http", true /* can_modify_httponly */);
+ status = SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
+ http_www_foo_.url(),
+ true /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// The preexisting cookie should still be there.
@@ -2812,8 +2780,9 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
base::nullopt /* server_time */);
// Allow modifying HttpOnly, so that we don't skip preexisting cookies for
// being HttpOnly.
- status = SetCanonicalCookieReturnStatus(
- cm.get(), std::move(bad_cookie), "http", true /* can_modify_httponly */);
+ status = SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
+ http_www_foo_.url(),
+ true /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// The preexisting cookie should still be there.
@@ -2839,9 +2808,9 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
bad_cookie = CanonicalCookie::Create(https_www_foo_.url(), "A=E; Secure",
base::Time::Now(),
base::nullopt /* server_time */);
- status =
- SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie), "https",
- false /* can_modify_httponly */);
+ status = SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
+ https_www_foo_.url(),
+ false /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
@@ -2865,7 +2834,8 @@ TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) {
base::nullopt /* server_time */);
CanonicalCookie::CookieInclusionStatus status =
SetCanonicalCookieReturnStatus(cm.get(), std::move(preexisting_cookie),
- "https", true /* can_modify_httponly */);
+ https_www_foo_.url(),
+ true /* can_modify_httponly */);
ASSERT_TRUE(status.IsInclude());
// Attempt to set a new cookie with the same name that is not Secure or
@@ -2873,7 +2843,8 @@ TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) {
auto cookie =
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
base::nullopt /* server_time */);
- status = SetCanonicalCookieReturnStatus(cm.get(), std::move(cookie), "http",
+ status = SetCanonicalCookieReturnStatus(cm.get(), std::move(cookie),
+ http_www_foo_.url(),
false /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE,
@@ -2899,14 +2870,16 @@ TEST_F(CookieMonsterTest, DontDeleteEquivalentCookieIfSetIsRejected) {
base::nullopt /* server_time */);
CanonicalCookie::CookieInclusionStatus status =
SetCanonicalCookieReturnStatus(cm.get(), std::move(preexisting_cookie),
- "https", false /* can_modify_httponly */);
+ http_www_foo_.url(),
+ false /* can_modify_httponly */);
ASSERT_TRUE(status.IsInclude());
auto bad_cookie = CanonicalCookie::Create(
http_www_foo_.url(), "cookie=bar;secure", base::Time::Now(),
base::nullopt /* server_time */);
CanonicalCookie::CookieInclusionStatus status2 =
- SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie), "http",
+ SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
+ http_www_foo_.url(),
false /* can_modify_httponly */);
EXPECT_TRUE(status2.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
@@ -2930,13 +2903,13 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B;").IsInclude());
- // A secure cookie cannot be created from a URL with an insecure scheme.
+ // A secure cookie cannot be set from a URL with an insecure scheme.
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=B; Secure")
.HasExactlyExclusionReasonsForTesting(
{CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
- // A secure cookie can be created from a URL with a secure scheme.
+ // A secure cookie can be set from a URL with a secure scheme.
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
.IsInclude());
@@ -3095,6 +3068,288 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
NetLogEventPhase::NONE);
}
+// Tests the behavior of "Leave Secure Cookies Alone" in
+// MaybeDeleteEquivalentCookieAndUpdateStatus().
+// Check domain-match criterion: If either cookie domain matches the other,
+// don't set the insecure cookie.
+TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_DomainMatch) {
+ std::unique_ptr<CookieMonster> cm(new CookieMonster(nullptr, &net_log_));
+
+ // These domains will domain-match each other.
+ const char* kRegistrableDomain = "foo.com";
+ const char* kSuperdomain = "a.foo.com";
+ const char* kDomain = "b.a.foo.com";
+ const char* kSubdomain = "c.b.a.foo.com";
+ // This domain does not match any, aside from the registrable domain.
+ const char* kOtherDomain = "z.foo.com";
+
+ for (const char* preexisting_cookie_host :
+ {kRegistrableDomain, kSuperdomain, kDomain, kSubdomain}) {
+ GURL preexisting_cookie_url(
+ base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
+ preexisting_cookie_host}));
+ for (const char* new_cookie_host :
+ {kRegistrableDomain, kSuperdomain, kDomain, kSubdomain}) {
+ GURL https_url(base::StrCat(
+ {url::kHttpsScheme, url::kStandardSchemeSeparator, new_cookie_host}));
+ GURL http_url(base::StrCat(
+ {url::kHttpScheme, url::kStandardSchemeSeparator, new_cookie_host}));
+
+ // Preexisting Secure host and domain cookies.
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), preexisting_cookie_url, "A=0; Secure")
+ .IsInclude());
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(
+ cm.get(), preexisting_cookie_url,
+ base::StrCat({"B=0; Secure; Domain=", preexisting_cookie_host}))
+ .IsInclude());
+
+ // Don't set insecure cookie from an insecure URL if equivalent secure
+ // cookie exists.
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=1")
+ .HasExactlyExclusionReasonsForTesting(
+ {CanonicalCookie::CookieInclusionStatus::
+ EXCLUDE_OVERWRITE_SECURE}))
+ << "Insecure host cookie from " << http_url
+ << " should not be set if equivalent secure host cookie from "
+ << preexisting_cookie_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), http_url,
+ base::StrCat({"A=2; Domain=", new_cookie_host}))
+ .HasExactlyExclusionReasonsForTesting(
+ {CanonicalCookie::CookieInclusionStatus::
+ EXCLUDE_OVERWRITE_SECURE}))
+ << "Insecure domain cookie from " << http_url
+ << " should not be set if equivalent secure host cookie from "
+ << preexisting_cookie_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=1")
+ .HasExactlyExclusionReasonsForTesting(
+ {CanonicalCookie::CookieInclusionStatus::
+ EXCLUDE_OVERWRITE_SECURE}))
+ << "Insecure host cookie from " << http_url
+ << " should not be set if equivalent secure domain cookie from "
+ << preexisting_cookie_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), http_url,
+ base::StrCat({"B=2; Domain=", new_cookie_host}))
+ .HasExactlyExclusionReasonsForTesting(
+ {CanonicalCookie::CookieInclusionStatus::
+ EXCLUDE_OVERWRITE_SECURE}))
+ << "Insecure domain cookie from " << http_url
+ << " should not be set if equivalent secure domain cookie from "
+ << preexisting_cookie_url << " exists.";
+
+ // Allow setting insecure cookie from a secure URL even if equivalent
+ // secure cookie exists.
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=3;")
+ .IsInclude())
+ << "Insecure host cookie from " << https_url
+ << " can be set even if equivalent secure host cookie from "
+ << preexisting_cookie_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), https_url,
+ base::StrCat({"A=4; Domain=", new_cookie_host}))
+ .IsInclude())
+ << "Insecure domain cookie from " << https_url
+ << " can be set even if equivalent secure host cookie from "
+ << preexisting_cookie_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "B=3;")
+ .IsInclude())
+ << "Insecure host cookie from " << https_url
+ << " can be set even if equivalent secure domain cookie from "
+ << preexisting_cookie_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), https_url,
+ base::StrCat({"B=4; Domain=", new_cookie_host}))
+ .IsInclude())
+ << "Insecure domain cookie from " << https_url
+ << " can be set even if equivalent secure domain cookie from "
+ << preexisting_cookie_url << " exists.";
+
+ DeleteAll(cm.get());
+ }
+ }
+
+ // Test non-domain-matching case. These sets should all be allowed because the
+ // cookie is not equivalent.
+ GURL nonmatching_https_url(base::StrCat(
+ {url::kHttpsScheme, url::kStandardSchemeSeparator, kOtherDomain}));
+
+ for (const char* host : {kSuperdomain, kDomain, kSubdomain}) {
+ GURL https_url(
+ base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator, host}));
+ GURL http_url(
+ base::StrCat({url::kHttpScheme, url::kStandardSchemeSeparator, host}));
+
+ // Preexisting Secure host and domain cookies.
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), nonmatching_https_url,
+ "A=0; Secure")
+ .IsInclude());
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), nonmatching_https_url,
+ base::StrCat({"B=0; Secure; Domain=", kOtherDomain}))
+ .IsInclude());
+
+ // New cookie from insecure URL is set.
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=1;").IsInclude())
+ << "Insecure host cookie from " << http_url
+ << " can be set even if equivalent secure host cookie from "
+ << nonmatching_https_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), http_url, base::StrCat({"A=2; Domain=", host}))
+ .IsInclude())
+ << "Insecure domain cookie from " << http_url
+ << " can be set even if equivalent secure host cookie from "
+ << nonmatching_https_url << " exists.";
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=1;").IsInclude())
+ << "Insecure host cookie from " << http_url
+ << " can be set even if equivalent secure domain cookie from "
+ << nonmatching_https_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), http_url, base::StrCat({"B=2; Domain=", host}))
+ .IsInclude())
+ << "Insecure domain cookie from " << http_url
+ << " can be set even if equivalent secure domain cookie from "
+ << nonmatching_https_url << " exists.";
+
+ // New cookie from secure URL is set.
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=3;").IsInclude())
+ << "Insecure host cookie from " << https_url
+ << " can be set even if equivalent secure host cookie from "
+ << nonmatching_https_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), https_url, base::StrCat({"A=4; Domain=", host}))
+ .IsInclude())
+ << "Insecure domain cookie from " << https_url
+ << " can be set even if equivalent secure host cookie from "
+ << nonmatching_https_url << " exists.";
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(cm.get(), https_url, "B=3;").IsInclude())
+ << "Insecure host cookie from " << https_url
+ << " can be set even if equivalent secure host cookie from "
+ << nonmatching_https_url << " exists.";
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), https_url, base::StrCat({"B=4; Domain=", host}))
+ .IsInclude())
+ << "Insecure domain cookie from " << https_url
+ << " can be set even if equivalent secure host cookie from "
+ << nonmatching_https_url << " exists.";
+
+ DeleteAll(cm.get());
+ }
+}
+
+// Tests the behavior of "Leave Secure Cookies Alone" in
+// MaybeDeleteEquivalentCookieAndUpdateStatus().
+// Check path-match criterion: If the new cookie is for the same path or a
+// subdirectory of the preexisting cookie's path, don't set the new cookie.
+TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_PathMatch) {
+ std::unique_ptr<CookieMonster> cm(new CookieMonster(nullptr, &net_log_));
+
+ // A path that is later in this list will path-match all the paths before it.
+ const char* kPaths[] = {"/", "/1", "/1/2", "/1/2/3"};
+ // This path does not match any, aside from the root path.
+ const char* kOtherDirectory = "/9";
+
+ for (int preexisting_cookie_path_index = 0; preexisting_cookie_path_index < 4;
+ ++preexisting_cookie_path_index) {
+ const char* preexisting_cookie_path = kPaths[preexisting_cookie_path_index];
+ GURL preexisting_cookie_url(
+ base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
+ "a.foo.com", preexisting_cookie_path}));
+ for (int new_cookie_path_index = 0; new_cookie_path_index < 4;
+ ++new_cookie_path_index) {
+ const char* new_cookie_path = kPaths[new_cookie_path_index];
+ bool should_path_match =
+ new_cookie_path_index >= preexisting_cookie_path_index;
+ GURL https_url(
+ base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
+ "a.foo.com", new_cookie_path}));
+ GURL http_url(
+ base::StrCat({url::kHttpScheme, url::kStandardSchemeSeparator,
+ "a.foo.com", new_cookie_path}));
+
+ // Preexisting Secure cookie.
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(
+ cm.get(), preexisting_cookie_url,
+ base::StrCat({"A=0; Secure; Path=", preexisting_cookie_path}))
+ .IsInclude());
+
+ // Don't set insecure cookie from an insecure URL if equivalent secure
+ // cookie exists.
+ CanonicalCookie::CookieInclusionStatus set =
+ CreateAndSetCookieReturnStatus(
+ cm.get(), http_url,
+ base::StrCat({"A=1; Path=", new_cookie_path}));
+ EXPECT_TRUE(should_path_match
+ ? set.HasExactlyExclusionReasonsForTesting(
+ {CanonicalCookie::CookieInclusionStatus::
+ EXCLUDE_OVERWRITE_SECURE})
+ : set.IsInclude())
+ << "Insecure cookie from " << http_url << " should "
+ << (should_path_match ? "not " : "")
+ << "be set if equivalent secure cookie from "
+ << preexisting_cookie_url << " exists.";
+
+ // Allow setting insecure cookie from a secure URL even if equivalent
+ // secure cookie exists.
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), https_url,
+ base::StrCat({"A=2; Path=", new_cookie_path}))
+ .IsInclude())
+ << "Insecure cookie from " << http_url
+ << " can be set even if equivalent secure cookie from "
+ << preexisting_cookie_url << " exists.";
+
+ DeleteAll(cm.get());
+ }
+ }
+
+ // Test non-matching-path case. These sets should all be allowed because the
+ // cookie is not equivalent.
+ GURL nonmatching_https_url(
+ base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
+ "a.foo.com", kOtherDirectory}));
+
+ for (int new_cookie_path_index = 1; new_cookie_path_index < 4;
+ ++new_cookie_path_index) {
+ const char* new_cookie_path = kPaths[new_cookie_path_index];
+ GURL https_url(base::StrCat(
+ {url::kHttpsScheme, url::kStandardSchemeSeparator, new_cookie_path}));
+ GURL http_url(base::StrCat(
+ {url::kHttpScheme, url::kStandardSchemeSeparator, new_cookie_path}));
+
+ // Preexisting Secure cookie.
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(
+ cm.get(), nonmatching_https_url,
+ base::StrCat({"A=0; Secure; Path=", kOtherDirectory}))
+ .IsInclude());
+
+ // New cookie from insecure URL is set.
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(
+ cm.get(), http_url, base::StrCat({"A=1; Path=", new_cookie_path}))
+ .IsInclude())
+ << "Insecure cookie from " << http_url
+ << " can be set even if equivalent secure cookie from "
+ << nonmatching_https_url << " exists.";
+
+ // New cookie from secure URL is set.
+ EXPECT_TRUE(
+ CreateAndSetCookieReturnStatus(
+ cm.get(), https_url, base::StrCat({"A=1; Path=", new_cookie_path}))
+ .IsInclude())
+ << "Insecure cookie from " << https_url
+ << " can be set even if equivalent secure cookie from "
+ << nonmatching_https_url << " exists.";
+ }
+}
+
// Tests for behavior for strict secure cookies.
TEST_F(CookieMonsterTest, EvictSecureCookies) {
// Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
@@ -3254,10 +3509,12 @@ TEST_F(CookieMonsterTest, SetCanonicalCookieDoesNotBlockForLoadAll) {
// Start of a canonical cookie set.
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
callback_set;
+ GURL cookie_url("http://a.com/");
cm.SetCanonicalCookieAsync(
- CanonicalCookie::Create(GURL("http://a.com/"), "A=B", base::Time::Now(),
+ CanonicalCookie::Create(cookie_url, "A=B", base::Time::Now(),
base::nullopt /* server_time */),
- "http", CookieOptions::MakeAllInclusive(), callback_set.MakeCallback());
+ cookie_url, CookieOptions::MakeAllInclusive(),
+ callback_set.MakeCallback());
// Get cookies for a different URL.
GetCookieListCallback callback_get;
@@ -3339,7 +3596,7 @@ TEST_F(CookieMonsterTest, DeleteCookieWithInheritedTimestamps) {
auto cookie = CanonicalCookie::Create(url, cookie_line, t1, server_time);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
set_callback_1;
- cm.SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options,
+ cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
set_callback_1.MakeCallback());
set_callback_1.WaitUntilDone();
@@ -3347,7 +3604,7 @@ TEST_F(CookieMonsterTest, DeleteCookieWithInheritedTimestamps) {
cookie = CanonicalCookie::Create(url, cookie_line, t2, server_time);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
set_callback_2;
- cm.SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options,
+ cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
set_callback_2.MakeCallback());
set_callback_2.WaitUntilDone();
@@ -3380,7 +3637,7 @@ TEST_F(CookieMonsterTest, RejectCreatedSameSiteCookieOnSet) {
// ... but the environment is checked on set, so this may be rejected then.
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
- cm.SetCanonicalCookieAsync(std::move(cookie), "http", env_cross_site,
+ cm.SetCanonicalCookieAsync(std::move(cookie), url, env_cross_site,
callback.MakeCallback());
callback.WaitUntilDone();
EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
@@ -3404,7 +3661,7 @@ TEST_F(CookieMonsterTest, RejectCreatedSecureCookieOnSet) {
// Cookie is rejected when attempting to set from a non-secure scheme.
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
- cm.SetCanonicalCookieAsync(std::move(cookie), "http",
+ cm.SetCanonicalCookieAsync(std::move(cookie), http_url,
CookieOptions::MakeAllInclusive(),
callback.MakeCallback());
callback.WaitUntilDone();
@@ -3434,7 +3691,7 @@ TEST_F(CookieMonsterTest, RejectCreatedHttpOnlyCookieOnSet) {
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
options_no_httponly.set_exclude_httponly(); // Default, but make it explicit.
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
- cm.SetCanonicalCookieAsync(std::move(cookie), "http", options_no_httponly,
+ cm.SetCanonicalCookieAsync(std::move(cookie), url, options_no_httponly,
callback.MakeCallback());
callback.WaitUntilDone();
EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
@@ -3565,7 +3822,7 @@ TEST_F(CookieMonsterTest, CookiesWithoutSameSiteMustBeSecure) {
CanonicalCookie cookie_copy = *cookie;
CanonicalCookie::CookieInclusionStatus result =
SetCanonicalCookieReturnStatus(
- cm.get(), std::move(cookie), url.scheme(),
+ cm.get(), std::move(cookie), url,
true /* can_modify_httponly (irrelevant) */);
EXPECT_EQ(test.expected_set_cookie_result, result)
<< "Test case " << i << " failed.";
diff --git a/chromium/net/cookies/cookie_options.cc b/chromium/net/cookies/cookie_options.cc
index 252de953cea..3ab86e67f0c 100644
--- a/chromium/net/cookies/cookie_options.cc
+++ b/chromium/net/cookies/cookie_options.cc
@@ -6,20 +6,41 @@
#include "net/cookies/cookie_options.h"
+#include "net/cookies/cookie_util.h"
+
namespace net {
CookieOptions::SameSiteCookieContext
CookieOptions::SameSiteCookieContext::MakeInclusive() {
- return SameSiteCookieContext(ContextType::SAME_SITE_STRICT);
+ return SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
+ ContextType::SAME_SITE_STRICT);
+}
+
+CookieOptions::SameSiteCookieContext
+CookieOptions::SameSiteCookieContext::MakeInclusiveForSet() {
+ return SameSiteCookieContext(ContextType::SAME_SITE_LAX,
+ ContextType::SAME_SITE_LAX);
+}
+
+CookieOptions::SameSiteCookieContext::ContextType
+CookieOptions::SameSiteCookieContext::GetContextForCookieInclusion() const {
+ DCHECK_LE(schemeful_context_, context_);
+
+ if (cookie_util::IsSchemefulSameSiteEnabled())
+ return schemeful_context_;
+
+ return context_;
+}
+
+bool operator==(const CookieOptions::SameSiteCookieContext& lhs,
+ const CookieOptions::SameSiteCookieContext& rhs) {
+ return std::tie(lhs.context_, lhs.schemeful_context_) ==
+ std::tie(rhs.context_, rhs.schemeful_context_);
}
-int64_t CookieOptions::SameSiteCookieContext::ConvertToMetricsValue() const {
- if (cross_schemeness == CrossSchemeness::INSECURE_SECURE) {
- return static_cast<int64_t>(context) | kToSecureMask;
- } else if (cross_schemeness == CrossSchemeness::SECURE_INSECURE) {
- return static_cast<int64_t>(context) | kToInsecureMask;
- }
- return static_cast<int64_t>(context);
+bool operator!=(const CookieOptions::SameSiteCookieContext& lhs,
+ const CookieOptions::SameSiteCookieContext& rhs) {
+ return !(lhs == rhs);
}
// Keep default values in sync with content/public/common/cookie_manager.mojom.
@@ -39,15 +60,4 @@ CookieOptions CookieOptions::MakeAllInclusive() {
return options;
}
-bool operator==(const CookieOptions::SameSiteCookieContext& lhs,
- const CookieOptions::SameSiteCookieContext& rhs) {
- return std::tie(lhs.context, lhs.cross_schemeness) ==
- std::tie(rhs.context, rhs.cross_schemeness);
-}
-
-bool operator!=(const CookieOptions::SameSiteCookieContext& lhs,
- const CookieOptions::SameSiteCookieContext& rhs) {
- return !(lhs == rhs);
-}
-
} // namespace net
diff --git a/chromium/net/cookies/cookie_options.h b/chromium/net/cookies/cookie_options.h
index db0c434ec3b..abf074b6aab 100644
--- a/chromium/net/cookies/cookie_options.h
+++ b/chromium/net/cookies/cookie_options.h
@@ -33,49 +33,53 @@ class NET_EXPORT CookieOptions {
COUNT
};
- // Used for when, and in what direction, same-site requests and responses
- // are made in a cross-scheme context. Currently only used for metrics
- // gathering and does not affect cookie behavior.
- enum class CrossSchemeness {
- NONE,
- INSECURE_SECURE, // Insecure site-for-cookies, secure request/response
- SECURE_INSECURE // Secure site-for-cookies, insecure request/response
- };
-
- SameSiteCookieContext() : SameSiteCookieContext(ContextType::CROSS_SITE) {}
- explicit SameSiteCookieContext(
- ContextType same_site_context,
- CrossSchemeness cross_schemeness = CrossSchemeness::NONE)
- : context(same_site_context), cross_schemeness(cross_schemeness) {}
+ 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)
+ : context_(same_site_context),
+ schemeful_context_(schemeful_same_site_context) {
+ DCHECK_LE(schemeful_context_, context_);
+ }
// Convenience method which returns a SameSiteCookieContext with the most
- // inclusive context. This allows access to all SameSite cookies.
+ // inclusive contexts. This allows access to all SameSite cookies.
static SameSiteCookieContext MakeInclusive();
- // The following functions are for conversion to the previous style of
- // SameSiteCookieContext for metrics usage. This may be removed when the
- // metrics using them are also removed.
+ // Convenience method which returns a SameSiteCookieContext with the most
+ // inclusive contexts for set. This allows setting all SameSite cookies.
+ static SameSiteCookieContext MakeInclusiveForSet();
- // Used as the "COUNT" entry in a histogram enum.
- static constexpr int64_t MetricCount() {
- return (static_cast<int>(ContextType::SAME_SITE_STRICT) |
- kToInsecureMask) +
- 1;
- }
- int64_t ConvertToMetricsValue() const;
+ // Returns the context for determining SameSite cookie inclusion.
+ ContextType GetContextForCookieInclusion() const;
- ContextType context;
+ // 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; }
- CrossSchemeness cross_schemeness;
+ ContextType schemeful_context() const { return schemeful_context_; }
+ void set_schemeful_context(ContextType schemeful_context) {
+ schemeful_context_ = schemeful_context;
+ }
+
+ 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:
- // The following variables are for conversion to the previous style of
- // SameSiteCookieContext for metrics usage. This may be removed when the
- // metrics using them are also removed.
- // Mask indicating insecure site-for-cookies and secure request/response.
- static const int kToSecureMask = 1 << 5;
- // Mask indicating secure site-for-cookies and insecure request/response.
- static const int kToInsecureMask = kToSecureMask << 1;
+
+ ContextType context_;
+
+ ContextType schemeful_context_;
};
// Creates a CookieOptions object which:
@@ -88,8 +92,7 @@ class NET_EXPORT CookieOptions {
// These settings can be altered by calling:
//
// * |set_{include,exclude}_httponly()|
- // * |set_same_site_cookie_context(
- // CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT)|
+ // * |set_same_site_cookie_context()|
// * |set_do_not_update_access_time()|
CookieOptions();
@@ -103,7 +106,6 @@ class NET_EXPORT CookieOptions {
same_site_cookie_context_ = context;
}
- // Strips off the cross-scheme bits to only return the same-site context.
SameSiteCookieContext same_site_cookie_context() const {
return same_site_cookie_context_;
}
@@ -131,12 +133,6 @@ class NET_EXPORT CookieOptions {
bool return_excluded_cookies_;
};
-NET_EXPORT bool operator==(const CookieOptions::SameSiteCookieContext& lhs,
- const CookieOptions::SameSiteCookieContext& rhs);
-
-NET_EXPORT bool operator!=(const CookieOptions::SameSiteCookieContext& lhs,
- const CookieOptions::SameSiteCookieContext& rhs);
-
} // namespace net
#endif // NET_COOKIES_COOKIE_OPTIONS_H_
diff --git a/chromium/net/cookies/cookie_store.h b/chromium/net/cookies/cookie_store.h
index 996ad7d14df..4157f0ce83a 100644
--- a/chromium/net/cookies/cookie_store.h
+++ b/chromium/net/cookies/cookie_store.h
@@ -62,14 +62,14 @@ class NET_EXPORT CookieStore {
virtual ~CookieStore();
// Set the cookie on the cookie store. |cookie.IsCanonical()| must
- // be true. |source_scheme| denotes the scheme of the resource setting this.
+ // be true. |source_url| denotes the url of the resource setting this.
//
// |options| is used to determine the context the operation is run in, and
// which cookies it can alter (e.g. http only, or same site).
//
// The current time will be used in place of a null creation time.
virtual void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback) = 0;
diff --git a/chromium/net/cookies/cookie_store_test_helpers.cc b/chromium/net/cookies/cookie_store_test_helpers.cc
index 6ac538077e8..a709c84f134 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.cc
+++ b/chromium/net/cookies/cookie_store_test_helpers.cc
@@ -89,12 +89,12 @@ void DelayedCookieMonster::GetCookieListWithOptionsInternalCallback(
void DelayedCookieMonster::SetCanonicalCookieAsync(
std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback) {
did_run_ = false;
cookie_monster_->SetCanonicalCookieAsync(
- std::move(cookie), std::move(source_scheme), options,
+ std::move(cookie), source_url, options,
base::BindOnce(&DelayedCookieMonster::SetCookiesInternalCallback,
base::Unretained(this)));
DCHECK_EQ(did_run_, true);
diff --git a/chromium/net/cookies/cookie_store_test_helpers.h b/chromium/net/cookies/cookie_store_test_helpers.h
index a78190831b6..ae6a152b7f2 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.h
+++ b/chromium/net/cookies/cookie_store_test_helpers.h
@@ -54,7 +54,7 @@ class DelayedCookieMonster : public CookieStore {
// Post a delayed task to invoke the original callback with the results.
void SetCanonicalCookieAsync(std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback) override;
diff --git a/chromium/net/cookies/cookie_store_unittest.h b/chromium/net/cookies/cookie_store_unittest.h
index 1e86c65f34a..ee8e46f9b1d 100644
--- a/chromium/net/cookies/cookie_store_unittest.h
+++ b/chromium/net/cookies/cookie_store_unittest.h
@@ -201,7 +201,7 @@ class CookieStoreTest : public testing::Test {
return false;
DCHECK(cs);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
- cs->SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options,
+ cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
callback.MakeCallback());
callback.WaitUntilDone();
return callback.result().IsInclude();
@@ -209,7 +209,7 @@ class CookieStoreTest : public testing::Test {
bool SetCanonicalCookie(CookieStore* cs,
std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
bool can_modify_httponly) {
DCHECK(cs);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
@@ -218,8 +218,8 @@ class CookieStoreTest : public testing::Test {
options.set_include_httponly();
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
- cs->SetCanonicalCookieAsync(std::move(cookie), std::move(source_scheme),
- options, callback.MakeCallback());
+ cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
+ callback.MakeCallback());
callback.WaitUntilDone();
return callback.result().IsInclude();
}
@@ -268,7 +268,7 @@ class CookieStoreTest : public testing::Test {
DCHECK(cs);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
- cs->SetCanonicalCookieAsync(std::move(cookie), url.scheme(), options,
+ cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
callback.MakeCallback());
callback.WaitUntilDone();
return callback.result();
@@ -277,7 +277,7 @@ class CookieStoreTest : public testing::Test {
CanonicalCookie::CookieInclusionStatus SetCanonicalCookieReturnStatus(
CookieStore* cs,
std::unique_ptr<CanonicalCookie> cookie,
- std::string source_scheme,
+ const GURL& source_url,
bool can_modify_httponly) {
DCHECK(cs);
ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
@@ -286,8 +286,8 @@ class CookieStoreTest : public testing::Test {
options.set_include_httponly();
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
- cs->SetCanonicalCookieAsync(std::move(cookie), std::move(source_scheme),
- options, callback.MakeCallback());
+ cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
+ callback.MakeCallback());
callback.WaitUntilDone();
return callback.result();
}
@@ -424,8 +424,8 @@ TYPED_TEST_P(CookieStoreTest, FilterTest) {
one_hour_from_now, base::Time(), false, false,
CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT));
ASSERT_TRUE(cc);
- EXPECT_TRUE(this->SetCanonicalCookie(cs, std::move(cc), "https",
- true /*modify_httponly*/));
+ EXPECT_TRUE(this->SetCanonicalCookie(
+ cs, std::move(cc), this->www_foo_foo_.url(), true /*modify_httponly*/));
// Note that for the creation time to be set exactly, without modification,
// it must be different from the one set by the line above.
@@ -434,8 +434,8 @@ TYPED_TEST_P(CookieStoreTest, FilterTest) {
two_hours_ago, base::Time(), one_hour_ago, false, true,
CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
ASSERT_TRUE(cc);
- EXPECT_TRUE(this->SetCanonicalCookie(cs, std::move(cc), "https",
- true /*modify_httponly*/));
+ EXPECT_TRUE(this->SetCanonicalCookie(
+ cs, std::move(cc), this->www_foo_bar_.url(), true /*modify_httponly*/));
// Because of strict secure cookies, it should not be possible to create
// a secure cookie with an HTTP URL.
@@ -451,8 +451,8 @@ TYPED_TEST_P(CookieStoreTest, FilterTest) {
base::Time(), base::Time(), base::Time(), true, false,
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
ASSERT_TRUE(cc);
- EXPECT_TRUE(this->SetCanonicalCookie(cs, std::move(cc), "https",
- true /*modify_httponly*/));
+ EXPECT_TRUE(this->SetCanonicalCookie(
+ cs, std::move(cc), this->https_www_foo_.url(), true /*modify_httponly*/));
// Get all the cookies for a given URL, regardless of properties. This 'get()'
// operation shouldn't update the access time, as the test checks that the
@@ -550,16 +550,14 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"A", "B", foo_foo_host, "/foo", one_hour_ago, one_hour_from_now,
base::Time(), false /* secure */, false /* httponly */,
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
- "http", true));
- // Note that for the creation time to be set exactly, without modification,
- // it must be different from the one set by the line above.
+ this->www_foo_foo_.url(), true));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"C", "D", "." + foo_bar_domain, "/bar", two_hours_ago, base::Time(),
one_hour_ago, false, true, CookieSameSite::LAX_MODE,
COOKIE_PRIORITY_DEFAULT),
- "http", true));
+ this->www_foo_bar_.url(), true));
// A secure source is required for setting secure cookies.
EXPECT_TRUE(
@@ -569,7 +567,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
COOKIE_PRIORITY_DEFAULT),
- "http", true)
+ this->http_www_foo_.url(), true)
.HasExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
@@ -582,7 +580,8 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
EXPECT_TRUE(cookie->IsSecure());
EXPECT_TRUE(status.IsInclude());
EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(cs, std::move(cookie), "http", true)
+ this->SetCanonicalCookieReturnStatus(cs, std::move(cookie),
+ this->http_www_foo_.url(), true)
.HasExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
@@ -591,10 +590,10 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
- "E", "F", http_foo_host, "/", base::Time(), base::Time(),
+ "E", "F", https_foo_host, "/", base::Time(), base::Time(),
base::Time(), true /* secure */, false /* httponly */,
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
- "https", true /* modify_http_only */));
+ this->https_www_foo_.url(), true /* modify_http_only */));
EXPECT_TRUE(
this->SetCanonicalCookieReturnStatus(
@@ -603,7 +602,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
base::Time(), true /* secure */, false /* httponly */,
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
- "http", true /* modify_http_only */)
+ this->http_www_foo_.url(), true /* modify_http_only */)
.HasExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
@@ -618,7 +617,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
base::Time(), base::Time(), false /* secure */,
true /* httponly */, CookieSameSite::LAX_MODE,
COOKIE_PRIORITY_DEFAULT),
- "http", false /* modify_http_only */)
+ this->http_www_foo_.url(), false /* modify_http_only */)
.HasExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
@@ -631,7 +630,8 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
EXPECT_TRUE(c->IsHttpOnly());
EXPECT_TRUE(create_status.IsInclude());
EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(cs, std::move(c), "http",
+ this->SetCanonicalCookieReturnStatus(cs, std::move(c),
+ this->http_www_foo_.url(),
false /* can_modify_httponly */)
.HasExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
@@ -644,7 +644,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
base::Time(), false /* secure */, true /* httponly */,
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
- "http", true /* modify_http_only */));
+ this->http_www_foo_.url(), true /* modify_http_only */));
EXPECT_TRUE(
this->SetCanonicalCookieReturnStatus(
@@ -654,7 +654,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
base::Time(), base::Time(), false /* secure */,
true /* httponly */, CookieSameSite::LAX_MODE,
COOKIE_PRIORITY_DEFAULT),
- "http", false /* modify_http_only */)
+ this->http_www_foo_.url(), false /* modify_http_only */)
.HasExclusionReason(
CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
} else {
@@ -665,7 +665,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
base::Time(), false /* secure */, true /* httponly */,
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
- "http", true /* modify_http_only */));
+ this->http_www_foo_.url(), true /* modify_http_only */));
}
// Get all the cookies for a given URL, regardless of properties. This 'get()'
@@ -743,28 +743,28 @@ TYPED_TEST_P(CookieStoreTest, SecureEnforcement) {
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), true, false, CookieSameSite::STRICT_MODE,
COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ http_url, true /*modify_httponly*/));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), true, false, CookieSameSite::STRICT_MODE,
COOKIE_PRIORITY_DEFAULT),
- "https", true /*modify_httponly*/));
+ https_url, true /*modify_httponly*/));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), false, false, CookieSameSite::STRICT_MODE,
COOKIE_PRIORITY_DEFAULT),
- "https", true /*modify_httponly*/));
+ https_url, true /*modify_httponly*/));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), false, false, CookieSameSite::STRICT_MODE,
COOKIE_PRIORITY_DEFAULT),
- "http", true /*modify_httponly*/));
+ http_url, true /*modify_httponly*/));
}
// The iOS networking stack uses the iOS cookie parser, which we do not
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index ed58360cd75..7f3afe4e178 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -9,8 +9,9 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/check.h"
#include "base/feature_list.h"
-#include "base/logging.h"
+#include "base/notreached.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
@@ -21,12 +22,15 @@
#include "net/base/url_util.h"
#include "net/http/http_util.h"
#include "url/gurl.h"
+#include "url/url_constants.h"
namespace net {
namespace cookie_util {
namespace {
+using ContextType = CookieOptions::SameSiteCookieContext::ContextType;
+
base::Time MinNonNullTime() {
return base::Time::FromInternalValue(1);
}
@@ -74,47 +78,45 @@ bool SaturatedTimeFromUTCExploded(const base::Time::Exploded& exploded,
return false;
}
-CookieOptions::SameSiteCookieContext::CrossSchemeness ComputeSchemeChange(
- const GURL& url,
- const SiteForCookies& site_for_cookies) {
-
- CookieOptions::SameSiteCookieContext::CrossSchemeness cross_schemeness =
- CookieOptions::SameSiteCookieContext::CrossSchemeness::NONE;
- bool url_secure = url.SchemeIsCryptographic();
- bool site_for_cookies_secure =
- GURL::SchemeIsCryptographic(site_for_cookies.scheme());
-
- if (url_secure && !site_for_cookies_secure) {
- cross_schemeness =
- CookieOptions::SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE;
- } else if (!url_secure && site_for_cookies_secure) {
- cross_schemeness =
- CookieOptions::SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE;
+ContextType ComputeSameSiteContext(const GURL& url,
+ const SiteForCookies& site_for_cookies,
+ const base::Optional<url::Origin>& initiator,
+ bool compute_schemefully) {
+ if (site_for_cookies.IsFirstPartyWithSchemefulMode(url,
+ compute_schemefully)) {
+ // Create a SiteForCookies object from the initiator so that we can reuse
+ // IsFirstPartyWithSchemefulMode().
+ if (!initiator ||
+ SiteForCookies::FromOrigin(initiator.value())
+ .IsFirstPartyWithSchemefulMode(url, compute_schemefully)) {
+ return ContextType::SAME_SITE_STRICT;
+ } else {
+ return ContextType::SAME_SITE_LAX;
+ }
}
-
- return cross_schemeness;
+ return ContextType::CROSS_SITE;
}
-CookieOptions::SameSiteCookieContext ComputeSameSiteContext(
+CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSet(
const GURL& url,
const SiteForCookies& site_for_cookies,
- const base::Optional<url::Origin>& initiator) {
- CookieOptions::SameSiteCookieContext same_site_type(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE);
- if (site_for_cookies.IsFirstParty(url)) {
- // Create a SiteForCookies object from the initiator so that we can reuse
- // IsFirstParty().
- if (!initiator ||
- SiteForCookies::FromOrigin(initiator.value()).IsFirstParty(url)) {
- same_site_type.context =
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT;
- } else {
- same_site_type.context =
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX;
- }
+ bool force_ignore_site_for_cookies) {
+ if (force_ignore_site_for_cookies)
+ return CookieOptions::SameSiteCookieContext::MakeInclusiveForSet();
+
+ // Schemeless check
+ if (!site_for_cookies.IsFirstPartyWithSchemefulMode(url, false)) {
+ return CookieOptions::SameSiteCookieContext(ContextType::CROSS_SITE,
+ ContextType::CROSS_SITE);
}
- same_site_type.cross_schemeness = ComputeSchemeChange(url, site_for_cookies);
- return same_site_type;
+
+ // Schemeful check
+ if (!site_for_cookies.IsFirstPartyWithSchemefulMode(url, true)) {
+ return CookieOptions::SameSiteCookieContext(ContextType::SAME_SITE_LAX,
+ ContextType::CROSS_SITE);
+ }
+
+ return CookieOptions::SameSiteCookieContext::MakeInclusiveForSet();
}
} // namespace
@@ -123,6 +125,12 @@ bool DomainIsHostOnly(const std::string& domain_string) {
return (domain_string.empty() || domain_string[0] != '.');
}
+std::string CookieDomainAsHost(const std::string& cookie_domain) {
+ if (DomainIsHostOnly(cookie_domain))
+ return cookie_domain;
+ return cookie_domain.substr(1);
+}
+
std::string GetEffectiveDomain(const std::string& scheme,
const std::string& host) {
if (scheme == "http" || scheme == "https" || scheme == "ws" ||
@@ -132,9 +140,7 @@ std::string GetEffectiveDomain(const std::string& scheme,
registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
}
- if (!DomainIsHostOnly(host))
- return host.substr(1);
- return host;
+ return CookieDomainAsHost(host);
}
bool GetCookieDomainWithString(const GURL& url,
@@ -324,9 +330,19 @@ GURL CookieOriginToURL(const std::string& domain, bool is_https) {
if (domain.empty())
return GURL();
- const std::string scheme = is_https ? "https" : "http";
- const std::string host = domain[0] == '.' ? domain.substr(1) : domain;
- return GURL(scheme + "://" + host);
+ const std::string scheme = is_https ? url::kHttpsScheme : url::kHttpScheme;
+ return GURL(scheme + url::kStandardSchemeSeparator +
+ CookieDomainAsHost(domain) + "/");
+}
+
+GURL SimulatedCookieSource(const CanonicalCookie& cookie,
+ const std::string& source_scheme) {
+ // Note: cookie.DomainWithoutDot() could be empty for e.g. file cookies.
+ if (cookie.DomainWithoutDot().empty() || source_scheme.empty())
+ return GURL();
+
+ return GURL(source_scheme + url::kStandardSchemeSeparator +
+ cookie.DomainWithoutDot() + cookie.Path());
}
bool IsDomainMatch(const std::string& domain, const std::string& host) {
@@ -421,7 +437,7 @@ CookieOptions::SameSiteCookieContext ComputeSameSiteContextForRequest(
const GURL& url,
const SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& initiator,
- bool attach_same_site_cookies) {
+ bool force_ignore_site_for_cookies) {
// Set SameSiteCookieMode according to the rules laid out in
// https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02:
//
@@ -446,25 +462,27 @@ CookieOptions::SameSiteCookieContext ComputeSameSiteContextForRequest(
// but appear like cross-site ones.
//
// * Otherwise, do not include same-site cookies.
- CookieOptions::SameSiteCookieContext same_site_context;
- if (attach_same_site_cookies) {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT;
- same_site_context.cross_schemeness =
- ComputeSchemeChange(url, site_for_cookies);
- return same_site_context;
- }
+ if (force_ignore_site_for_cookies)
+ return CookieOptions::SameSiteCookieContext::MakeInclusive();
+
+ CookieOptions::SameSiteCookieContext same_site_context;
- same_site_context = ComputeSameSiteContext(url, site_for_cookies, initiator);
+ same_site_context.set_context(
+ ComputeSameSiteContext(url, site_for_cookies, initiator, false));
+ same_site_context.set_schemeful_context(
+ ComputeSameSiteContext(url, site_for_cookies, initiator, true));
// If the method is safe, the context is Lax. Otherwise, make a note that
// the method is unsafe.
- if (same_site_context.context ==
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX &&
- !net::HttpUtil::IsMethodSafe(http_method)) {
- same_site_context.context = CookieOptions::SameSiteCookieContext::
- ContextType::SAME_SITE_LAX_METHOD_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);
+ }
}
return same_site_context;
@@ -474,71 +492,63 @@ NET_EXPORT CookieOptions::SameSiteCookieContext
ComputeSameSiteContextForScriptGet(const GURL& url,
const SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& initiator,
- bool attach_same_site_cookies) {
- if (attach_same_site_cookies) {
- CookieOptions::SameSiteCookieContext same_site_context(
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT);
- same_site_context.cross_schemeness =
- ComputeSchemeChange(url, site_for_cookies);
- return same_site_context;
- }
- return ComputeSameSiteContext(url, site_for_cookies, initiator);
+ bool force_ignore_site_for_cookies) {
+ if (force_ignore_site_for_cookies)
+ return CookieOptions::SameSiteCookieContext::MakeInclusive();
+
+ CookieOptions::SameSiteCookieContext same_site_context;
+
+ same_site_context.set_context(
+ ComputeSameSiteContext(url, site_for_cookies, initiator, false));
+ same_site_context.set_schemeful_context(
+ ComputeSameSiteContext(url, site_for_cookies, initiator, true));
+
+ return same_site_context;
}
CookieOptions::SameSiteCookieContext ComputeSameSiteContextForResponse(
const GURL& url,
const SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& initiator,
- bool attach_same_site_cookies) {
- CookieOptions::SameSiteCookieContext same_site_context;
+ bool force_ignore_site_for_cookies) {
// |initiator| is here in case it'll be decided to ignore |site_for_cookies|
// for entirely browser-side requests (see https://crbug.com/958335).
- if (attach_same_site_cookies || site_for_cookies.IsFirstParty(url)) {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX;
- } else {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE;
- }
- same_site_context.cross_schemeness =
- ComputeSchemeChange(url, site_for_cookies);
- return same_site_context;
+
+ return ComputeSameSiteContextForSet(url, site_for_cookies,
+ force_ignore_site_for_cookies);
}
CookieOptions::SameSiteCookieContext ComputeSameSiteContextForScriptSet(
const GURL& url,
const SiteForCookies& site_for_cookies,
- bool attach_same_site_cookies) {
- CookieOptions::SameSiteCookieContext same_site_context;
- if (attach_same_site_cookies || site_for_cookies.IsFirstParty(url)) {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX;
- } else {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE;
- }
- same_site_context.cross_schemeness =
- ComputeSchemeChange(url, site_for_cookies);
- return same_site_context;
+ bool force_ignore_site_for_cookies) {
+ return ComputeSameSiteContextForSet(url, site_for_cookies,
+ force_ignore_site_for_cookies);
}
CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSubresource(
const GURL& url,
const SiteForCookies& site_for_cookies,
- bool attach_same_site_cookies) {
- CookieOptions::SameSiteCookieContext same_site_context;
+ bool force_ignore_site_for_cookies) {
+ if (force_ignore_site_for_cookies)
+ return CookieOptions::SameSiteCookieContext::MakeInclusive();
+
// If the URL is same-site as site_for_cookies it's same-site as all frames
// in the tree from the initiator frame up --- including the initiator frame.
- if (attach_same_site_cookies || site_for_cookies.IsFirstParty(url)) {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT;
- } else {
- same_site_context.context =
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE;
+
+ // Schemeless check
+ if (!site_for_cookies.IsFirstPartyWithSchemefulMode(url, false)) {
+ return CookieOptions::SameSiteCookieContext(ContextType::CROSS_SITE,
+ ContextType::CROSS_SITE);
}
- same_site_context.cross_schemeness =
- ComputeSchemeChange(url, site_for_cookies);
- return same_site_context;
+
+ // Schemeful check
+ if (!site_for_cookies.IsFirstPartyWithSchemefulMode(url, true)) {
+ return CookieOptions::SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
+ ContextType::CROSS_SITE);
+ }
+
+ return CookieOptions::SameSiteCookieContext::MakeInclusive();
}
bool IsSameSiteByDefaultCookiesEnabled() {
@@ -551,6 +561,10 @@ bool IsCookiesWithoutSameSiteMustBeSecureEnabled() {
features::kCookiesWithoutSameSiteMustBeSecure);
}
+bool IsSchemefulSameSiteEnabled() {
+ return base::FeatureList::IsEnabled(features::kSchemefulSameSite);
+}
+
bool IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled() {
return IsSameSiteByDefaultCookiesEnabled() &&
base::FeatureList::IsEnabled(
diff --git a/chromium/net/cookies/cookie_util.h b/chromium/net/cookies/cookie_util.h
index 19c63715b3d..3634058c1b0 100644
--- a/chromium/net/cookies/cookie_util.h
+++ b/chromium/net/cookies/cookie_util.h
@@ -48,6 +48,13 @@ NET_EXPORT bool GetCookieDomainWithString(const GURL& url,
// i.e. it doesn't begin with a leading '.' character.
NET_EXPORT bool DomainIsHostOnly(const std::string& domain_string);
+// If |cookie_domain| is nonempty and starts with a "." character, this returns
+// the substring of |cookie_domain| without the leading dot. (Note only one
+// leading dot is stripped, if there are multiple.) Otherwise it returns
+// |cookie_domain|. This is useful for converting from CanonicalCookie's
+// representation of a cookie domain to the RFC's notion of a cookie's domain.
+NET_EXPORT std::string CookieDomainAsHost(const std::string& cookie_domain);
+
// Parses the string with the cookie expiration time (very forgivingly).
// Returns the "null" time on failure.
//
@@ -59,8 +66,16 @@ NET_EXPORT base::Time ParseCookieExpirationTime(const std::string& time_string);
// Convenience for converting a cookie origin (domain and https pair) to a URL.
NET_EXPORT GURL CookieOriginToURL(const std::string& domain, bool is_https);
-// Returns true if the cookie |domain| matches the given |host| as described
-// in section 5.1.3 of RFC 6265.
+// Returns a URL that could have been the cookie's source.
+// Not guaranteed to actually be the URL that set the cookie. Not guaranteed to
+// be a valid GURL. Intended as a shim for SetCanonicalCookieAsync calls, where
+// a source URL is required but only a source scheme may be available.
+NET_EXPORT GURL SimulatedCookieSource(const CanonicalCookie& cookie,
+ const std::string& source_scheme);
+
+// |domain| is the output of cookie.Domain() for some cookie. This returns true
+// if a |domain| indicates that the cookie can be accessed by |host|.
+// See comment on CanonicalCookie::IsDomainMatch().
NET_EXPORT bool IsDomainMatch(const std::string& domain,
const std::string& host);
@@ -98,7 +113,7 @@ NET_EXPORT std::string SerializeRequestCookieLine(
// the user directly interacting with the browser UI, e.g. entering a URL
// or selecting a bookmark.
//
-// If |attach_same_site_cookies| is specified, all SameSite cookies will be
+// If |force_ignore_site_for_cookies| is specified, all SameSite cookies will be
// attached, i.e. this will return SAME_SITE_STRICT. This flag is set to true
// when the |site_for_cookies| is a chrome:// URL embedding a secure origin,
// among other scenarios.
@@ -116,50 +131,51 @@ ComputeSameSiteContextForRequest(const std::string& http_method,
const GURL& url,
const SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& initiator,
- bool attach_same_site_cookies);
+ bool force_ignore_site_for_cookies);
// As above, but applying for scripts. |initiator| here should be the initiator
// used when fetching the document.
-// If |attach_same_site_cookies| is true, this returns SAME_SITE_STRICT.
+// If |force_ignore_site_for_cookies| is true, this returns SAME_SITE_STRICT.
NET_EXPORT CookieOptions::SameSiteCookieContext
ComputeSameSiteContextForScriptGet(const GURL& url,
const SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& initiator,
- bool attach_same_site_cookies);
+ bool force_ignore_site_for_cookies);
// Determines which of the cookies for |url| can be set from a network response,
// with respect to the SameSite attribute. This will only return CROSS_SITE or
// SAME_SITE_LAX (cookie sets of SameSite=strict cookies are permitted in same
// contexts that sets of SameSite=lax cookies are).
-// If |attach_same_site_cookies| is true, this returns SAME_SITE_LAX.
+// If |force_ignore_site_for_cookies| is true, this returns SAME_SITE_LAX.
NET_EXPORT CookieOptions::SameSiteCookieContext
ComputeSameSiteContextForResponse(const GURL& url,
const SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& initiator,
- bool attach_same_site_cookies);
+ bool force_ignore_site_for_cookies);
// Determines which of the cookies for |url| can be set from a script context,
// with respect to the SameSite attribute. This will only return CROSS_SITE or
// SAME_SITE_LAX (cookie sets of SameSite=strict cookies are permitted in same
// contexts that sets of SameSite=lax cookies are).
-// If |attach_same_site_cookies| is true, this returns SAME_SITE_LAX.
+// If |force_ignore_site_for_cookies| is true, this returns SAME_SITE_LAX.
NET_EXPORT CookieOptions::SameSiteCookieContext
ComputeSameSiteContextForScriptSet(const GURL& url,
const SiteForCookies& site_for_cookies,
- bool attach_same_site_cookies);
+ bool force_ignore_site_for_cookies);
// Determines which of the cookies for |url| can be accessed when fetching a
// subresources. This is either CROSS_SITE or SAME_SITE_STRICT,
// since the initiator for a subresource is the frame loading it.
NET_EXPORT CookieOptions::SameSiteCookieContext
-// If |attach_same_site_cookies| is true, this returns SAME_SITE_STRICT.
+// If |force_ignore_site_for_cookies| is true, this returns SAME_SITE_STRICT.
ComputeSameSiteContextForSubresource(const GURL& url,
const SiteForCookies& site_for_cookies,
- bool attach_same_site_cookies);
+ bool force_ignore_site_for_cookies);
// Returns whether the respective SameSite feature is enabled.
NET_EXPORT bool IsSameSiteByDefaultCookiesEnabled();
NET_EXPORT bool IsCookiesWithoutSameSiteMustBeSecureEnabled();
+NET_EXPORT bool IsSchemefulSameSiteEnabled();
bool IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled();
bool IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled();
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index 13f41bae1f5..b95e1d6da26 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -225,6 +225,49 @@ TEST(CookieUtilTest, TestRequestCookieParsing) {
}
}
+TEST(CookieUtilTest, SimulatedCookieSource) {
+ GURL secure_url("https://b.a.com");
+ GURL insecure_url("http://b.a.com");
+
+ struct {
+ std::string cookie;
+ std::string source_scheme;
+ std::string expected_simulated_source;
+ } kTests[]{
+ {"cookie=foo", "http", "http://b.a.com/"},
+ {"cookie=foo", "https", "https://b.a.com/"},
+ {"cookie=foo", "wss", "wss://b.a.com/"},
+ {"cookie=foo", "file", "file://b.a.com/"},
+ {"cookie=foo; Domain=b.a.com", "https", "https://b.a.com/"},
+ {"cookie=foo; Domain=a.com", "https", "https://a.com/"},
+ {"cookie=foo; Domain=.b.a.com", "https", "https://b.a.com/"},
+ {"cookie=foo; Domain=.a.com", "https", "https://a.com/"},
+ {"cookie=foo; Path=/", "https", "https://b.a.com/"},
+ {"cookie=foo; Path=/bar", "https", "https://b.a.com/bar"},
+ {"cookie=foo; Domain=b.a.com; Path=/", "https", "https://b.a.com/"},
+ {"cookie=foo; Domain=b.a.com; Path=/bar", "https", "https://b.a.com/bar"},
+ {"cookie=foo; Domain=a.com; Path=/", "https", "https://a.com/"},
+ {"cookie=foo; Domain=a.com; Path=/bar", "https", "https://a.com/bar"},
+ };
+
+ for (const auto& test : kTests) {
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies;
+ // It shouldn't depend on the cookie's secureness or actual source scheme.
+ cookies.push_back(CanonicalCookie::Create(
+ insecure_url, test.cookie, base::Time::Now(), base::nullopt));
+ cookies.push_back(CanonicalCookie::Create(
+ secure_url, test.cookie, base::Time::Now(), base::nullopt));
+ cookies.push_back(
+ CanonicalCookie::Create(secure_url, test.cookie + "; Secure",
+ base::Time::Now(), base::nullopt));
+ for (const auto& cookie : cookies) {
+ GURL simulated_source =
+ cookie_util::SimulatedCookieSource(*cookie, test.source_scheme);
+ EXPECT_EQ(GURL(test.expected_simulated_source), simulated_source);
+ }
+ }
+}
+
TEST(CookieUtilTest, TestGetEffectiveDomain) {
// Note: registry_controlled_domains::GetDomainAndRegistry is tested in its
// own unittests.
@@ -261,25 +304,24 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt /*initiator*/, false /* attach_same_site_cookies */));
+ base::nullopt /*initiator*/,
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt /*initiator*/, false /* attach_same_site_cookies */));
+ base::nullopt /*initiator*/,
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://notexample.com")),
- base::nullopt /*initiator*/, false /* attach_same_site_cookies */));
+ base::nullopt /*initiator*/,
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
@@ -287,32 +329,53 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
url::Origin::Create(GURL("http://example.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForScriptGet(
- GURL("https://example.com"),
- SiteForCookies::FromUrl(GURL("http://notexample.com")),
- url::Origin::Create(GURL("http://example.com")),
- false /* attach_same_site_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://notexample.com")),
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- cookie_util::ComputeSameSiteContextForScriptGet(
- GURL("http://example.com"),
- SiteForCookies::FromUrl(GURL("https://notexample.com")),
- url::Origin::Create(GURL("http://example.com")),
- false /* attach_same_site_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://notexample.com")),
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://a.com"), SiteForCookies::FromUrl(GURL("http://b.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
+
+ // |site_for_cookies| not being schemefully_same -> it's cross-site.
+ SiteForCookies insecure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("http://example.com"));
+ insecure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("http://example.com"), insecure_not_schemefully_same,
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ SiteForCookies secure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("https://example.com"));
+ secure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("https://example.com"), secure_not_schemefully_same,
+ url::Origin::Create(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
// Same |site_for_cookies|, but not |initiator| -> it's same-site lax.
EXPECT_EQ(
@@ -322,27 +385,46 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
// This isn't a full on origin check --- subdomains and different schema are
- // accepted.
+ // accepted. For SameSiteCookieContext::schemeful_context the scheme is
+ // considered.
EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
cookie_util::ComputeSameSiteContextForScriptGet(
- GURL("https://example.com"),
+ GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
- url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /* attach_same_site_cookies */));
+ url::Origin::Create(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
cookie_util::ComputeSameSiteContextForScriptGet(
- GURL("http://example.com"),
+ GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("https://example.com")),
- url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /* attach_same_site_cookies */));
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ url::Origin::Create(GURL("http://from-elsewhere.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ url::Origin::Create(GURL("http://from-elsewhere.com")),
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
@@ -350,7 +432,7 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://sub.example.com"),
SiteForCookies::FromUrl(GURL("http://sub2.example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
@@ -358,7 +440,24 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://sub.example.com"),
SiteForCookies::FromUrl(GURL("http://sub.example.com:8080")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
+
+ // wss/https and http/ws are considered the same for schemeful purposes.
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("wss://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ url::Origin::Create(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("ws://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
// nullopt |initiator| is trusted for purposes of strict, an opaque one isn't.
EXPECT_EQ(SameSiteCookieContext(
@@ -367,25 +466,25 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
- EXPECT_EQ(
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForScriptGet(
- GURL("https://example.com"),
- SiteForCookies::FromUrl(GURL("http://example.com")),
- base::nullopt /*initiator*/, false /* attach_same_site_cookies */));
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ base::nullopt /*initiator*/,
+ false /* force_ignore_site_for_cookies */));
- EXPECT_EQ(
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- cookie_util::ComputeSameSiteContextForScriptGet(
- GURL("http://example.com"),
- SiteForCookies::FromUrl(GURL("https://example.com")),
- base::nullopt /*initiator*/, false /* attach_same_site_cookies */));
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptGet(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ base::nullopt /*initiator*/,
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -393,7 +492,8 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
- base::nullopt /*initiator*/, false /* attach_same_site_cookies */));
+ base::nullopt /*initiator*/,
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -401,9 +501,9 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")), url::Origin(),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
- // |attach_same_site_cookies| causes (some variant of) SAME_SITE_STRICT to be
+ // |force_ignore_site_for_cookies| causes SAME_SITE_STRICT to be
// returned.
EXPECT_EQ(
SameSiteCookieContext(
@@ -411,7 +511,8 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt /*initiator*/, true /* attach_same_site_cookies */));
+ base::nullopt /*initiator*/,
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -420,7 +521,7 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
url::Origin::Create(GURL("http://example.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -428,7 +529,7 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://a.com"), SiteForCookies::FromUrl(GURL("http://b.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -437,25 +538,23 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
cookie_util::ComputeSameSiteContextForScriptGet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -464,7 +563,7 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://sub.example.com"),
SiteForCookies::FromUrl(GURL("http://sub2.example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -473,37 +572,59 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForScriptGet) {
GURL("http://sub.example.com"),
SiteForCookies::FromUrl(GURL("http://sub.example.com:8080")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
}
TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
- EXPECT_EQ(
- SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
- cookie_util::ComputeSameSiteContextForRequest(
- "GET", GURL("http://example.com"),
- SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt /*initiator*/, false /*attach_same_site_cookies*/));
- EXPECT_EQ(
- SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForRequest(
- "GET", GURL("https://example.com"),
- SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt /*initiator*/, false /*attach_same_site_cookies*/));
+ EXPECT_EQ(SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("http://notexample.com")),
+ base::nullopt /*initiator*/,
+ false /*force_ignore_site_for_cookies*/));
+ EXPECT_EQ(SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://notexample.com")),
+ base::nullopt /*initiator*/,
+ false /*force_ignore_site_for_cookies*/));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://notexample.com")),
+ base::nullopt /*initiator*/,
+ false /*force_ignore_site_for_cookies*/));
+ // |site_for_cookies| not being schemefully_same -> it's cross-site.
+ SiteForCookies insecure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("http://example.com"));
+ insecure_not_schemefully_same.SetSchemefullySameForTesting(false);
EXPECT_EQ(
SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
- "GET", GURL("http://example.com"),
- SiteForCookies::FromUrl(GURL("https://notexample.com")),
- base::nullopt /*initiator*/, false /*attach_same_site_cookies*/));
+ "GET", GURL("http://example.com"), insecure_not_schemefully_same,
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ SiteForCookies secure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("https://example.com"));
+ secure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("https://example.com"), secure_not_schemefully_same,
+ url::Origin::Create(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
- // |attach_same_site_cookies| = true bypasses all checks.
+ // |force_ignore_site_for_cookies| = true bypasses all checks.
EXPECT_EQ(
SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
@@ -511,7 +632,7 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"GET", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /*attach_same_site_cookies*/));
+ true /*force_ignore_site_for_cookies*/));
EXPECT_EQ(
SameSiteCookieContext(
@@ -520,7 +641,7 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"POST", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /*attach_same_site_cookies*/));
+ true /*force_ignore_site_for_cookies*/));
EXPECT_EQ(
SameSiteCookieContext(
@@ -529,7 +650,7 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"GET", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://question.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- true /*attach_same_site_cookies*/));
+ true /*force_ignore_site_for_cookies*/));
EXPECT_EQ(
SameSiteCookieContext(
@@ -538,7 +659,7 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"GET", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(
SameSiteCookieContext(
@@ -547,45 +668,80 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"POST", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
"GET", GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
"POST", GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
"GET", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
"POST", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://example.com")),
url::Origin::Create(GURL("http://example.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
// Normally, lax requests also require a safe method.
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ url::Origin::Create(GURL("http://example.com")),
+ false /*force_ignore_site_for_cookies*/));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ url::Origin::Create(GURL("https://example.com")),
+ false /*force_ignore_site_for_cookies*/));
+
+ // wss/https and http/ws are considered the same for schemeful purposes.
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("wss://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ url::Origin::Create(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("ws://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ url::Origin::Create(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
EXPECT_EQ(
SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
@@ -593,7 +749,7 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"GET", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(
SameSiteCookieContext(
@@ -602,25 +758,45 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"HEAD", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForRequest(
- "GET", GURL("https://example.com"),
- SiteForCookies::FromUrl(GURL("http://example.com")),
- url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ url::Origin::Create(GURL("http://from-elsewhere.com")),
+ false /*force_ignore_site_for_cookies*/));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- cookie_util::ComputeSameSiteContextForRequest(
- "GET", GURL("http://example.com"),
- SiteForCookies::FromUrl(GURL("https://example.com")),
- url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "GET", GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ url::Origin::Create(GURL("http://from-elsewhere.com")),
+ false /*force_ignore_site_for_cookies*/));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "POST", GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ url::Origin::Create(GURL("http://example.com")),
+ false /*force_ignore_site_for_cookies*/));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ cookie_util::ComputeSameSiteContextForRequest(
+ "POST", GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ url::Origin::Create(GURL("https://example.com")),
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(CookieOptions::SameSiteCookieContext::
ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
@@ -628,34 +804,25 @@ TEST(CookieUtilTest, ComputeSameSiteContextForRequest) {
"POST", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
"POST", GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForRequest(
"POST", GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://example.com")),
url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
-
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForRequest(
- "POST", GURL("https://example.com"),
- SiteForCookies::FromUrl(GURL("http://example.com")),
- url::Origin::Create(GURL("http://from-elsewhere.com")),
- false /*attach_same_site_cookies*/));
+ false /*force_ignore_site_for_cookies*/));
}
TEST(CookieUtilTest, ComputeSameSiteContextForSet) {
@@ -665,64 +832,168 @@ TEST(CookieUtilTest, ComputeSameSiteContextForSet) {
cookie_util::ComputeSameSiteContextForResponse(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt, false /* attach_same_site_cookies */));
+ base::nullopt, false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForResponse(
GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- base::nullopt, false /* attach_same_site_cookies */));
+ base::nullopt, false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForResponse(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://notexample.com")),
- base::nullopt, false /* attach_same_site_cookies */));
+ base::nullopt, false /* force_ignore_site_for_cookies */));
- // Same as above except |attach_same_site_cookies| makes it return LAX.
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")), base::nullopt,
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")), base::nullopt,
+ false /* force_ignore_site_for_cookies */));
+
+ // Same as above except |force_ignore_site_for_cookies| makes it return LAX.
EXPECT_EQ(
SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
cookie_util::ComputeSameSiteContextForResponse(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")), base::nullopt,
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")), base::nullopt,
+ true /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")), base::nullopt,
+ true /* force_ignore_site_for_cookies */));
+
+ // |site_for_cookies| not being schemefully_same -> it's cross-site.
+ SiteForCookies insecure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("http://example.com"));
+ insecure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("http://example.com"), insecure_not_schemefully_same,
+ base::nullopt, false /* force_ignore_site_for_cookies */));
+
+ SiteForCookies secure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("https://example.com"));
+ secure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("https://example.com"), secure_not_schemefully_same,
+ base::nullopt, false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForScriptSet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForScriptSet(
GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForScriptSet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("https://notexample.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
- // Same as above except |attach_same_site_cookies| makes it return LAX.
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ // Same as above except |force_ignore_site_for_cookies| makes it return LAX.
EXPECT_EQ(
SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
cookie_util::ComputeSameSiteContextForScriptSet(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ true /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ true /* force_ignore_site_for_cookies */));
+
+ // |site_for_cookies| not being schemefully_same -> it's cross-site.
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("http://example.com"), insecure_not_schemefully_same,
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("https://example.com"), secure_not_schemefully_same,
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -730,42 +1001,58 @@ TEST(CookieUtilTest, ComputeSameSiteContextForSet) {
cookie_util::ComputeSameSiteContextForResponse(
GURL("http://example.com/dir"),
SiteForCookies::FromUrl(GURL("http://sub.example.com")),
- base::nullopt, false /* attach_same_site_cookies */));
+ base::nullopt, false /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
cookie_util::ComputeSameSiteContextForResponse(
GURL("http://example.com/dir"),
SiteForCookies::FromUrl(GURL("http://sub.example.com")),
- base::nullopt, true /* attach_same_site_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- cookie_util::ComputeSameSiteContextForResponse(
- GURL("http://example.com/dir"),
- SiteForCookies::FromUrl(GURL("https://sub.example.com")),
- base::nullopt, false /* attach_same_site_cookies */));
+ base::nullopt, true /* force_ignore_site_for_cookies */));
+
+ // wss/https and http/ws are considered the same for schemeful purposes.
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("ws://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")), base::nullopt,
+ true /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("wss://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")), base::nullopt,
+ true /* force_ignore_site_for_cookies */));
+
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForResponse(
GURL("http://example.com/dir"),
SiteForCookies::FromUrl(GURL("https://sub.example.com")),
- base::nullopt, true /* attach_same_site_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForResponse(
- GURL("https://example.com/dir"),
- SiteForCookies::FromUrl(GURL("http://sub.example.com")),
- base::nullopt, false /* attach_same_site_cookies */));
+ base::nullopt, false /* force_ignore_site_for_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("http://example.com/dir"),
+ SiteForCookies::FromUrl(GURL("https://sub.example.com")),
+ base::nullopt, true /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForResponse(
GURL("https://example.com/dir"),
SiteForCookies::FromUrl(GURL("http://sub.example.com")),
- base::nullopt, true /* attach_same_site_cookies */));
+ base::nullopt, false /* force_ignore_site_for_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForResponse(
+ GURL("https://example.com/dir"),
+ SiteForCookies::FromUrl(GURL("http://sub.example.com")),
+ base::nullopt, true /* force_ignore_site_for_cookies */));
EXPECT_EQ(
SameSiteCookieContext(
@@ -773,21 +1060,35 @@ TEST(CookieUtilTest, ComputeSameSiteContextForSet) {
cookie_util::ComputeSameSiteContextForScriptSet(
GURL("http://example.com/dir"),
SiteForCookies::FromUrl(GURL("http://sub.example.com")),
- false /* attach_same_site_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- cookie_util::ComputeSameSiteContextForScriptSet(
- GURL("http://example.com/dir"),
- SiteForCookies::FromUrl(GURL("https://sub.example.com")),
- false /* attach_same_site_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForScriptSet(
- GURL("https://example.com/dir"),
- SiteForCookies::FromUrl(GURL("http://sub.example.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("ws://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("wss://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("http://example.com/dir"),
+ SiteForCookies::FromUrl(GURL("https://sub.example.com")),
+ false /* force_ignore_site_for_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForScriptSet(
+ GURL("https://example.com/dir"),
+ SiteForCookies::FromUrl(GURL("http://sub.example.com")),
+ false /* force_ignore_site_for_cookies */));
}
TEST(CookieUtilTest, TestComputeSameSiteContextForSubresource) {
@@ -798,62 +1099,116 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForSubresource) {
cookie_util::ComputeSameSiteContextForSubresource(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
- cookie_util::ComputeSameSiteContextForSubresource(
- GURL("https://example.com"),
- SiteForCookies::FromUrl(GURL("http://notexample.com")),
- false /* attach_same_site_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("https://example.com"),
+ SiteForCookies::FromUrl(GURL("http://notexample.com")),
+ false /* force_ignore_site_for_cookies */));
- EXPECT_EQ(SameSiteCookieContext(
- SameSiteCookieContext::ContextType::CROSS_SITE,
- SameSiteCookieContext::CrossSchemeness::SECURE_INSECURE),
- cookie_util::ComputeSameSiteContextForSubresource(
- GURL("http://example.com"),
- SiteForCookies::FromUrl(GURL("https://notexample.com")),
- false /* attach_same_site_cookies */));
+ EXPECT_EQ(
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://notexample.com")),
+ false /* force_ignore_site_for_cookies */));
- // Same as above except |attach_same_site_cookies| makes it return STRICT.
+ // Same as above except |force_ignore_site_for_cookies| makes it return
+ // STRICT.
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
cookie_util::ComputeSameSiteContextForSubresource(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://notexample.com")),
- true /* attach_same_site_cookies */));
+ true /* force_ignore_site_for_cookies */));
+
+ // |site_for_cookies| not being schemefully_same -> it's cross-site.
+ SiteForCookies insecure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("http://example.com"));
+ insecure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("http://example.com"), insecure_not_schemefully_same,
+ false /* force_ignore_site_for_cookies */));
+
+ SiteForCookies secure_not_schemefully_same =
+ SiteForCookies::FromUrl(GURL("https://example.com"));
+ secure_not_schemefully_same.SetSchemefullySameForTesting(false);
+ EXPECT_EQ(
+ SameSiteCookieContext(
+ CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("https://example.com"), secure_not_schemefully_same,
+ false /* force_ignore_site_for_cookies */));
// This isn't a full on origin check --- subdomains and different schema are
- // accepted.
+ // accepted. For SameSiteCookieContext::schemeful_context the scheme is
+ // considered.
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::CrossSchemeness::INSECURE_SECURE),
+ SameSiteCookieContext::ContextType::CROSS_SITE),
cookie_util::ComputeSameSiteContextForSubresource(
GURL("https://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("http://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
cookie_util::ComputeSameSiteContextForSubresource(
GURL("http://sub.example.com"),
SiteForCookies::FromUrl(GURL("http://sub2.example.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
cookie_util::ComputeSameSiteContextForSubresource(
GURL("http://sub.example.com"),
SiteForCookies::FromUrl(GURL("http://sub.example.com:8080")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
EXPECT_EQ(SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
cookie_util::ComputeSameSiteContextForSubresource(
GURL("http://example.com"),
SiteForCookies::FromUrl(GURL("http://example.com")),
- false /* attach_same_site_cookies */));
+ false /* force_ignore_site_for_cookies */));
+
+ // wss/https and http/ws are considered the same for schemeful purposes.
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("ws://example.com"),
+ SiteForCookies::FromUrl(GURL("http://example.com")),
+ false /* force_ignore_site_for_cookies */));
+
+ EXPECT_EQ(SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
+ cookie_util::ComputeSameSiteContextForSubresource(
+ GURL("wss://example.com"),
+ SiteForCookies::FromUrl(GURL("https://example.com")),
+ false /* force_ignore_site_for_cookies */));
}
TEST(CookieUtilTest, AdaptCookieInclusionStatusToBool) {
diff --git a/chromium/net/cookies/parse_cookie_line_fuzzer.cc b/chromium/net/cookies/parse_cookie_line_fuzzer.cc
index e65412f1a82..4ea774ab748 100644
--- a/chromium/net/cookies/parse_cookie_line_fuzzer.cc
+++ b/chromium/net/cookies/parse_cookie_line_fuzzer.cc
@@ -7,7 +7,7 @@
#include <fuzzer/FuzzedDataProvider.h>
-#include "base/logging.h"
+#include "base/check_op.h"
#include "net/cookies/parsed_cookie.h"
const std::string GetArbitraryString(FuzzedDataProvider* data_provider) {
diff --git a/chromium/net/cookies/site_for_cookies.cc b/chromium/net/cookies/site_for_cookies.cc
index 8c152a67943..759b4e7a372 100644
--- a/chromium/net/cookies/site_for_cookies.cc
+++ b/chromium/net/cookies/site_for_cookies.cc
@@ -7,6 +7,7 @@
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "net/cookies/cookie_util.h"
namespace net {
@@ -20,7 +21,7 @@ std::string RegistrableDomainOrHost(const std::string& host) {
} // namespace
-SiteForCookies::SiteForCookies() = default;
+SiteForCookies::SiteForCookies() : schemefully_same_(false) {}
SiteForCookies::SiteForCookies(const SiteForCookies& other) = default;
SiteForCookies::SiteForCookies(SiteForCookies&& other) = default;
@@ -35,6 +36,7 @@ SiteForCookies& SiteForCookies::operator=(SiteForCookies&& site_for_cookies) =
// static
bool SiteForCookies::FromWire(const std::string& scheme,
const std::string& registrable_domain,
+ bool schemefully_same,
SiteForCookies* out) {
// Make sure scheme meets precondition of methods like
// GURL::SchemeIsCryptographic.
@@ -46,6 +48,8 @@ bool SiteForCookies::FromWire(const std::string& scheme,
if (registrable_domain != candidate.registrable_domain_)
return false;
+ candidate.schemefully_same_ = schemefully_same;
+
*out = std::move(candidate);
return true;
}
@@ -65,25 +69,34 @@ SiteForCookies SiteForCookies::FromUrl(const GURL& url) {
}
std::string SiteForCookies::ToDebugString() const {
+ std::string same_scheme_string = schemefully_same_ ? "true" : "false";
return base::StrCat({"SiteForCookies: {scheme=", scheme_,
- "; registrable_domain=", registrable_domain_, "}"});
+ "; registrable_domain=", registrable_domain_,
+ "; schemefully_same=", same_scheme_string, "}"});
}
bool SiteForCookies::IsFirstParty(const GURL& url) const {
- if (scheme_.empty() || !url.is_valid())
- return false;
-
- std::string other_registrable_domain = RegistrableDomainOrHost(url.host());
+ return IsFirstPartyWithSchemefulMode(
+ url, cookie_util::IsSchemefulSameSiteEnabled());
+}
- if (registrable_domain_.empty())
- return other_registrable_domain.empty() && (scheme_ == url.scheme());
+bool SiteForCookies::IsFirstPartyWithSchemefulMode(
+ const GURL& url,
+ bool compute_schemefully) const {
+ if (compute_schemefully)
+ return IsSchemefullyFirstParty(url);
- return registrable_domain_ == other_registrable_domain;
+ return IsSchemelesslyFirstParty(url);
}
bool SiteForCookies::IsEquivalent(const SiteForCookies& other) const {
- if (scheme_.empty())
- return other.scheme_.empty();
+ if (IsNull())
+ return other.IsNull();
+
+ if (cookie_util::IsSchemefulSameSiteEnabled() &&
+ !CompatibleScheme(other.scheme())) {
+ return false;
+ }
if (registrable_domain_.empty())
return other.registrable_domain_.empty() && (scheme_ == other.scheme_);
@@ -91,16 +104,91 @@ bool SiteForCookies::IsEquivalent(const SiteForCookies& other) const {
return registrable_domain_ == other.registrable_domain_;
}
+void SiteForCookies::MarkIfCrossScheme(const url::Origin& other) {
+ // If |this| is IsNull() then |this| doesn't match anything which means that
+ // the scheme check is pointless. Also exit early if schemefully_same_ is
+ // already false.
+ if (IsNull() || !schemefully_same_)
+ return;
+
+ // Mark if |other| is opaque. Opaque origins shouldn't match.
+ if (other.opaque()) {
+ schemefully_same_ = false;
+ return;
+ }
+
+ if (CompatibleScheme(other.scheme()))
+ return;
+
+ // The two are cross-scheme to each other.
+ schemefully_same_ = false;
+}
+
GURL SiteForCookies::RepresentativeUrl() const {
- if (scheme_.empty())
+ if (IsNull())
return GURL();
GURL result(base::StrCat({scheme_, "://", registrable_domain_, "/"}));
DCHECK(result.is_valid());
return result;
}
+bool SiteForCookies::IsNull() const {
+ if (cookie_util::IsSchemefulSameSiteEnabled())
+ return scheme_.empty() || !schemefully_same_;
+
+ return scheme_.empty();
+}
+
SiteForCookies::SiteForCookies(const std::string& scheme,
const std::string& host)
- : scheme_(scheme), registrable_domain_(RegistrableDomainOrHost(host)) {}
+ : scheme_(scheme),
+ registrable_domain_(RegistrableDomainOrHost(host)),
+ schemefully_same_(!scheme.empty()) {}
+
+bool SiteForCookies::CompatibleScheme(const std::string& other_scheme) const {
+ DCHECK(base::IsStringASCII(other_scheme));
+ DCHECK(base::ToLowerASCII(other_scheme) == other_scheme);
+
+ // Exact match case.
+ if (scheme_ == other_scheme)
+ return true;
+
+ // ["https", "wss"] case.
+ if ((scheme_ == url::kHttpsScheme || scheme_ == url::kWssScheme) &&
+ (other_scheme == url::kHttpsScheme || other_scheme == url::kWssScheme)) {
+ return true;
+ }
+
+ // ["http", "ws"] case.
+ if ((scheme_ == url::kHttpScheme || scheme_ == url::kWsScheme) &&
+ (other_scheme == url::kHttpScheme || other_scheme == url::kWsScheme)) {
+ return true;
+ }
+
+ return false;
+}
+
+bool SiteForCookies::IsSchemefullyFirstParty(const GURL& url) const {
+ // Can't use IsNull() as we want the same behavior regardless of
+ // SchemefulSameSite feature status.
+ if (scheme_.empty() || !schemefully_same_ || !url.is_valid())
+ return false;
+
+ return CompatibleScheme(url.scheme()) && IsSchemelesslyFirstParty(url);
+}
+
+bool SiteForCookies::IsSchemelesslyFirstParty(const GURL& url) const {
+ // Can't use IsNull() as we want the same behavior regardless of
+ // SchemefulSameSite feature status.
+ if (scheme_.empty() || !url.is_valid())
+ return false;
+
+ std::string other_registrable_domain = RegistrableDomainOrHost(url.host());
+
+ if (registrable_domain_.empty())
+ return other_registrable_domain.empty() && (scheme_ == url.scheme());
+
+ return registrable_domain_ == other_registrable_domain;
+}
} // namespace net
diff --git a/chromium/net/cookies/site_for_cookies.h b/chromium/net/cookies/site_for_cookies.h
index 680a9a16330..0de33fabeba 100644
--- a/chromium/net/cookies/site_for_cookies.h
+++ b/chromium/net/cookies/site_for_cookies.h
@@ -23,12 +23,13 @@ namespace net {
// 2) They both have empty hostnames and equal schemes.
// Invalid URLs are not first party to anything.
//
-// TODO(morlovich): It may make sense to require scheme to match in case (1)
-// too, where the notion of matching makes http/https/ws/wss equivalent, but
-// all other schemes are distinct.
-//
-// This should wait until SiteForCookies type is used everywhere relevant, so
-// any changes are consistent.
+// With the SchemefulSameSite feature enabled the policy is that two valid URLs
+// would be considered the same party if either:
+// 1) They both have compatible schemes along with non-empty and equal
+// registrable domains or hostnames/IPs. See CompatibleScheme() for more details
+// on what it means to have a compatible scheme.
+// 2) They both have empty hostnames and exactly equal schemes. Invalid URLs are
+// not first party to anything.
class NET_EXPORT SiteForCookies {
public:
// Matches nothing.
@@ -50,6 +51,7 @@ class NET_EXPORT SiteForCookies {
// did not lie, merely that they are well-formed.
static bool FromWire(const std::string& scheme,
const std::string& registrable_domain,
+ bool schemefully_same,
SiteForCookies* out);
// If the origin is opaque, returns SiteForCookies that matches nothing.
@@ -61,16 +63,39 @@ class NET_EXPORT SiteForCookies {
// Equivalent to FromOrigin(url::Origin::Create(url)).
static SiteForCookies FromUrl(const GURL& url);
+ // Returns a string with the values of the member variables.
+ // |schemefully_same| being false does not change the output.
std::string ToDebugString() const;
// Returns true if |url| should be considered first-party to the context
// |this| represents.
bool IsFirstParty(const GURL& url) const;
+ // Don't use this function unless you know what you're doing, if you're unsure
+ // you probably want IsFirstParty().
+ //
+ // If |compute_schemefully| is true this function will return true if |url|
+ // should be considered first-party to the context |this| represents when the
+ // compatibility of the schemes are taken into account.
+ //
+ // If |compute_schemefully| is false this function will return true if |url|
+ // should be considered first-party to the context |this| represents when the
+ // compatibility of the scheme are not taken into account. Note that schemes
+ // are still compared for exact equality if neither |this| nor |url| have a
+ // registered domain.
+ //
+ // See CompatibleScheme() for more information on scheme compatibility.
+ bool IsFirstPartyWithSchemefulMode(const GURL& url,
+ bool compute_schemefully) const;
+
// Returns true if |other.IsFirstParty()| is true for exactly the same URLs
// as |this->IsFirstParty| (potentially none).
bool IsEquivalent(const SiteForCookies& other) const;
+ // Clears the schemefully_same_ flag if |other|'s scheme is cross-scheme to
+ // |this|. Schemes are considered cross-scheme if they're !CompatibleScheme().
+ void MarkIfCrossScheme(const url::Origin& other);
+
// Returns a URL that's first party to this SiteForCookies (an empty URL if
// none) --- that is, it has the property that
// site_for_cookies.IsEquivalent(
@@ -87,12 +112,30 @@ class NET_EXPORT SiteForCookies {
const std::string& registrable_domain() const { return registrable_domain_; }
+ // Used for serialization/deserialization. This value is irrelevant if
+ // IsNull() is true.
+ bool schemefully_same() const { return schemefully_same_; }
+
+ void SetSchemefullySameForTesting(bool schemefully_same) {
+ schemefully_same_ = schemefully_same;
+ }
+
// Returns true if this SiteForCookies matches nothing.
- bool IsNull() const { return scheme_.empty(); }
+ // If the SchemefulSameSite feature is enabled then !schemefully_same_ causes
+ // this function to return true.
+ bool IsNull() const;
private:
SiteForCookies(const std::string& scheme, const std::string& host);
+ // Two schemes are considered compatible if they exactly match, they are both
+ // in ["https", "wss"], or they are both in ["http", "ws"].
+ bool CompatibleScheme(const std::string& other_scheme) const;
+
+ bool IsSchemefullyFirstParty(const GURL& url) const;
+
+ bool IsSchemelesslyFirstParty(const GURL& url) const;
+
// These should be canonicalized appropriately by GURL/url::Origin.
// An empty |scheme_| means that this matches nothing.
std::string scheme_;
@@ -102,6 +145,23 @@ class NET_EXPORT SiteForCookies {
// just the bare hostname or IP, or an empty string if this represents
// something like file:///
std::string registrable_domain_;
+
+ // Used to indicate if the SiteForCookies would be the same if computed
+ // schemefully. A schemeful computation means to take the |scheme_| as well as
+ // the |registrable_domain_| into account when determining first-partyness.
+ // See CompatibleScheme() for more information on scheme comparison.
+ //
+ // True means to treat |this| as-is while false means that |this| should be
+ // treated as if it matches nothing i.e. IsNull() returns true.
+ //
+ // This value is important in the case where the SiteForCookies is being used
+ // to assess the first-partyness of a sub-frame in a document.
+ //
+ // For a SiteForCookies with !scheme_.empty() this value starts as true and
+ // will only go false via MarkIfCrossScheme(), otherwise this value is
+ // irrelevant (For tests this value can also be modified by
+ // SetSchemefullySameForTesting()).
+ bool schemefully_same_;
};
} // namespace net
diff --git a/chromium/net/cookies/site_for_cookies_unittest.cc b/chromium/net/cookies/site_for_cookies_unittest.cc
index 3583f1a744e..640b9987628 100644
--- a/chromium/net/cookies/site_for_cookies_unittest.cc
+++ b/chromium/net/cookies/site_for_cookies_unittest.cc
@@ -7,6 +7,8 @@
#include <vector>
#include "base/strings/strcat.h"
+#include "base/test/scoped_feature_list.h"
+#include "net/base/features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -15,6 +17,16 @@
namespace net {
namespace {
+class SchemefulSiteForCookiesTest : public ::testing::Test {
+ public:
+ SchemefulSiteForCookiesTest() {
+ scope_feature_list_.InitAndEnableFeature(features::kSchemefulSameSite);
+ }
+
+ protected:
+ base::test::ScopedFeatureList scope_feature_list_;
+};
+
// Tests that all URLs from |equivalent| produce SiteForCookies that match
// URLs in the set and are equivalent to each other, and are distinct and
// don't match |distinct|.
@@ -70,8 +82,9 @@ TEST(SiteForCookiesTest, Default) {
SiteForCookies::FromOrigin(url::Origin())));
EXPECT_EQ("", should_match_none.scheme());
- EXPECT_EQ("SiteForCookies: {scheme=; registrable_domain=}",
- should_match_none.ToDebugString());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=; registrable_domain=; schemefully_same=false}",
+ should_match_none.ToDebugString());
}
TEST(SiteForCookiesTest, Basic) {
@@ -89,6 +102,38 @@ TEST(SiteForCookiesTest, Basic) {
TestEquivalentAndDistinct(equivalent, distinct, "example.com");
}
+// Similar to SiteForCookiesTest_Basic with a focus on testing secure SFCs.
+TEST_F(SchemefulSiteForCookiesTest, BasicSecure) {
+ std::vector<GURL> equivalent = {GURL("https://example.com"),
+ GURL("wss://example.com"),
+ GURL("https://sub1.example.com:42/something"),
+ GURL("wss://sub2.example.com/something")};
+
+ std::vector<GURL> distinct = {
+ GURL("http://example.com"), GURL("https://example.org"),
+ GURL("ws://example.com"), GURL("https://com/i_am_a_tld"),
+ GURL("file://example.com/helo"),
+ };
+
+ TestEquivalentAndDistinct(equivalent, distinct, "example.com");
+}
+
+// Similar to SiteForCookiesTest_Basic with a focus on testing insecure SFCs.
+TEST_F(SchemefulSiteForCookiesTest, BasicInsecure) {
+ std::vector<GURL> equivalent = {GURL("http://example.com"),
+ GURL("ws://example.com"),
+ GURL("http://sub1.example.com:42/something"),
+ GURL("ws://sub2.example.com/something")};
+
+ std::vector<GURL> distinct = {
+ GURL("https://example.com"), GURL("http://example.org"),
+ GURL("wss://example.com"), GURL("http://com/i_am_a_tld"),
+ GURL("file://example.com/helo"),
+ };
+
+ TestEquivalentAndDistinct(equivalent, distinct, "example.com");
+}
+
TEST(SiteForCookiesTest, File) {
std::vector<GURL> equivalent = {GURL("file:///a/b/c"),
GURL("file:///etc/shaaadow")};
@@ -103,6 +148,7 @@ TEST(SiteForCookiesTest, Extension) {
url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
std::vector<GURL> equivalent = {GURL("chrome-extension://abc/"),
GURL("chrome-extension://abc/foo.txt"),
+ GURL("https://abc"), GURL("http://abc"),
// This one is disputable.
GURL("file://abc/bar.txt")};
@@ -111,6 +157,23 @@ TEST(SiteForCookiesTest, Extension) {
TestEquivalentAndDistinct(equivalent, distinct, "abc");
}
+// Similar to SiteForCookiesTest_Extension with a focus on ensuring that http(s)
+// schemes are distinct.
+TEST_F(SchemefulSiteForCookiesTest, Extension) {
+ url::ScopedSchemeRegistryForTests scoped_registry;
+ url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
+ std::vector<GURL> equivalent = {
+ GURL("chrome-extension://abc/"),
+ GURL("chrome-extension://abc/foo.txt"),
+ };
+
+ std::vector<GURL> distinct = {GURL("chrome-extension://def"),
+ GURL("https://abc"), GURL("http://abc"),
+ GURL("file://abc/bar.txt")};
+
+ TestEquivalentAndDistinct(equivalent, distinct, "abc");
+}
+
TEST(SiteForCookiesTest, NonStandard) {
// If we don't register the scheme, nothing matches, even identical ones
std::vector<GURL> equivalent;
@@ -134,39 +197,210 @@ TEST(SiteForCookiesTest, Blob) {
EXPECT_TRUE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
EXPECT_EQ("https", from_blob.scheme());
- EXPECT_EQ("SiteForCookies: {scheme=https; registrable_domain=example.org}",
- from_blob.ToDebugString());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=https; registrable_domain=example.org; "
+ "schemefully_same=true}",
+ from_blob.ToDebugString());
EXPECT_EQ("https://example.org/", from_blob.RepresentativeUrl().spec());
EXPECT_TRUE(from_blob.IsEquivalent(
SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
}
+// Similar to SiteForCookiesTest_Blob with a focus on a secure blob.
+TEST_F(SchemefulSiteForCookiesTest, SecureBlob) {
+ SiteForCookies from_blob = SiteForCookies::FromUrl(
+ GURL("blob:https://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
+
+ EXPECT_TRUE(from_blob.IsFirstParty(GURL("https://sub.example.org/resource")));
+ EXPECT_FALSE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
+ EXPECT_EQ("https", from_blob.scheme());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=https; registrable_domain=example.org; "
+ "schemefully_same=true}",
+ from_blob.ToDebugString());
+ EXPECT_EQ("https://example.org/", from_blob.RepresentativeUrl().spec());
+ EXPECT_TRUE(from_blob.IsEquivalent(
+ SiteForCookies::FromUrl(GURL("https://www.example.org:631"))));
+ EXPECT_FALSE(from_blob.IsEquivalent(
+ SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
+}
+
+// Similar to SiteForCookiesTest_Blob with a focus on an insecure blob.
+TEST_F(SchemefulSiteForCookiesTest, InsecureBlob) {
+ SiteForCookies from_blob = SiteForCookies::FromUrl(
+ GURL("blob:http://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
+
+ EXPECT_TRUE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
+ EXPECT_FALSE(
+ from_blob.IsFirstParty(GURL("https://sub.example.org/resource")));
+ EXPECT_EQ("http", from_blob.scheme());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=http; registrable_domain=example.org; "
+ "schemefully_same=true}",
+ from_blob.ToDebugString());
+ EXPECT_EQ("http://example.org/", from_blob.RepresentativeUrl().spec());
+ EXPECT_TRUE(from_blob.IsEquivalent(
+ SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
+ EXPECT_FALSE(from_blob.IsEquivalent(
+ SiteForCookies::FromUrl(GURL("https://www.example.org:631"))));
+}
+
TEST(SiteForCookiesTest, Wire) {
SiteForCookies out;
// Empty one.
- EXPECT_TRUE(SiteForCookies::FromWire("", "", &out));
+ EXPECT_TRUE(SiteForCookies::FromWire("", "", false, &out));
+ EXPECT_TRUE(out.IsNull());
+
+ EXPECT_TRUE(SiteForCookies::FromWire("", "", true, &out));
EXPECT_TRUE(out.IsNull());
// Not a valid scheme.
- EXPECT_FALSE(SiteForCookies::FromWire("aH", "example.com", &out));
+ EXPECT_FALSE(SiteForCookies::FromWire("aH", "example.com", false, &out));
EXPECT_TRUE(out.IsNull());
// Not a eTLD + 1 (or something hosty).
- EXPECT_FALSE(SiteForCookies::FromWire("http", "sub.example.com", &out));
+ EXPECT_FALSE(
+ SiteForCookies::FromWire("http", "sub.example.com", false, &out));
EXPECT_TRUE(out.IsNull());
// This is fine, though.
- EXPECT_TRUE(SiteForCookies::FromWire("https", "127.0.0.1", &out));
+ EXPECT_TRUE(SiteForCookies::FromWire("https", "127.0.0.1", true, &out));
EXPECT_FALSE(out.IsNull());
- EXPECT_EQ("SiteForCookies: {scheme=https; registrable_domain=127.0.0.1}",
- out.ToDebugString());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=https; registrable_domain=127.0.0.1; "
+ "schemefully_same=true}",
+ out.ToDebugString());
+
+ EXPECT_TRUE(SiteForCookies::FromWire("https", "127.0.0.1", false, &out));
+ EXPECT_FALSE(out.IsNull());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=https; registrable_domain=127.0.0.1; "
+ "schemefully_same=false}",
+ out.ToDebugString());
// As is actual eTLD+1.
- EXPECT_TRUE(SiteForCookies::FromWire("wss", "example.com", &out));
+ EXPECT_TRUE(SiteForCookies::FromWire("wss", "example.com", true, &out));
EXPECT_FALSE(out.IsNull());
- EXPECT_EQ("SiteForCookies: {scheme=wss; registrable_domain=example.com}",
- out.ToDebugString());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=wss; registrable_domain=example.com; "
+ "schemefully_same=true}",
+ out.ToDebugString());
+}
+
+// Similar to SiteForCookiesTest_Wire except that schemefully_same has an
+// effect.
+TEST_F(SchemefulSiteForCookiesTest, Wire) {
+ SiteForCookies out;
+
+ // Empty one.
+ EXPECT_TRUE(SiteForCookies::FromWire("", "", false, &out));
+ EXPECT_TRUE(out.IsNull());
+
+ EXPECT_TRUE(SiteForCookies::FromWire("", "", true, &out));
+ EXPECT_TRUE(out.IsNull());
+
+ // Not a valid scheme.
+ EXPECT_FALSE(SiteForCookies::FromWire("aH", "example.com", false, &out));
+ EXPECT_TRUE(out.IsNull());
+
+ // Not a eTLD + 1 (or something hosty).
+ EXPECT_FALSE(
+ SiteForCookies::FromWire("http", "sub.example.com", false, &out));
+ EXPECT_TRUE(out.IsNull());
+
+ // This is fine, though.
+ EXPECT_TRUE(SiteForCookies::FromWire("https", "127.0.0.1", true, &out));
+ EXPECT_FALSE(out.IsNull());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=https; registrable_domain=127.0.0.1; "
+ "schemefully_same=true}",
+ out.ToDebugString());
+
+ // This one's schemefully_same is false
+ EXPECT_TRUE(SiteForCookies::FromWire("https", "127.0.0.1", false, &out));
+ EXPECT_TRUE(out.IsNull());
+
+ // As is actual eTLD+1.
+ EXPECT_TRUE(SiteForCookies::FromWire("wss", "example.com", true, &out));
+ EXPECT_FALSE(out.IsNull());
+ EXPECT_EQ(
+ "SiteForCookies: {scheme=wss; registrable_domain=example.com; "
+ "schemefully_same=true}",
+ out.ToDebugString());
+}
+
+TEST(SiteForCookiesTest, SameScheme) {
+ struct TestCase {
+ const char* first;
+ const char* second;
+ bool expected_value;
+ };
+
+ const TestCase kTestCases[] = {
+ {"http://a.com", "http://a.com", true},
+ {"https://a.com", "https://a.com", true},
+ {"ws://a.com", "ws://a.com", true},
+ {"wss://a.com", "wss://a.com", true},
+ {"https://a.com", "wss://a.com", true},
+ {"wss://a.com", "https://a.com", true},
+ {"http://a.com", "ws://a.com", true},
+ {"ws://a.com", "http://a.com", true},
+ {"file://a.com", "file://a.com", true},
+ {"file://folder1/folder2/file.txt", "file://folder1/folder2/file.txt",
+ true},
+ {"ftp://a.com", "ftp://a.com", true},
+ {"http://a.com", "file://a.com", false},
+ {"ws://a.com", "wss://a.com", false},
+ {"wss://a.com", "ws://a.com", false},
+ {"https://a.com", "http://a.com", false},
+ {"file://a.com", "https://a.com", false},
+ {"https://a.com", "file://a.com", false},
+ {"file://a.com", "ftp://a.com", false},
+ {"ftp://a.com", "file://a.com", false},
+ };
+
+ for (const TestCase& t : kTestCases) {
+ SiteForCookies first = SiteForCookies::FromUrl(GURL(t.first));
+ url::Origin second = url::Origin::Create(GURL(t.second));
+ EXPECT_FALSE(first.IsNull());
+ first.MarkIfCrossScheme(second);
+ EXPECT_EQ(first.schemefully_same(), t.expected_value);
+ }
+}
+
+TEST(SiteForCookiesTest, SameSchemeOpaque) {
+ url::Origin not_opaque_secure =
+ url::Origin::Create(GURL("https://site.example"));
+ url::Origin not_opaque_nonsecure =
+ url::Origin::Create(GURL("http://site.example"));
+ // Check an opaque origin made from a triple origin and one from the default
+ // constructor.
+ const url::Origin kOpaqueOrigins[] = {
+ not_opaque_secure.DeriveNewOpaqueOrigin(),
+ not_opaque_nonsecure.DeriveNewOpaqueOrigin(), url::Origin()};
+
+ for (const url::Origin& origin : kOpaqueOrigins) {
+ SiteForCookies secure_sfc = SiteForCookies::FromOrigin(not_opaque_secure);
+ EXPECT_FALSE(secure_sfc.IsNull());
+ SiteForCookies nonsecure_sfc =
+ SiteForCookies::FromOrigin(not_opaque_nonsecure);
+ EXPECT_FALSE(nonsecure_sfc.IsNull());
+
+ EXPECT_TRUE(secure_sfc.schemefully_same());
+ secure_sfc.MarkIfCrossScheme(origin);
+ EXPECT_FALSE(secure_sfc.schemefully_same());
+
+ EXPECT_TRUE(nonsecure_sfc.schemefully_same());
+ nonsecure_sfc.MarkIfCrossScheme(origin);
+ EXPECT_FALSE(nonsecure_sfc.schemefully_same());
+
+ SiteForCookies opaque_sfc = SiteForCookies::FromOrigin(origin);
+ EXPECT_TRUE(opaque_sfc.IsNull());
+ // Slightly implementation detail specific as the value isn't relevant for
+ // null SFCs.
+ EXPECT_FALSE(nonsecure_sfc.schemefully_same());
+ }
}
} // namespace
diff --git a/chromium/net/cookies/static_cookie_policy.cc b/chromium/net/cookies/static_cookie_policy.cc
index 25c6e411826..96a45759a5f 100644
--- a/chromium/net/cookies/static_cookie_policy.cc
+++ b/chromium/net/cookies/static_cookie_policy.cc
@@ -4,7 +4,7 @@
#include "net/cookies/static_cookie_policy.h"
-#include "base/logging.h"
+#include "base/notreached.h"
#include "net/base/net_errors.h"
#include "net/cookies/site_for_cookies.h"
#include "url/gurl.h"
diff --git a/chromium/net/cookies/test_cookie_access_delegate.cc b/chromium/net/cookies/test_cookie_access_delegate.cc
index 41893830adb..78750a8152e 100644
--- a/chromium/net/cookies/test_cookie_access_delegate.cc
+++ b/chromium/net/cookies/test_cookie_access_delegate.cc
@@ -48,7 +48,7 @@ void TestCookieAccessDelegate::SetIgnoreSameSiteRestrictionsScheme(
std::string TestCookieAccessDelegate::GetKeyForDomainValue(
const std::string& domain) const {
DCHECK(!domain.empty());
- return domain[0] == '.' ? domain.substr(1) : domain;
+ return cookie_util::CookieDomainAsHost(domain);
}
} // namespace net