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