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 5 #ifndef NET_BASE_ISOLATION_INFO_H_ 6 #define NET_BASE_ISOLATION_INFO_H_ 7 8 #include "base/optional.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 "url/origin.h" 13 14 namespace net { 15 16 // Class to store information about network stack requests based on the context 17 // in which they are made. It provides NetworkIsolationKeys, used to shard 18 // storage, and SiteForCookies, used determine when to send same site cookies. 19 // The IsolationInfo is typically the same for all subresource requests made in 20 // the context of the same frame, but may be different for different frames 21 // within a page. The IsolationInfo associated with requests for frames may 22 // change as redirects are followed, and this class also contains the logic on 23 // how to do that. 24 // 25 // The SiteForCookies logic in this class is currently unused, but will 26 // eventually replace the logic in URLRequest/RedirectInfo for tracking and 27 // updating that value. 28 class NET_EXPORT IsolationInfo { 29 public: 30 // The update-on-redirect patterns. 31 // 32 // In general, almost everything should use kOther, as a 33 // kMainFrame request accidentally sent or redirected to an attacker 34 // allows cross-site tracking, and kSubFrame allows information 35 // leaks between sites that iframe each other. Anything that uses 36 // kMainFrame should be user triggered and user visible, like a main 37 // frame navigation or downloads. 38 // 39 // The RequestType is a core part of an IsolationInfo, and using an 40 // IsolationInfo with one value to create an IsolationInfo with another 41 // RequestType is generally not a good idea, unless the RequestType of the 42 // new IsolationInfo is kOther. 43 enum class RequestType { 44 // Updates top level origin, frame origin, and SiteForCookies on redirect. 45 // These requests allow users to be recognized across sites on redirect, so 46 // should not generally be used for anything other than navigations. 47 kMainFrame, 48 49 // Only updates frame origin on redirect. 50 kSubFrame, 51 52 // Updates nothing on redirect. 53 kOther, 54 }; 55 56 // Default constructor returns an IsolationInfo with empty origins, a null 57 // SiteForCookies(), and a RequestType of kOther. 58 IsolationInfo(); 59 IsolationInfo(const IsolationInfo&); 60 IsolationInfo(IsolationInfo&&); 61 ~IsolationInfo(); 62 63 IsolationInfo& operator=(const IsolationInfo&); 64 IsolationInfo& operator=(IsolationInfo&&); 65 66 // Simple constructor for internal requests. Sets |frame_origin| and 67 // |site_for_cookies| match |top_frame_origin|. Sets |request_type| to 68 // kOther. Will only send SameSite cookies to the site associated with 69 // the passed in origin. 70 static IsolationInfo CreateForInternalRequest( 71 const url::Origin& top_frame_origin); 72 73 // Creates a transient IsolationInfo. A transient IsolationInfo will not save 74 // data to disk and not send SameSite cookies. Equivalent to calling 75 // CreateForInternalRequest with a fresh opaque origin. 76 static IsolationInfo CreateTransient(); 77 78 // Creates a non-transient IsolationInfo. Just like a transient IsolationInfo 79 // (no SameSite cookies, opaque Origins), but does write data to disk, so this 80 // allows use of the disk cache with a transient NIK. 81 static IsolationInfo CreateOpaqueAndNonTransient(); 82 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 // 95 // Note that the |site_for_cookies| consistency checks are skipped when 96 // |site_for_cookies| is not HTTP/HTTPS. 97 static IsolationInfo Create(RequestType request_type, 98 const url::Origin& top_frame_origin, 99 const url::Origin& frame_origin, 100 const SiteForCookies& site_for_cookies); 101 102 // Create an IsolationInfos that may not be fully correct - in particular, 103 // the SiteForCookies will always set to null, and if the NetworkIsolationKey 104 // only has a top frame origin, the frame origin will either be set to the top 105 // frame origin, in the kMainFrame case, or be replaced by an opaque 106 // origin in all other cases. If the NetworkIsolationKey is not fully 107 // populated, will create an empty IsolationInfo. This is intended for use 108 // while transitioning from NIKs being set on only some requests to 109 // IsolationInfos being set on all requests. 110 // 111 // TODO(https://crbug.com/1060631): Remove this once no longer needed. 112 static IsolationInfo CreatePartial( 113 RequestType request_type, 114 const net::NetworkIsolationKey& network_isolation_key); 115 116 // Returns nullopt if the arguments are not consistent. Otherwise, returns a 117 // fully populated IsolationInfo. Any IsolationInfo that can be created by 118 // the other construction methods, including the 0-argument constructor, is 119 // considered consistent. 120 // 121 // Intended for use by cross-process deserialization. 122 static base::Optional<IsolationInfo> CreateIfConsistent( 123 RequestType request_type, 124 const base::Optional<url::Origin>& top_frame_origin, 125 const base::Optional<url::Origin>& frame_origin, 126 const SiteForCookies& site_for_cookies, 127 bool opaque_and_non_transient); 128 129 // Create a new IsolationInfo for a redirect to the supplied origin. |this| is 130 // unmodified. 131 IsolationInfo CreateForRedirect(const url::Origin& new_origin) const; 132 request_type()133 RequestType request_type() const { return request_type_; } 134 IsEmpty()135 bool IsEmpty() const { return !top_frame_origin_; } 136 137 // These may only be nullopt if created by the empty constructor. If one is 138 // nullopt, both are, and SiteForCookies is null. 139 // 140 // Note that these are the values the IsolationInfo was created with. In the 141 // case an IsolationInfo was created from a NetworkIsolationKey, they may be 142 // scheme + eTLD+1 instead of actual origins. top_frame_origin()143 const base::Optional<url::Origin>& top_frame_origin() const { 144 return top_frame_origin_; 145 } frame_origin()146 const base::Optional<url::Origin>& frame_origin() const { 147 return frame_origin_; 148 } 149 network_isolation_key()150 const NetworkIsolationKey& network_isolation_key() const { 151 return network_isolation_key_; 152 } 153 154 // The value that should be consulted for the third-party cookie blocking 155 // policy, as defined in Section 2.1.1 and 2.1.2 of 156 // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site. 157 // 158 // WARNING: This value must only be used for the third-party cookie blocking 159 // policy. It MUST NEVER be used for any kind of SECURITY check. site_for_cookies()160 const SiteForCookies& site_for_cookies() const { return site_for_cookies_; } 161 opaque_and_non_transient()162 bool opaque_and_non_transient() const { return opaque_and_non_transient_; } 163 164 bool IsEqualForTesting(const IsolationInfo& other) const; 165 166 private: 167 IsolationInfo(RequestType request_type, 168 const base::Optional<url::Origin>& top_frame_origin, 169 const base::Optional<url::Origin>& frame_origin, 170 const SiteForCookies& site_for_cookies, 171 bool opaque_and_non_transient); 172 173 RequestType request_type_; 174 175 base::Optional<url::Origin> top_frame_origin_; 176 base::Optional<url::Origin> frame_origin_; 177 178 // This can be deduced from the two origins above, but keep a cached version 179 // to avoid repeated eTLD+1 calculations, when this is using eTLD+1. 180 net::NetworkIsolationKey network_isolation_key_; 181 182 SiteForCookies site_for_cookies_; 183 184 bool opaque_and_non_transient_ = false; 185 }; 186 187 } // namespace net 188 189 #endif // NET_BASE_ISOLATION_INFO_H_ 190