cookie_partition_key.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/cookies/cookie_partition_key.h"
  5. #include <ostream>
  6. #include <tuple>
  7. #include "base/feature_list.h"
  8. #include "base/logging.h"
  9. #include "base/stl_util.h"
  10. #include "net/base/features.h"
  11. #include "net/cookies/cookie_constants.h"
  12. namespace net {
  13. CookiePartitionKey::CookiePartitionKey() = default;
  14. CookiePartitionKey::CookiePartitionKey(
  15. const SchemefulSite& site,
  16. absl::optional<base::UnguessableToken> nonce)
  17. : site_(site), nonce_(nonce) {}
  18. CookiePartitionKey::CookiePartitionKey(const GURL& url)
  19. : site_(SchemefulSite(url)) {}
  20. CookiePartitionKey::CookiePartitionKey(bool from_script)
  21. : from_script_(from_script) {}
  22. CookiePartitionKey::CookiePartitionKey(const CookiePartitionKey& other) =
  23. default;
  24. CookiePartitionKey::CookiePartitionKey(CookiePartitionKey&& other) = default;
  25. CookiePartitionKey& CookiePartitionKey::operator=(
  26. const CookiePartitionKey& other) = default;
  27. CookiePartitionKey& CookiePartitionKey::operator=(CookiePartitionKey&& other) =
  28. default;
  29. CookiePartitionKey::~CookiePartitionKey() = default;
  30. bool CookiePartitionKey::operator==(const CookiePartitionKey& other) const {
  31. return site_ == other.site_ && nonce_ == other.nonce_;
  32. }
  33. bool CookiePartitionKey::operator!=(const CookiePartitionKey& other) const {
  34. return site_ != other.site_ || nonce_ != other.nonce_;
  35. }
  36. bool CookiePartitionKey::operator<(const CookiePartitionKey& other) const {
  37. return std::tie(site_, nonce_) < std::tie(other.site_, other.nonce_);
  38. }
  39. // static
  40. bool CookiePartitionKey::Serialize(const absl::optional<CookiePartitionKey>& in,
  41. std::string& out) {
  42. if (!in) {
  43. out = kEmptyCookiePartitionKey;
  44. return true;
  45. }
  46. if (!in->IsSerializeable()) {
  47. DLOG(WARNING) << "CookiePartitionKey is not serializeable";
  48. return false;
  49. }
  50. out = in->site_.GetURL().SchemeIsFile()
  51. ? in->site_.SerializeFileSiteWithHost()
  52. : in->site_.Serialize();
  53. return true;
  54. }
  55. // static
  56. bool CookiePartitionKey::Deserialize(const std::string& in,
  57. absl::optional<CookiePartitionKey>& out) {
  58. if (in == kEmptyCookiePartitionKey) {
  59. out = absl::nullopt;
  60. return true;
  61. }
  62. if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
  63. DLOG(WARNING) << "Attempting to deserialize CookiePartitionKey when "
  64. "PartitionedCookies is disabled";
  65. return false;
  66. }
  67. auto schemeful_site = SchemefulSite::Deserialize(in);
  68. // SchemfulSite is opaque if the input is invalid.
  69. if (schemeful_site.opaque()) {
  70. DLOG(WARNING) << "Cannot deserialize opaque origin to CookiePartitionKey";
  71. return false;
  72. }
  73. out = absl::make_optional(CookiePartitionKey(schemeful_site, absl::nullopt));
  74. return true;
  75. }
  76. absl::optional<CookiePartitionKey> CookiePartitionKey::FromNetworkIsolationKey(
  77. const NetworkIsolationKey& network_isolation_key,
  78. const SchemefulSite* first_party_set_owner_site) {
  79. absl::optional<base::UnguessableToken> nonce =
  80. network_isolation_key.GetNonce();
  81. // If PartitionedCookies is enabled, all partitioned cookies are allowed.
  82. // If NoncedPartitionedCookies is enabled, only partitioned cookies whose
  83. // partition key has a nonce are allowed.
  84. if (!base::FeatureList::IsEnabled(features::kPartitionedCookies) &&
  85. (!base::FeatureList::IsEnabled(features::kNoncedPartitionedCookies) ||
  86. !nonce)) {
  87. return absl::nullopt;
  88. }
  89. // TODO(crbug.com/1225444): Check if the top frame site is in a First-Party
  90. // Set or if it is an extension URL.
  91. const SchemefulSite* partition_key_site =
  92. first_party_set_owner_site
  93. ? first_party_set_owner_site
  94. : base::OptionalOrNullptr(network_isolation_key.GetTopFrameSite());
  95. if (!partition_key_site)
  96. return absl::nullopt;
  97. return absl::make_optional(
  98. net::CookiePartitionKey(*partition_key_site, nonce));
  99. }
  100. bool CookiePartitionKey::IsSerializeable() const {
  101. if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
  102. DLOG(WARNING) << "Attempting to serialize CookiePartitionKey when "
  103. "PartitionedCookies feature is disabled";
  104. return false;
  105. }
  106. // We should not try to serialize a partition key created by a renderer.
  107. DCHECK(!from_script_);
  108. return !site_.opaque() && !nonce_.has_value();
  109. }
  110. std::ostream& operator<<(std::ostream& os, const CookiePartitionKey& cpk) {
  111. os << cpk.site();
  112. return os;
  113. }
  114. } // namespace net