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_SCHEMEFUL_SITE_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_BASE_SCHEMEFUL_SITE_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <optional> 9*6777b538SAndroid Build Coastguard Worker #include <ostream> 10*6777b538SAndroid Build Coastguard Worker #include <string> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/types/pass_key.h" 14*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 15*6777b538SAndroid Build Coastguard Worker #include "url/origin.h" 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker class GURL; 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker namespace blink { 20*6777b538SAndroid Build Coastguard Worker class BlinkSchemefulSite; 21*6777b538SAndroid Build Coastguard Worker class StorageKey; 22*6777b538SAndroid Build Coastguard Worker } // namespace blink 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker namespace IPC { 25*6777b538SAndroid Build Coastguard Worker template <class P> 26*6777b538SAndroid Build Coastguard Worker struct ParamTraits; 27*6777b538SAndroid Build Coastguard Worker } // namespace IPC 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker namespace network::mojom { 30*6777b538SAndroid Build Coastguard Worker class SchemefulSiteDataView; 31*6777b538SAndroid Build Coastguard Worker } // namespace network::mojom 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker namespace mojo { 34*6777b538SAndroid Build Coastguard Worker template <typename DataViewType, typename T> 35*6777b538SAndroid Build Coastguard Worker struct StructTraits; 36*6777b538SAndroid Build Coastguard Worker } // namespace mojo 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker namespace net { 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker class NetworkAnonymizationKey; 41*6777b538SAndroid Build Coastguard Worker class SiteForCookies; 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker // Class which represents a scheme and etld+1 for an origin, as specified by 44*6777b538SAndroid Build Coastguard Worker // https://html.spec.whatwg.org/multipage/origin.html#obtain-a-site. 45*6777b538SAndroid Build Coastguard Worker // 46*6777b538SAndroid Build Coastguard Worker // A SchemefulSite is obtained from an input origin by normalizing, such that: 47*6777b538SAndroid Build Coastguard Worker // 1. Opaque origins have distinct SchemefulSites. 48*6777b538SAndroid Build Coastguard Worker // 2. Origins whose schemes have network hosts have the same SchemefulSite iff 49*6777b538SAndroid Build Coastguard Worker // they share a scheme, and share a hostname or registrable domain. Origins 50*6777b538SAndroid Build Coastguard Worker // whose schemes have network hosts include http, https, ws, wss, file, etc. 51*6777b538SAndroid Build Coastguard Worker // 3. Origins whose schemes do not have a network host have the same 52*6777b538SAndroid Build Coastguard Worker // SchemefulSite iff they share a scheme and host. 53*6777b538SAndroid Build Coastguard Worker // 4. Origins which differ only by port have the same SchemefulSite. 54*6777b538SAndroid Build Coastguard Worker // 5. Websocket origins cannot have a SchemefulSite (they trigger a DCHECK). 55*6777b538SAndroid Build Coastguard Worker // 56*6777b538SAndroid Build Coastguard Worker // Note that blink::BlinkSchemefulSite mirrors this class and needs to be kept 57*6777b538SAndroid Build Coastguard Worker // in sync with any data member changes. 58*6777b538SAndroid Build Coastguard Worker class NET_EXPORT SchemefulSite { 59*6777b538SAndroid Build Coastguard Worker public: 60*6777b538SAndroid Build Coastguard Worker SchemefulSite() = default; 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker // The passed `origin` may not match the resulting internal representation in 63*6777b538SAndroid Build Coastguard Worker // certain circumstances. See the comment, below, on the `site_as_origin_` 64*6777b538SAndroid Build Coastguard Worker // member. 65*6777b538SAndroid Build Coastguard Worker explicit SchemefulSite(const url::Origin& origin); 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker // Using the origin constructor is preferred as this is less efficient. 68*6777b538SAndroid Build Coastguard Worker // Should only be used if the origin for a given GURL is not readily 69*6777b538SAndroid Build Coastguard Worker // available. 70*6777b538SAndroid Build Coastguard Worker explicit SchemefulSite(const GURL& url); 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker SchemefulSite(const SchemefulSite& other); 73*6777b538SAndroid Build Coastguard Worker SchemefulSite(SchemefulSite&& other) noexcept; 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker SchemefulSite& operator=(const SchemefulSite& other); 76*6777b538SAndroid Build Coastguard Worker SchemefulSite& operator=(SchemefulSite&& other) noexcept; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker // Tries to construct an instance from a (potentially untrusted) value of the 79*6777b538SAndroid Build Coastguard Worker // internal `site_as_origin_` that got received over an RPC. 80*6777b538SAndroid Build Coastguard Worker // 81*6777b538SAndroid Build Coastguard Worker // Returns whether successful or not. Doesn't touch |*out| if false is 82*6777b538SAndroid Build Coastguard Worker // returned. This returning |true| does not mean that whoever sent the values 83*6777b538SAndroid Build Coastguard Worker // did not lie, merely that they are well-formed. 84*6777b538SAndroid Build Coastguard Worker static bool FromWire(const url::Origin& site_as_origin, SchemefulSite* out); 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker // Creates a SchemefulSite iff the passed-in origin has a registerable domain. 87*6777b538SAndroid Build Coastguard Worker static std::optional<SchemefulSite> CreateIfHasRegisterableDomain( 88*6777b538SAndroid Build Coastguard Worker const url::Origin&); 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker // If the scheme is ws or wss, it is converted to http or https, respectively. 91*6777b538SAndroid Build Coastguard Worker // Has no effect on SchemefulSites with any other schemes. 92*6777b538SAndroid Build Coastguard Worker // 93*6777b538SAndroid Build Coastguard Worker // See Step 1 of algorithm "establish a WebSocket connection" in 94*6777b538SAndroid Build Coastguard Worker // https://fetch.spec.whatwg.org/#websocket-opening-handshake. 95*6777b538SAndroid Build Coastguard Worker void ConvertWebSocketToHttp(); 96*6777b538SAndroid Build Coastguard Worker 97*6777b538SAndroid Build Coastguard Worker // Deserializes a string obtained from `Serialize()` to a `SchemefulSite`. 98*6777b538SAndroid Build Coastguard Worker // Returns an opaque `SchemefulSite` if the value was invalid in any way. 99*6777b538SAndroid Build Coastguard Worker static SchemefulSite Deserialize(const std::string& value); 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker // Returns a serialized version of `site_as_origin_`. If the underlying origin 102*6777b538SAndroid Build Coastguard Worker // is invalid, returns an empty string. If serialization of opaque origins 103*6777b538SAndroid Build Coastguard Worker // with their associated nonce is necessary, see `SerializeWithNonce()`. 104*6777b538SAndroid Build Coastguard Worker std::string Serialize() const; 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker // Serializes `site_as_origin_` in cases when it has a 'file' scheme but 107*6777b538SAndroid Build Coastguard Worker // we want to preserve the Origin's host. 108*6777b538SAndroid Build Coastguard Worker // This was added to serialize cookie partition keys, which may contain 109*6777b538SAndroid Build Coastguard Worker // file origins with a host. 110*6777b538SAndroid Build Coastguard Worker std::string SerializeFileSiteWithHost() const; 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard Worker std::string GetDebugString() const; 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker // Gets the underlying site as a GURL. If the internal Origin is opaque, 115*6777b538SAndroid Build Coastguard Worker // returns an empty GURL. 116*6777b538SAndroid Build Coastguard Worker GURL GetURL() const; 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker // Deserializes a string obtained from `SerializeWithNonce()` to a 119*6777b538SAndroid Build Coastguard Worker // `SchemefulSite`. Returns nullopt if the value was invalid in any way. 120*6777b538SAndroid Build Coastguard Worker static std::optional<SchemefulSite> DeserializeWithNonce( 121*6777b538SAndroid Build Coastguard Worker base::PassKey<NetworkAnonymizationKey>, 122*6777b538SAndroid Build Coastguard Worker const std::string& value); 123*6777b538SAndroid Build Coastguard Worker 124*6777b538SAndroid Build Coastguard Worker // Returns a serialized version of `site_as_origin_`. For an opaque 125*6777b538SAndroid Build Coastguard Worker // `site_as_origin_`, this serializes with the nonce. See 126*6777b538SAndroid Build Coastguard Worker // `url::origin::SerializeWithNonce()` for usage information. 127*6777b538SAndroid Build Coastguard Worker std::optional<std::string> SerializeWithNonce( 128*6777b538SAndroid Build Coastguard Worker base::PassKey<NetworkAnonymizationKey>); 129*6777b538SAndroid Build Coastguard Worker opaque()130*6777b538SAndroid Build Coastguard Worker bool opaque() const { return site_as_origin_.opaque(); } 131*6777b538SAndroid Build Coastguard Worker has_registrable_domain_or_host()132*6777b538SAndroid Build Coastguard Worker bool has_registrable_domain_or_host() const { 133*6777b538SAndroid Build Coastguard Worker return !registrable_domain_or_host().empty(); 134*6777b538SAndroid Build Coastguard Worker } 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker // Testing only function which allows tests to access the underlying 137*6777b538SAndroid Build Coastguard Worker // `site_as_origin_` in order to verify behavior. 138*6777b538SAndroid Build Coastguard Worker const url::Origin& GetInternalOriginForTesting() const; 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard Worker // Testing-only function which allows access to the private 141*6777b538SAndroid Build Coastguard Worker // `registrable_domain_or_host` method. registrable_domain_or_host_for_testing()142*6777b538SAndroid Build Coastguard Worker std::string registrable_domain_or_host_for_testing() const { 143*6777b538SAndroid Build Coastguard Worker return registrable_domain_or_host(); 144*6777b538SAndroid Build Coastguard Worker } 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker // Estimates dynamic memory usage. 147*6777b538SAndroid Build Coastguard Worker // See base/trace_event/memory_usage_estimator.h for more info. 148*6777b538SAndroid Build Coastguard Worker size_t EstimateMemoryUsage() const; 149*6777b538SAndroid Build Coastguard Worker 150*6777b538SAndroid Build Coastguard Worker bool operator==(const SchemefulSite& other) const; 151*6777b538SAndroid Build Coastguard Worker 152*6777b538SAndroid Build Coastguard Worker bool operator!=(const SchemefulSite& other) const; 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker bool operator<(const SchemefulSite& other) const; 155*6777b538SAndroid Build Coastguard Worker 156*6777b538SAndroid Build Coastguard Worker private: 157*6777b538SAndroid Build Coastguard Worker // IPC serialization code needs to access internal origin. 158*6777b538SAndroid Build Coastguard Worker friend struct mojo::StructTraits<network::mojom::SchemefulSiteDataView, 159*6777b538SAndroid Build Coastguard Worker SchemefulSite>; 160*6777b538SAndroid Build Coastguard Worker friend struct IPC::ParamTraits<net::SchemefulSite>; 161*6777b538SAndroid Build Coastguard Worker 162*6777b538SAndroid Build Coastguard Worker friend class blink::BlinkSchemefulSite; 163*6777b538SAndroid Build Coastguard Worker 164*6777b538SAndroid Build Coastguard Worker // Create SiteForCookies from SchemefulSite needs to access internal origin, 165*6777b538SAndroid Build Coastguard Worker // and SiteForCookies needs to access private method SchemelesslyEqual. 166*6777b538SAndroid Build Coastguard Worker friend class SiteForCookies; 167*6777b538SAndroid Build Coastguard Worker 168*6777b538SAndroid Build Coastguard Worker // Needed to create a bogus origin from a site. 169*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1148927): Give IsolationInfos empty origins instead, 170*6777b538SAndroid Build Coastguard Worker // in this case, and unfriend IsolationInfo. 171*6777b538SAndroid Build Coastguard Worker friend class IsolationInfo; 172*6777b538SAndroid Build Coastguard Worker 173*6777b538SAndroid Build Coastguard Worker // Needed to create a bogus origin from a site. 174*6777b538SAndroid Build Coastguard Worker friend class URLRequest; 175*6777b538SAndroid Build Coastguard Worker 176*6777b538SAndroid Build Coastguard Worker // Needed for access to nonce for serialization. 177*6777b538SAndroid Build Coastguard Worker friend class blink::StorageKey; 178*6777b538SAndroid Build Coastguard Worker 179*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(SchemefulSiteTest, OpaqueSerialization); 180*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(SchemefulSiteTest, InternalValue); 181*6777b538SAndroid Build Coastguard Worker 182*6777b538SAndroid Build Coastguard Worker struct ObtainASiteResult { 183*6777b538SAndroid Build Coastguard Worker url::Origin origin; 184*6777b538SAndroid Build Coastguard Worker bool used_registerable_domain; 185*6777b538SAndroid Build Coastguard Worker }; 186*6777b538SAndroid Build Coastguard Worker 187*6777b538SAndroid Build Coastguard Worker static ObtainASiteResult ObtainASite(const url::Origin&); 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker explicit SchemefulSite(ObtainASiteResult); 190*6777b538SAndroid Build Coastguard Worker 191*6777b538SAndroid Build Coastguard Worker // Deserializes a string obtained from `SerializeWithNonce()` to a 192*6777b538SAndroid Build Coastguard Worker // `SchemefulSite`. Returns nullopt if the value was invalid in any way. 193*6777b538SAndroid Build Coastguard Worker static std::optional<SchemefulSite> DeserializeWithNonce( 194*6777b538SAndroid Build Coastguard Worker const std::string& value); 195*6777b538SAndroid Build Coastguard Worker 196*6777b538SAndroid Build Coastguard Worker // Returns a serialized version of `site_as_origin_`. For an opaque 197*6777b538SAndroid Build Coastguard Worker // `site_as_origin_`, this serializes with the nonce. See 198*6777b538SAndroid Build Coastguard Worker // `url::origin::SerializeWithNonce()` for usage information. 199*6777b538SAndroid Build Coastguard Worker std::optional<std::string> SerializeWithNonce(); 200*6777b538SAndroid Build Coastguard Worker 201*6777b538SAndroid Build Coastguard Worker // Returns whether `this` and `other` share a host or registrable domain. 202*6777b538SAndroid Build Coastguard Worker // Should NOT be used to check equality or equivalence. This is only used 203*6777b538SAndroid Build Coastguard Worker // for legacy same-site cookie logic that does not check schemes. Private to 204*6777b538SAndroid Build Coastguard Worker // restrict usage. 205*6777b538SAndroid Build Coastguard Worker bool SchemelesslyEqual(const SchemefulSite& other) const; 206*6777b538SAndroid Build Coastguard Worker 207*6777b538SAndroid Build Coastguard Worker // Returns the host of the underlying `origin`, which will usually be the 208*6777b538SAndroid Build Coastguard Worker // registrable domain. This is private because if it were public, it would 209*6777b538SAndroid Build Coastguard Worker // trivially allow circumvention of the "Schemeful"-ness of this class. 210*6777b538SAndroid Build Coastguard Worker std::string registrable_domain_or_host() const { 211*6777b538SAndroid Build Coastguard Worker return site_as_origin_.host(); 212*6777b538SAndroid Build Coastguard Worker } 213*6777b538SAndroid Build Coastguard Worker 214*6777b538SAndroid Build Coastguard Worker // This should not be used casually, it's an opaque Origin or an scheme+eTLD+1 215*6777b538SAndroid Build Coastguard Worker // packed into an Origin. If you extract this value SchemefulSite is not 216*6777b538SAndroid Build Coastguard Worker // responsible for any unexpected friction you might encounter. 217*6777b538SAndroid Build Coastguard Worker const url::Origin& internal_value() const { return site_as_origin_; } 218*6777b538SAndroid Build Coastguard Worker 219*6777b538SAndroid Build Coastguard Worker // Origin which stores the result of running the steps documented at 220*6777b538SAndroid Build Coastguard Worker // https://html.spec.whatwg.org/multipage/origin.html#obtain-a-site. 221*6777b538SAndroid Build Coastguard Worker // This is not an arbitrary origin. It must either be an opaque origin, or a 222*6777b538SAndroid Build Coastguard Worker // scheme + eTLD+1 + default port. 223*6777b538SAndroid Build Coastguard Worker // 224*6777b538SAndroid Build Coastguard Worker // The `origin` passed into the SchemefulSite(const url::Origin&) constructor 225*6777b538SAndroid Build Coastguard Worker // might not match this internal representation used by this class to track 226*6777b538SAndroid Build Coastguard Worker // the scheme and eTLD+1 representing a schemeful site. This may be the case 227*6777b538SAndroid Build Coastguard Worker // if, e.g., the passed `origin` has an eTLD+1 that is not equal to its 228*6777b538SAndroid Build Coastguard Worker // hostname, or if the port number is not the default port for its scheme. 229*6777b538SAndroid Build Coastguard Worker // 230*6777b538SAndroid Build Coastguard Worker // In general, this `site_as_origin_` used for the internal representation 231*6777b538SAndroid Build Coastguard Worker // should NOT be used directly by SchemefulSite consumers. 232*6777b538SAndroid Build Coastguard Worker url::Origin site_as_origin_; 233*6777b538SAndroid Build Coastguard Worker }; 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker // Provided to allow gtest to create more helpful error messages, instead of 236*6777b538SAndroid Build Coastguard Worker // printing hex. 237*6777b538SAndroid Build Coastguard Worker // 238*6777b538SAndroid Build Coastguard Worker // Also used so that SchemefulSites can be the arguments of DCHECK_EQ. 239*6777b538SAndroid Build Coastguard Worker NET_EXPORT std::ostream& operator<<(std::ostream& os, const SchemefulSite& ss); 240*6777b538SAndroid Build Coastguard Worker 241*6777b538SAndroid Build Coastguard Worker } // namespace net 242*6777b538SAndroid Build Coastguard Worker 243*6777b538SAndroid Build Coastguard Worker #endif // NET_BASE_SCHEMEFUL_SITE_H_ 244