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