network_anonymization_key.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2022 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. #ifndef NET_BASE_NETWORK_ANONYMIZATION_KEY_H_
  5. #define NET_BASE_NETWORK_ANONYMIZATION_KEY_H_
  6. #include <string>
  7. #include <tuple>
  8. #include "base/unguessable_token.h"
  9. #include "net/base/net_export.h"
  10. #include "net/base/schemeful_site.h"
  11. #include "third_party/abseil-cpp/absl/types/optional.h"
  12. namespace net {
  13. // NetworkAnonymizationKey will be used to partition shared network state based
  14. // on the context on which they were made. This class is an expiremental key
  15. // that contains properties that will be changed via feature flags.
  16. // NetworkAnonymizationKey contains the following properties:
  17. // `top_frame_site` represents the SchemefulSite of the pages top level frame.
  18. // In order to separate first and third party context from each other this field
  19. // will always be populated.
  20. // `frame_site` represents the SchemefulSite of the requestor frame. This will
  21. // be empty when kEnableDoubleKeyNetworkAnonymizationKey is enabled.
  22. //`is_cross_site` is an expiremental boolean that will be used with the
  23. //`top_frame_site` to create a partition key that separates the
  24. //`top_frame_site`s first party partition from any cross-site iframes. This will
  25. // be used only when `kEnableCrossSiteFlagNetworkAnonymizationKey` is enabled.
  26. // When `kEnableCrossSiteFlagNetworkAnonymizationKey` is disabled,
  27. // `is_cross_site_` will be an empty optional.
  28. // The following show how the `is_cross_site` boolean is populated for the
  29. // innermost frame in the chain.
  30. // a->a => is_cross_site = true
  31. // a->b => is_cross_site = false
  32. // a->b->a => is_cross_site = false
  33. // a->(sandboxed a [has nonce]) => is_cross_site = true
  34. // The `nonce` value creates a key for anonymous iframes by giving them a
  35. // temporary `nonce` value which changes per top level navigation. For now, any
  36. // NetworkAnonymizationKey with a nonce will be considered transient. This is
  37. // being considered to possibly change in the future in an effort to allow
  38. // anonymous iframes with the same partition key access to shared resources.
  39. // The nonce value will be empty except for anonymous iframes.
  40. // TODO @brgoldstein, add link to public documentation of key scheme naming
  41. // conventions.
  42. class NET_EXPORT NetworkAnonymizationKey {
  43. public:
  44. NetworkAnonymizationKey(
  45. const SchemefulSite& top_frame_site,
  46. const absl::optional<SchemefulSite>& frame_site,
  47. const absl::optional<bool> is_cross_site = absl::nullopt,
  48. const absl::optional<base::UnguessableToken> nonce = absl::nullopt);
  49. // Construct an empty key.
  50. NetworkAnonymizationKey();
  51. NetworkAnonymizationKey(
  52. const NetworkAnonymizationKey& network_anonymization_key);
  53. NetworkAnonymizationKey(NetworkAnonymizationKey&& network_anonymization_key);
  54. ~NetworkAnonymizationKey();
  55. NetworkAnonymizationKey& operator=(
  56. const NetworkAnonymizationKey& network_anonymization_key);
  57. NetworkAnonymizationKey& operator=(
  58. NetworkAnonymizationKey&& network_anonymization_key);
  59. // Compare keys for equality, true if all enabled fields are equal.
  60. bool operator==(const NetworkAnonymizationKey& other) const {
  61. return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) ==
  62. std::tie(other.top_frame_site_, other.frame_site_,
  63. other.is_cross_site_, other.nonce_);
  64. }
  65. // Compare keys for inequality, true if any enabled field varies.
  66. bool operator!=(const NetworkAnonymizationKey& other) const {
  67. return !(*this == other);
  68. }
  69. // Provide an ordering for keys based on all enabled fields.
  70. bool operator<(const NetworkAnonymizationKey& other) const {
  71. return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) <
  72. std::tie(other.top_frame_site_, other.frame_site_,
  73. other.is_cross_site_, other.nonce_);
  74. }
  75. // Returns the string representation of the key.
  76. std::string ToDebugString() const;
  77. // Returns true if all parts of the key are empty.
  78. bool IsEmpty() const;
  79. // Returns true if `top_frame_site_` and `frame_site_` of the key are
  80. // non-empty.
  81. bool IsFullyPopulated() const;
  82. // Returns true if this key's lifetime is short-lived. It may not make sense
  83. // to persist state to disk related to it (e.g., disk cache).
  84. // A NetworkAnonymizationKey will be considered transient if either
  85. // `top_frame_site_` or `frame_site_` are empty or opaque or if the key has a
  86. // `nonce_`.
  87. bool IsTransient() const;
  88. // Getters for the top frame, frame site, nonce and is cross site flag.
  89. // TODO @brgoldstein: create feature flags to wrap these properties so that
  90. // the key can be modified for experimentation.
  91. const absl::optional<SchemefulSite>& GetTopFrameSite() const {
  92. return top_frame_site_;
  93. }
  94. const absl::optional<SchemefulSite>& GetFrameSite() const {
  95. return frame_site_;
  96. }
  97. bool GetIsCrossSite() const;
  98. const absl::optional<base::UnguessableToken>& GetNonce() const {
  99. return nonce_;
  100. }
  101. // Returns true if the NetworkAnonymizationKey has a triple keyed scheme. This
  102. // means the values of the NetworkAnonymizationKey are as follows:
  103. // `top_frame_site` -> the schemeful site of the top level page.
  104. // `frame_site ` -> the schemeful site of the requestor frame
  105. // `is_cross_site` -> nullopt
  106. static bool IsFrameSiteEnabled();
  107. // Returns true if the NetworkAnonymizationKey has a double keyed scheme. This
  108. // means the values of the NetworkAnonymizationKey are as follows:
  109. // `top_frame_site` -> the schemeful site of the top level page.
  110. // `frame_site ` -> nullopt
  111. // `is_cross_site` -> nullopt
  112. static bool IsDoubleKeySchemeEnabled();
  113. // Returns true if the NetworkAnonymizationKey has a <double keyed +
  114. // is_cross_site> scheme. This means the values of the NetworkAnonymizationKey
  115. // are as follows:
  116. // `top_frame_site` -> the schemeful site of the top level page.
  117. // `frame_site ` -> nullopt
  118. // `is_cross_site` -> a boolean indicating if the requestor frame site is
  119. // cross site from the top level site.
  120. static bool IsCrossSiteFlagSchemeEnabled();
  121. private:
  122. std::string GetSiteDebugString(
  123. const absl::optional<SchemefulSite>& site) const;
  124. // The origin/etld+1 of the top frame of the page making the request. This
  125. // will always be populated unless all other fields are also nullopt.
  126. absl::optional<SchemefulSite> top_frame_site_;
  127. // The origin/etld+1 of the frame that initiates the request.
  128. absl::optional<SchemefulSite> frame_site_;
  129. // True if the frame site is cross site when compared to the top frame site.
  130. absl::optional<bool> is_cross_site_;
  131. // for non-opaque origins.
  132. absl::optional<base::UnguessableToken> nonce_;
  133. };
  134. } // namespace net
  135. #endif // NET_BASE_NETWORK_ANONYMIZATION_KEY_H_