isolation_info.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright 2020 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_ISOLATION_INFO_H_
  5. #define NET_BASE_ISOLATION_INFO_H_
  6. #include <set>
  7. #include <string>
  8. #include "base/unguessable_token.h"
  9. #include "net/base/net_export.h"
  10. #include "net/base/network_isolation_key.h"
  11. #include "net/cookies/site_for_cookies.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. #include "url/origin.h"
  14. namespace network::mojom {
  15. class IsolationInfoDataView;
  16. } // namespace network::mojom
  17. namespace mojo {
  18. template <typename DataViewType, typename T>
  19. struct StructTraits;
  20. } // namespace mojo
  21. namespace net {
  22. // Class to store information about network stack requests based on the context
  23. // in which they are made. It provides NetworkIsolationKeys, used to shard
  24. // storage, and SiteForCookies, used determine when to send same site cookies.
  25. // The IsolationInfo is typically the same for all subresource requests made in
  26. // the context of the same frame, but may be different for different frames
  27. // within a page. The IsolationInfo associated with requests for frames may
  28. // change as redirects are followed, and this class also contains the logic on
  29. // how to do that.
  30. //
  31. // The SiteForCookies logic in this class is currently unused, but will
  32. // eventually replace the logic in URLRequest/RedirectInfo for tracking and
  33. // updating that value.
  34. class NET_EXPORT IsolationInfo {
  35. public:
  36. // The update-on-redirect patterns.
  37. //
  38. // In general, almost everything should use kOther, as a
  39. // kMainFrame request accidentally sent or redirected to an attacker
  40. // allows cross-site tracking, and kSubFrame allows information
  41. // leaks between sites that iframe each other. Anything that uses
  42. // kMainFrame should be user triggered and user visible, like a main
  43. // frame navigation or downloads.
  44. //
  45. // The RequestType is a core part of an IsolationInfo, and using an
  46. // IsolationInfo with one value to create an IsolationInfo with another
  47. // RequestType is generally not a good idea, unless the RequestType of the
  48. // new IsolationInfo is kOther.
  49. enum class RequestType {
  50. // Updates top level origin, frame origin, and SiteForCookies on redirect.
  51. // These requests allow users to be recognized across sites on redirect, so
  52. // should not generally be used for anything other than navigations.
  53. kMainFrame,
  54. // Only updates frame origin on redirect.
  55. kSubFrame,
  56. // Updates nothing on redirect.
  57. kOther,
  58. };
  59. // Bound the party_context size with a reasonable number.
  60. static constexpr size_t kPartyContextMaxSize = 20;
  61. // Default constructor returns an IsolationInfo with empty origins, a null
  62. // SiteForCookies(), null |party_context|, and a RequestType of kOther.
  63. IsolationInfo();
  64. IsolationInfo(const IsolationInfo&);
  65. IsolationInfo(IsolationInfo&&);
  66. ~IsolationInfo();
  67. IsolationInfo& operator=(const IsolationInfo&);
  68. IsolationInfo& operator=(IsolationInfo&&);
  69. // Simple constructor for internal requests. Sets |frame_origin| and
  70. // |site_for_cookies| match |top_frame_origin|. Sets |request_type| to
  71. // kOther. Will only send SameSite cookies to the site associated with
  72. // the passed in origin. |party_context| is set to be an empty set.
  73. static IsolationInfo CreateForInternalRequest(
  74. const url::Origin& top_frame_origin);
  75. // Creates a transient IsolationInfo. A transient IsolationInfo will not save
  76. // data to disk and not send SameSite cookies. Equivalent to calling
  77. // CreateForInternalRequest with a fresh opaque origin.
  78. static IsolationInfo CreateTransient();
  79. // Creates an IsolationInfo from the serialized contents. Returns a nullopt
  80. // if deserialization fails or if data is inconsistent.
  81. static absl::optional<IsolationInfo> Deserialize(
  82. const std::string& serialized);
  83. // Creates an IsolationInfo with the provided parameters. If the parameters
  84. // are inconsistent, DCHECKs. In particular:
  85. // * If |request_type| is kMainFrame, |top_frame_origin| must equal
  86. // |frame_origin|, and |site_for_cookies| must be either null or first party
  87. // with respect to them.
  88. // * If |request_type| is kSubFrame, |top_frame_origin| must be
  89. // first party with respect to |site_for_cookies|, or |site_for_cookies|
  90. // must be null.
  91. // * If |request_type| is kOther, |top_frame_origin| and
  92. // |frame_origin| must be first party with respect to |site_for_cookies|, or
  93. // |site_for_cookies| must be null.
  94. // * If |party_context| is not empty, |top_frame_origin| must not be null.
  95. // * If |nonce| is specified, then |top_frame_origin| must not be null.
  96. //
  97. // Note that the |site_for_cookies| consistency checks are skipped when
  98. // |site_for_cookies| is not HTTP/HTTPS.
  99. static IsolationInfo Create(
  100. RequestType request_type,
  101. const url::Origin& top_frame_origin,
  102. const url::Origin& frame_origin,
  103. const SiteForCookies& site_for_cookies,
  104. absl::optional<std::set<SchemefulSite>> party_context = absl::nullopt,
  105. const base::UnguessableToken* nonce = nullptr);
  106. // Create and IsolationInfo from the context of a double key. This should only
  107. // be used when we don't have access to the frame_origin because the
  108. // IsolationInfo is being created from an existing double keyed IsolationInfo.
  109. static IsolationInfo CreateDoubleKey(
  110. RequestType request_type,
  111. const url::Origin& top_frame_origin,
  112. const SiteForCookies& site_for_cookies,
  113. absl::optional<std::set<SchemefulSite>> party_context = absl::nullopt,
  114. const base::UnguessableToken* nonce = nullptr);
  115. // Create an IsolationInfos that may not be fully correct - in particular,
  116. // the SiteForCookies will always set to null, and if the NetworkIsolationKey
  117. // only has a top frame origin, the frame origin will either be set to the top
  118. // frame origin, in the kMainFrame case, or be replaced by an opaque
  119. // origin in all other cases. If the NetworkIsolationKey is not fully
  120. // populated, will create an empty IsolationInfo. This is intended for use
  121. // while transitioning from NIKs being set on only some requests to
  122. // IsolationInfos being set on all requests.
  123. static IsolationInfo CreatePartial(
  124. RequestType request_type,
  125. const net::NetworkIsolationKey& network_isolation_key);
  126. // Returns nullopt if the arguments are not consistent. Otherwise, returns a
  127. // fully populated IsolationInfo. Any IsolationInfo that can be created by
  128. // the other construction methods, including the 0-argument constructor, is
  129. // considered consistent.
  130. //
  131. // Intended for use by cross-process deserialization.
  132. static absl::optional<IsolationInfo> CreateIfConsistent(
  133. RequestType request_type,
  134. const absl::optional<url::Origin>& top_frame_origin,
  135. const absl::optional<url::Origin>& frame_origin,
  136. const SiteForCookies& site_for_cookies,
  137. absl::optional<std::set<SchemefulSite>> party_context = absl::nullopt,
  138. const base::UnguessableToken* nonce = nullptr);
  139. // Create a new IsolationInfo for a redirect to the supplied origin. |this| is
  140. // unmodified.
  141. IsolationInfo CreateForRedirect(const url::Origin& new_origin) const;
  142. // Intended for temporary use in locations that should be using main frame and
  143. // frame origin, but are currently only using frame origin, because the
  144. // creating object may be shared across main frame objects. Having a special
  145. // constructor for these methods makes it easier to keep track of locating
  146. // callsites that need to have their IsolationInfo filled in.
  147. static IsolationInfo ToDoUseTopFrameOriginAsWell(
  148. const url::Origin& incorrectly_used_frame_origin);
  149. RequestType request_type() const { return request_type_; }
  150. bool IsEmpty() const { return !top_frame_origin_; }
  151. // These may only be nullopt if created by the empty constructor. If one is
  152. // nullopt, both are, and SiteForCookies is null.
  153. //
  154. // Note that these are the values the IsolationInfo was created with. In the
  155. // case an IsolationInfo was created from a NetworkIsolationKey, they may be
  156. // scheme + eTLD+1 instead of actual origins.
  157. const absl::optional<url::Origin>& top_frame_origin() const {
  158. return top_frame_origin_;
  159. }
  160. const absl::optional<url::Origin>& frame_origin() const;
  161. const NetworkIsolationKey& network_isolation_key() const {
  162. return network_isolation_key_;
  163. }
  164. const absl::optional<base::UnguessableToken>& nonce() const { return nonce_; }
  165. // The value that should be consulted for the third-party cookie blocking
  166. // policy, as defined in Section 2.1.1 and 2.1.2 of
  167. // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site.
  168. //
  169. // WARNING: This value must only be used for the third-party cookie blocking
  170. // policy. It MUST NEVER be used for any kind of SECURITY check.
  171. const SiteForCookies& site_for_cookies() const { return site_for_cookies_; }
  172. // Return |party_context| which exclude the top frame origin and the frame
  173. // origin.
  174. // TODO(mmenke): Make this function PartyContextForTesting() after switching
  175. // RenderFrameHostImpl to use the parent IsolationInfo to create the child
  176. // IsolationInfo instead of walking through all parent frames.
  177. const absl::optional<std::set<SchemefulSite>>& party_context() const {
  178. return party_context_;
  179. }
  180. bool IsEqualForTesting(const IsolationInfo& other) const;
  181. // Serialize the `IsolationInfo` into a string. Fails if transient, returning
  182. // an empty string.
  183. std::string Serialize() const;
  184. // Returns true if the IsolationInfo has a triple keyed scheme. This
  185. // means both `frame_site_` and `top_frame_site_` are populated.
  186. static bool IsFrameSiteEnabled();
  187. private:
  188. IsolationInfo(RequestType request_type,
  189. const absl::optional<url::Origin>& top_frame_origin,
  190. const absl::optional<url::Origin>& frame_origin,
  191. const SiteForCookies& site_for_cookies,
  192. const base::UnguessableToken* nonce,
  193. absl::optional<std::set<SchemefulSite>> party_context);
  194. RequestType request_type_;
  195. absl::optional<url::Origin> top_frame_origin_;
  196. absl::optional<url::Origin> frame_origin_;
  197. // This can be deduced from the two origins above, but keep a cached version
  198. // to avoid repeated eTLD+1 calculations, when this is using eTLD+1.
  199. net::NetworkIsolationKey network_isolation_key_;
  200. SiteForCookies site_for_cookies_;
  201. // Having a nonce is a way to force a transient opaque `IsolationInfo`
  202. // for non-opaque origins.
  203. absl::optional<base::UnguessableToken> nonce_;
  204. // This will hold the list of distinct sites in the form of SchemefulSite to
  205. // be used for First-Party-Sets check.
  206. //
  207. // For |request_type_| being either RequestType::kMainFrame or
  208. // RequestType::kSubFrame, |party_context| holds the set of the sites
  209. // of the frames in between the current frame and the top frame (i.e. not
  210. // considering the current frame or the top frame).
  211. //
  212. // For |request_type_| being RequestType::kOther, |party_context_| holds the
  213. // above, and also the site of the current frame.
  214. //
  215. // Note that if an intermediate frame shares a site with the top frame, that
  216. // frame's site is not reflected in the |party_context_|. Also note that if an
  217. // intermediate frame shares a site with the current frame, that frame's site
  218. // is still included in the set. The top frame's site is excluded because it
  219. // is redundant with the |top_frame_origin_| field. The current frame is
  220. // excluded to make it easier to update on subframe redirects.
  221. absl::optional<std::set<SchemefulSite>> party_context_;
  222. // Mojo serialization code needs to access internal party_context_ field.
  223. friend struct mojo::StructTraits<network::mojom::IsolationInfoDataView,
  224. IsolationInfo>;
  225. };
  226. } // namespace net
  227. #endif // NET_BASE_ISOLATION_INFO_H_