xref: /aosp_15_r20/external/cronet/net/base/isolation_info.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_BASE_ISOLATION_INFO_H_
6 #define NET_BASE_ISOLATION_INFO_H_
7 
8 #include <optional>
9 #include <set>
10 #include <string>
11 
12 #include "base/unguessable_token.h"
13 #include "net/base/net_export.h"
14 #include "net/base/network_anonymization_key.h"
15 #include "net/base/network_isolation_key.h"
16 #include "net/cookies/site_for_cookies.h"
17 #include "url/origin.h"
18 
19 namespace network::mojom {
20 class IsolationInfoDataView;
21 }  // namespace network::mojom
22 
23 namespace mojo {
24 template <typename DataViewType, typename T>
25 struct StructTraits;
26 }  // namespace mojo
27 
28 namespace net {
29 
30 // Class to store information about network stack requests based on the context
31 // in which they are made. It provides NetworkIsolationKeys, used to shard
32 // storage, and SiteForCookies, used determine when to send same site cookies.
33 // The IsolationInfo is typically the same for all subresource requests made in
34 // the context of the same frame, but may be different for different frames
35 // within a page. The IsolationInfo associated with requests for frames may
36 // change as redirects are followed, and this class also contains the logic on
37 // how to do that.
38 //
39 // The SiteForCookies logic in this class is currently unused, but will
40 // eventually replace the logic in URLRequest/RedirectInfo for tracking and
41 // updating that value.
42 class NET_EXPORT IsolationInfo {
43  public:
44   // The update-on-redirect patterns.
45   //
46   // In general, almost everything should use kOther, as a
47   // kMainFrame request accidentally sent or redirected to an attacker
48   // allows cross-site tracking, and kSubFrame allows information
49   // leaks between sites that iframe each other. Anything that uses
50   // kMainFrame should be user triggered and user visible, like a main
51   // frame navigation or downloads.
52   //
53   // The RequestType is a core part of an IsolationInfo, and using an
54   // IsolationInfo with one value to create an IsolationInfo with another
55   // RequestType is generally not a good idea, unless the RequestType of the
56   // new IsolationInfo is kOther.
57   enum class RequestType {
58     // Updates top level origin, frame origin, and SiteForCookies on redirect.
59     // These requests allow users to be recognized across sites on redirect, so
60     // should not generally be used for anything other than navigations.
61     kMainFrame,
62 
63     // Only updates frame origin on redirect.
64     kSubFrame,
65 
66     // Updates nothing on redirect.
67     kOther,
68   };
69 
70   // Default constructor returns an IsolationInfo with empty origins, a null
71   // SiteForCookies(), and a RequestType of kOther.
72   IsolationInfo();
73   IsolationInfo(const IsolationInfo&);
74   IsolationInfo(IsolationInfo&&);
75   ~IsolationInfo();
76 
77   IsolationInfo& operator=(const IsolationInfo&);
78   IsolationInfo& operator=(IsolationInfo&&);
79 
80   // Simple constructor for internal requests. Sets |frame_origin| and
81   // |site_for_cookies| match |top_frame_origin|. Sets |request_type| to
82   // kOther. Will only send SameSite cookies to the site associated with
83   // the passed in origin.
84   static IsolationInfo CreateForInternalRequest(
85       const url::Origin& top_frame_origin);
86 
87   // Creates a transient IsolationInfo. A transient IsolationInfo will not save
88   // data to disk and not send SameSite cookies. Equivalent to calling
89   // CreateForInternalRequest with a fresh opaque origin.
90   static IsolationInfo CreateTransient();
91 
92   // Same as CreateTransient, with a `nonce` used to identify requests tagged
93   // with this IsolationInfo in the network service. The `nonce` provides no
94   // additional resource isolation, because the opaque origin in the resulting
95   // IsolationInfo already represents a unique partition.
96   static IsolationInfo CreateTransientWithNonce(
97       const base::UnguessableToken& nonce);
98 
99   // Creates an IsolationInfo from the serialized contents. Returns a nullopt
100   // if deserialization fails or if data is inconsistent.
101   static std::optional<IsolationInfo> Deserialize(
102       const std::string& serialized);
103 
104   // Creates an IsolationInfo with the provided parameters. If the parameters
105   // are inconsistent, DCHECKs. In particular:
106   // * If |request_type| is kMainFrame, |top_frame_origin| must equal
107   //   |frame_origin|, and |site_for_cookies| must be either null or first party
108   //   with respect to them.
109   // * If |request_type| is kSubFrame, |top_frame_origin| must be
110   //   first party with respect to |site_for_cookies|, or |site_for_cookies|
111   //   must be null.
112   // * If |request_type| is kOther, |top_frame_origin| and
113   //   |frame_origin| must be first party with respect to |site_for_cookies|, or
114   //   |site_for_cookies| must be null.
115   // * If |nonce| is specified, then |top_frame_origin| must not be null.
116   //
117   // Note that the |site_for_cookies| consistency checks are skipped when
118   // |site_for_cookies| is not HTTP/HTTPS.
119   static IsolationInfo Create(
120       RequestType request_type,
121       const url::Origin& top_frame_origin,
122       const url::Origin& frame_origin,
123       const SiteForCookies& site_for_cookies,
124       const std::optional<base::UnguessableToken>& nonce = std::nullopt);
125 
126   // TODO(crbug/1372769): Remove this and create a safer way to ensure NIKs
127   // created from NAKs aren't used by accident.
128   static IsolationInfo DoNotUseCreatePartialFromNak(
129       const net::NetworkAnonymizationKey& network_anonymization_key);
130 
131   // Returns nullopt if the arguments are not consistent. Otherwise, returns a
132   // fully populated IsolationInfo. Any IsolationInfo that can be created by
133   // the other construction methods, including the 0-argument constructor, is
134   // considered consistent.
135   //
136   // Intended for use by cross-process deserialization.
137   static std::optional<IsolationInfo> CreateIfConsistent(
138       RequestType request_type,
139       const std::optional<url::Origin>& top_frame_origin,
140       const std::optional<url::Origin>& frame_origin,
141       const SiteForCookies& site_for_cookies,
142       const std::optional<base::UnguessableToken>& nonce = std::nullopt);
143 
144   // Create a new IsolationInfo for a redirect to the supplied origin. |this| is
145   // unmodified.
146   IsolationInfo CreateForRedirect(const url::Origin& new_origin) const;
147 
request_type()148   RequestType request_type() const { return request_type_; }
149 
IsEmpty()150   bool IsEmpty() const { return !top_frame_origin_; }
151 
152   // These may only be nullopt if created by the empty constructor. If one is
153   // nullopt, both are, and SiteForCookies is null.
154   //
155   // Note that these are the values the IsolationInfo was created with. In the
156   // case an IsolationInfo was created from a NetworkIsolationKey, they may be
157   // scheme + eTLD+1 instead of actual origins.
top_frame_origin()158   const std::optional<url::Origin>& top_frame_origin() const {
159     return top_frame_origin_;
160   }
161   const std::optional<url::Origin>& frame_origin() const;
162 
network_isolation_key()163   const NetworkIsolationKey& network_isolation_key() const {
164     return network_isolation_key_;
165   }
166 
network_anonymization_key()167   const NetworkAnonymizationKey& network_anonymization_key() const {
168     return network_anonymization_key_;
169   }
170 
nonce()171   const std::optional<base::UnguessableToken>& nonce() const { return nonce_; }
172 
173   // The value that should be consulted for the third-party cookie blocking
174   // policy, as defined in Section 2.1.1 and 2.1.2 of
175   // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site.
176   //
177   // WARNING: This value must only be used for the third-party cookie blocking
178   //          policy. It MUST NEVER be used for any kind of SECURITY check.
site_for_cookies()179   const SiteForCookies& site_for_cookies() const { return site_for_cookies_; }
180 
181   // Do not use outside of testing. Returns the `frame_origin_`.
182   const std::optional<url::Origin>& frame_origin_for_testing() const;
183 
184   bool IsEqualForTesting(const IsolationInfo& other) const;
185 
186   NetworkAnonymizationKey CreateNetworkAnonymizationKeyForIsolationInfo(
187       const std::optional<url::Origin>& top_frame_origin,
188       const std::optional<url::Origin>& frame_origin,
189       const std::optional<base::UnguessableToken>& nonce) const;
190 
191   // Serialize the `IsolationInfo` into a string. Fails if transient, returning
192   // an empty string.
193   std::string Serialize() const;
194 
195   std::string DebugString() const;
196 
197  private:
198   IsolationInfo(RequestType request_type,
199                 const std::optional<url::Origin>& top_frame_origin,
200                 const std::optional<url::Origin>& frame_origin,
201                 const SiteForCookies& site_for_cookies,
202                 const std::optional<base::UnguessableToken>& nonce);
203 
204   RequestType request_type_;
205 
206   std::optional<url::Origin> top_frame_origin_;
207   std::optional<url::Origin> frame_origin_;
208 
209   // This can be deduced from the two origins above, but keep a cached version
210   // to avoid repeated eTLD+1 calculations, when this is using eTLD+1.
211   NetworkIsolationKey network_isolation_key_;
212 
213   NetworkAnonymizationKey network_anonymization_key_;
214 
215   SiteForCookies site_for_cookies_;
216 
217   // Having a nonce is a way to force a transient opaque `IsolationInfo`
218   // for non-opaque origins.
219   std::optional<base::UnguessableToken> nonce_;
220 
221   // Mojo serialization code needs to access internal fields.
222   friend struct mojo::StructTraits<network::mojom::IsolationInfoDataView,
223                                    IsolationInfo>;
224 };
225 
226 }  // namespace net
227 
228 #endif  // NET_BASE_ISOLATION_INFO_H_
229