summaryrefslogtreecommitdiff
path: root/chromium/net/cookies/cookie_inclusion_status.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/cookies/cookie_inclusion_status.cc')
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.cc290
1 files changed, 290 insertions, 0 deletions
diff --git a/chromium/net/cookies/cookie_inclusion_status.cc b/chromium/net/cookies/cookie_inclusion_status.cc
new file mode 100644
index 00000000000..8e13916ba13
--- /dev/null
+++ b/chromium/net/cookies/cookie_inclusion_status.cc
@@ -0,0 +1,290 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cookies/cookie_inclusion_status.h"
+
+#include "base/strings/strcat.h"
+#include "url/gurl.h"
+
+namespace net {
+
+namespace {
+
+uint32_t GetExclusionBitmask(CookieInclusionStatus::ExclusionReason reason) {
+ return 1u << static_cast<uint32_t>(reason);
+}
+
+uint32_t GetWarningBitmask(CookieInclusionStatus::WarningReason reason) {
+ return 1u << static_cast<uint32_t>(reason);
+}
+
+} // namespace
+
+CookieInclusionStatus::CookieInclusionStatus()
+ : exclusion_reasons_(0u), warning_reasons_(0u) {}
+
+CookieInclusionStatus::CookieInclusionStatus(ExclusionReason reason)
+ : exclusion_reasons_(GetExclusionBitmask(reason)) {}
+
+CookieInclusionStatus::CookieInclusionStatus(ExclusionReason reason,
+ WarningReason warning)
+ : exclusion_reasons_(GetExclusionBitmask(reason)),
+ warning_reasons_(GetWarningBitmask(warning)) {}
+
+bool CookieInclusionStatus::operator==(
+ const CookieInclusionStatus& other) const {
+ return exclusion_reasons_ == other.exclusion_reasons_ &&
+ warning_reasons_ == other.warning_reasons_;
+}
+
+bool CookieInclusionStatus::operator!=(
+ const CookieInclusionStatus& other) const {
+ return !operator==(other);
+}
+
+bool CookieInclusionStatus::IsInclude() const {
+ return exclusion_reasons_ == 0u;
+}
+
+bool CookieInclusionStatus::HasExclusionReason(ExclusionReason reason) const {
+ return exclusion_reasons_ & GetExclusionBitmask(reason);
+}
+
+void CookieInclusionStatus::AddExclusionReason(ExclusionReason reason) {
+ exclusion_reasons_ |= GetExclusionBitmask(reason);
+ // If the cookie would be excluded for reasons other than the new SameSite
+ // rules, don't bother warning about it.
+ MaybeClearSameSiteWarning();
+}
+
+void CookieInclusionStatus::RemoveExclusionReason(ExclusionReason reason) {
+ exclusion_reasons_ &= ~(GetExclusionBitmask(reason));
+}
+
+void CookieInclusionStatus::MaybeClearSameSiteWarning() {
+ uint32_t samesite_reasons_mask =
+ GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_NONE_INSECURE);
+ if (exclusion_reasons_ & ~samesite_reasons_mask) {
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ RemoveWarningReason(CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
+ RemoveWarningReason(
+ 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(
+ CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
+ }
+}
+
+bool 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 CookieInclusionStatus::ShouldWarn() const {
+ return warning_reasons_ != 0u;
+}
+
+bool CookieInclusionStatus::HasWarningReason(WarningReason reason) const {
+ return warning_reasons_ & GetWarningBitmask(reason);
+}
+
+bool CookieInclusionStatus::HasDowngradeWarning(
+ CookieInclusionStatus::WarningReason* reason) const {
+ if (!ShouldWarn())
+ return false;
+
+ 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;
+}
+
+void CookieInclusionStatus::AddWarningReason(WarningReason reason) {
+ warning_reasons_ |= GetWarningBitmask(reason);
+}
+
+void CookieInclusionStatus::RemoveWarningReason(WarningReason reason) {
+ warning_reasons_ &= ~(GetWarningBitmask(reason));
+}
+
+CookieInclusionStatus::ContextDowngradeMetricValues
+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 CookieInclusionStatus::GetDebugString() const {
+ std::string out;
+
+ // Inclusion/exclusion
+ if (IsInclude())
+ base::StrAppend(&out, {"INCLUDE, "});
+ if (HasExclusionReason(EXCLUDE_UNKNOWN_ERROR))
+ base::StrAppend(&out, {"EXCLUDE_UNKNOWN_ERROR, "});
+ if (HasExclusionReason(EXCLUDE_HTTP_ONLY))
+ base::StrAppend(&out, {"EXCLUDE_HTTP_ONLY, "});
+ if (HasExclusionReason(EXCLUDE_SECURE_ONLY))
+ base::StrAppend(&out, {"EXCLUDE_SECURE_ONLY, "});
+ if (HasExclusionReason(EXCLUDE_DOMAIN_MISMATCH))
+ base::StrAppend(&out, {"EXCLUDE_DOMAIN_MISMATCH, "});
+ if (HasExclusionReason(EXCLUDE_NOT_ON_PATH))
+ base::StrAppend(&out, {"EXCLUDE_NOT_ON_PATH, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_STRICT))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_STRICT, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_LAX))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_LAX, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_NONE_INSECURE))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_NONE_INSECURE, "});
+ if (HasExclusionReason(EXCLUDE_USER_PREFERENCES))
+ base::StrAppend(&out, {"EXCLUDE_USER_PREFERENCES, "});
+ if (HasExclusionReason(EXCLUDE_FAILURE_TO_STORE))
+ base::StrAppend(&out, {"EXCLUDE_FAILURE_TO_STORE, "});
+ if (HasExclusionReason(EXCLUDE_NONCOOKIEABLE_SCHEME))
+ base::StrAppend(&out, {"EXCLUDE_NONCOOKIEABLE_SCHEME, "});
+ if (HasExclusionReason(EXCLUDE_OVERWRITE_SECURE))
+ base::StrAppend(&out, {"EXCLUDE_OVERWRITE_SECURE, "});
+ if (HasExclusionReason(EXCLUDE_OVERWRITE_HTTP_ONLY))
+ base::StrAppend(&out, {"EXCLUDE_OVERWRITE_HTTP_ONLY, "});
+ if (HasExclusionReason(EXCLUDE_INVALID_DOMAIN))
+ base::StrAppend(&out, {"EXCLUDE_INVALID_DOMAIN, "});
+ if (HasExclusionReason(EXCLUDE_INVALID_PREFIX))
+ base::StrAppend(&out, {"EXCLUDE_INVALID_PREFIX, "});
+
+ // Add warning
+ if (!ShouldWarn()) {
+ base::StrAppend(&out, {"DO_NOT_WARN"});
+ return out;
+ }
+
+ if (HasWarningReason(WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT))
+ base::StrAppend(&out, {"WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT, "});
+ if (HasWarningReason(WARN_SAMESITE_NONE_INSECURE))
+ 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_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, "});
+ if (HasWarningReason(WARN_SAMESITE_COMPAT_PAIR))
+ base::StrAppend(&out, {"WARN_SAMESITE_COMPAT_PAIR, "});
+
+ // Strip trailing comma and space.
+ out.erase(out.end() - 2, out.end());
+
+ return out;
+}
+
+bool CookieInclusionStatus::IsValid() const {
+ // Bit positions where there should not be any true bits.
+ uint32_t exclusion_mask = ~0u << static_cast<int>(NUM_EXCLUSION_REASONS);
+ uint32_t warning_mask = ~0u << static_cast<int>(NUM_WARNING_REASONS);
+ return (exclusion_mask & exclusion_reasons_) == 0u &&
+ (warning_mask & warning_reasons_) == 0u;
+}
+
+bool CookieInclusionStatus::HasExactlyExclusionReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason> reasons) const {
+ CookieInclusionStatus expected = MakeFromReasonsForTesting(reasons);
+ return expected.exclusion_reasons_ == exclusion_reasons_;
+}
+
+bool CookieInclusionStatus::HasExactlyWarningReasonsForTesting(
+ std::vector<WarningReason> reasons) const {
+ CookieInclusionStatus expected = MakeFromReasonsForTesting({}, reasons);
+ return expected.warning_reasons_ == warning_reasons_;
+}
+
+// static
+CookieInclusionStatus CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<ExclusionReason> reasons,
+ std::vector<WarningReason> warnings) {
+ CookieInclusionStatus status;
+ for (ExclusionReason reason : reasons) {
+ status.AddExclusionReason(reason);
+ }
+ for (WarningReason warning : warnings) {
+ status.AddWarningReason(warning);
+ }
+ return status;
+}
+
+} // namespace net