cookie_util.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright (c) 2012 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. #ifndef NET_COOKIES_COOKIE_UTIL_H_
  5. #define NET_COOKIES_COOKIE_UTIL_H_
  6. #include <string>
  7. #include <vector>
  8. #include "base/callback_forward.h"
  9. #include "base/time/time.h"
  10. #include "net/base/net_export.h"
  11. #include "net/cookies/canonical_cookie.h"
  12. #include "net/cookies/cookie_access_result.h"
  13. #include "net/cookies/cookie_constants.h"
  14. #include "net/cookies/cookie_options.h"
  15. #include "net/cookies/first_party_set_metadata.h"
  16. #include "net/cookies/site_for_cookies.h"
  17. #include "third_party/abseil-cpp/absl/types/optional.h"
  18. #include "url/origin.h"
  19. class GURL;
  20. namespace net {
  21. class IsolationInfo;
  22. class SchemefulSite;
  23. class CookieAccessDelegate;
  24. class CookieInclusionStatus;
  25. namespace cookie_util {
  26. // Constants for use in VLOG
  27. const int kVlogPerCookieMonster = 1;
  28. const int kVlogSetCookies = 7;
  29. const int kVlogGarbageCollection = 5;
  30. // This enum must match the numbering for StorageAccessResult in
  31. // histograms/enums.xml. Do not reorder or remove items, only add new items
  32. // at the end.
  33. enum class StorageAccessResult {
  34. ACCESS_BLOCKED = 0,
  35. ACCESS_ALLOWED = 1,
  36. ACCESS_ALLOWED_STORAGE_ACCESS_GRANT = 2,
  37. kMaxValue = ACCESS_ALLOWED_STORAGE_ACCESS_GRANT,
  38. };
  39. // Helper to fire telemetry indicating if a given request for storage was
  40. // allowed or not by the provided |result|.
  41. NET_EXPORT void FireStorageAccessHistogram(StorageAccessResult result);
  42. // Returns the effective TLD+1 for a given host. This only makes sense for http
  43. // and https schemes. For other schemes, the host will be returned unchanged
  44. // (minus any leading period).
  45. NET_EXPORT std::string GetEffectiveDomain(const std::string& scheme,
  46. const std::string& host);
  47. // Determine the actual cookie domain based on the domain string passed
  48. // (if any) and the URL from which the cookie came.
  49. // On success returns true, and sets cookie_domain to either a
  50. // -host cookie domain (ex: "google.com")
  51. // -domain cookie domain (ex: ".google.com")
  52. // On success, DomainIsHostOnly(url.host()) is DCHECKed. The URL's host must not
  53. // begin with a '.' character.
  54. NET_EXPORT bool GetCookieDomainWithString(const GURL& url,
  55. const std::string& domain_string,
  56. CookieInclusionStatus& status,
  57. std::string* result);
  58. // Returns true if a domain string represents a host-only cookie,
  59. // i.e. it doesn't begin with a leading '.' character.
  60. NET_EXPORT bool DomainIsHostOnly(const std::string& domain_string);
  61. // If |cookie_domain| is nonempty and starts with a "." character, this returns
  62. // the substring of |cookie_domain| without the leading dot. (Note only one
  63. // leading dot is stripped, if there are multiple.) Otherwise it returns
  64. // |cookie_domain|. This is useful for converting from CanonicalCookie's
  65. // representation of a cookie domain to the RFC's notion of a cookie's domain.
  66. NET_EXPORT std::string CookieDomainAsHost(const std::string& cookie_domain);
  67. // Parses the string with the cookie expiration time (very forgivingly).
  68. // Returns the "null" time on failure.
  69. //
  70. // If the expiration date is below or above the platform-specific range
  71. // supported by Time::FromUTCExplodeded(), then this will return Time(1) or
  72. // Time::Max(), respectively.
  73. NET_EXPORT base::Time ParseCookieExpirationTime(const std::string& time_string);
  74. // Get a cookie's URL from it's domain, path, and source scheme.
  75. // The first field can be the combined domain-and-host-only-flag (e.g. the
  76. // string returned by CanonicalCookie::Domain()) as opposed to the domain
  77. // attribute per RFC6265bis. The GURL is constructed after stripping off any
  78. // leading dot.
  79. // Note: the GURL returned by this method is not guaranteed to be valid.
  80. NET_EXPORT GURL CookieDomainAndPathToURL(const std::string& domain,
  81. const std::string& path,
  82. const std::string& source_scheme);
  83. NET_EXPORT GURL CookieDomainAndPathToURL(const std::string& domain,
  84. const std::string& path,
  85. bool is_https);
  86. NET_EXPORT GURL CookieDomainAndPathToURL(const std::string& domain,
  87. const std::string& path,
  88. CookieSourceScheme source_scheme);
  89. // Convenience for converting a cookie origin (domain and https pair) to a URL.
  90. NET_EXPORT GURL CookieOriginToURL(const std::string& domain, bool is_https);
  91. // Returns a URL that could have been the cookie's source.
  92. // Not guaranteed to actually be the URL that set the cookie. Not guaranteed to
  93. // be a valid GURL. Intended as a shim for SetCanonicalCookieAsync calls, where
  94. // a source URL is required but only a source scheme may be available.
  95. NET_EXPORT GURL SimulatedCookieSource(const CanonicalCookie& cookie,
  96. const std::string& source_scheme);
  97. // Provisional evaluation of acceptability of setting secure cookies on
  98. // `source_url` based only on the `source_url`'s scheme and whether it
  99. // is a localhost URL. If this returns kNonCryptographic, it may be upgraded to
  100. // kTrustworthy by a CookieAccessDelegate when the cookie operation is being
  101. // performed, as the delegate may have access to user settings like manually
  102. // configured test domains which declare additional things trustworthy.
  103. NET_EXPORT CookieAccessScheme ProvisionalAccessScheme(const GURL& source_url);
  104. // |domain| is the output of cookie.Domain() for some cookie. This returns true
  105. // if a |domain| indicates that the cookie can be accessed by |host|.
  106. // See comment on CanonicalCookie::IsDomainMatch().
  107. NET_EXPORT bool IsDomainMatch(const std::string& domain,
  108. const std::string& host);
  109. // A ParsedRequestCookie consists of the key and value of the cookie.
  110. using ParsedRequestCookie = std::pair<std::string, std::string>;
  111. using ParsedRequestCookies = std::vector<ParsedRequestCookie>;
  112. // Assumes that |header_value| is the cookie header value of a HTTP Request
  113. // following the cookie-string schema of RFC 6265, section 4.2.1, and returns
  114. // cookie name/value pairs. If cookie values are presented in double quotes,
  115. // these will appear in |parsed_cookies| as well. Assumes that the cookie
  116. // header is written by Chromium and therefore well-formed.
  117. NET_EXPORT void ParseRequestCookieLine(const std::string& header_value,
  118. ParsedRequestCookies* parsed_cookies);
  119. // Writes all cookies of |parsed_cookies| into a HTTP Request header value
  120. // that belongs to the "Cookie" header. The entries of |parsed_cookies| must
  121. // already be appropriately escaped.
  122. NET_EXPORT std::string SerializeRequestCookieLine(
  123. const ParsedRequestCookies& parsed_cookies);
  124. // Determines which of the cookies for the request URL can be accessed, with
  125. // respect to the SameSite attribute. This applies to looking up existing
  126. // cookies for HTTP requests. For looking up cookies for non-HTTP APIs (i.e.,
  127. // JavaScript), see ComputeSameSiteContextForScriptGet. For setting new cookies,
  128. // see ComputeSameSiteContextForResponse and ComputeSameSiteContextForScriptSet.
  129. //
  130. // `url_chain` is a non-empty vector of URLs, the last of which is the current
  131. // request URL. It represents the redirect chain of the current request. The
  132. // redirect chain is used to calculate whether there has been a cross-site
  133. // redirect. In order for a context to be deemed strictly same-site, there must
  134. // not have been any cross-site redirects.
  135. //
  136. // `site_for_cookies` is the currently navigated to site that should be
  137. // considered "first-party" for cookies.
  138. //
  139. // `initiator` is the origin ultimately responsible for getting the request
  140. // issued. It may be different from `site_for_cookies`.
  141. //
  142. // absl::nullopt for `initiator` denotes that the navigation was initiated by
  143. // the user directly interacting with the browser UI, e.g. entering a URL
  144. // or selecting a bookmark.
  145. //
  146. // `is_main_frame_navigation` is whether the request is for a navigation that
  147. // targets the main frame or top-level browsing context. These requests may
  148. // sometimes send SameSite=Lax cookies but not SameSite=Strict cookies.
  149. //
  150. // If `force_ignore_site_for_cookies` is specified, all SameSite cookies will be
  151. // attached, i.e. this will return SAME_SITE_STRICT. This flag is set to true
  152. // when the `site_for_cookies` is a chrome:// URL embedding a secure origin,
  153. // among other scenarios.
  154. // This is *not* set when the *initiator* is chrome-extension://,
  155. // which is intentional, since it would be bad to let an extension arbitrarily
  156. // redirect anywhere and bypass SameSite=Strict rules.
  157. //
  158. // See also documentation for corresponding methods on net::URLRequest.
  159. //
  160. // `http_method` is used to enforce the requirement that, in a context that's
  161. // lax same-site but not strict same-site, SameSite=lax cookies be only sent
  162. // when the method is "safe" in the RFC7231 section 4.2.1 sense.
  163. NET_EXPORT CookieOptions::SameSiteCookieContext
  164. ComputeSameSiteContextForRequest(const std::string& http_method,
  165. const std::vector<GURL>& url_chain,
  166. const SiteForCookies& site_for_cookies,
  167. const absl::optional<url::Origin>& initiator,
  168. bool is_main_frame_navigation,
  169. bool force_ignore_site_for_cookies);
  170. // As above, but applying for scripts. `initiator` here should be the initiator
  171. // used when fetching the document.
  172. // If `force_ignore_site_for_cookies` is true, this returns SAME_SITE_STRICT.
  173. NET_EXPORT CookieOptions::SameSiteCookieContext
  174. ComputeSameSiteContextForScriptGet(const GURL& url,
  175. const SiteForCookies& site_for_cookies,
  176. const absl::optional<url::Origin>& initiator,
  177. bool force_ignore_site_for_cookies);
  178. // Determines which of the cookies for the request URL can be set from a network
  179. // response, with respect to the SameSite attribute. This will only return
  180. // CROSS_SITE or SAME_SITE_LAX (cookie sets of SameSite=strict cookies are
  181. // permitted in same contexts that sets of SameSite=lax cookies are).
  182. // `url_chain` is a non-empty vector of URLs, the last of which is the current
  183. // request URL. It represents the redirect chain of the current request. The
  184. // redirect chain is used to calculate whether there has been a cross-site
  185. // redirect.
  186. // `is_main_frame_navigation` is whether the request was for a navigation that
  187. // targets the main frame or top-level browsing context. Both SameSite=Lax and
  188. // SameSite=Strict cookies may be set by any main frame navigation.
  189. // If `force_ignore_site_for_cookies` is true, this returns SAME_SITE_LAX.
  190. NET_EXPORT CookieOptions::SameSiteCookieContext
  191. ComputeSameSiteContextForResponse(const std::vector<GURL>& url_chain,
  192. const SiteForCookies& site_for_cookies,
  193. const absl::optional<url::Origin>& initiator,
  194. bool is_main_frame_navigation,
  195. bool force_ignore_site_for_cookies);
  196. // Determines which of the cookies for `url` can be set from a script context,
  197. // with respect to the SameSite attribute. This will only return CROSS_SITE or
  198. // SAME_SITE_LAX (cookie sets of SameSite=strict cookies are permitted in same
  199. // contexts that sets of SameSite=lax cookies are).
  200. // If `force_ignore_site_for_cookies` is true, this returns SAME_SITE_LAX.
  201. NET_EXPORT CookieOptions::SameSiteCookieContext
  202. ComputeSameSiteContextForScriptSet(const GURL& url,
  203. const SiteForCookies& site_for_cookies,
  204. bool force_ignore_site_for_cookies);
  205. // Determines which of the cookies for |url| can be accessed when fetching a
  206. // subresources. This is either CROSS_SITE or SAME_SITE_STRICT,
  207. // since the initiator for a subresource is the frame loading it.
  208. NET_EXPORT CookieOptions::SameSiteCookieContext
  209. // If |force_ignore_site_for_cookies| is true, this returns SAME_SITE_STRICT.
  210. ComputeSameSiteContextForSubresource(const GURL& url,
  211. const SiteForCookies& site_for_cookies,
  212. bool force_ignore_site_for_cookies);
  213. // Returns whether the respective feature is enabled.
  214. NET_EXPORT bool IsSchemefulSameSiteEnabled();
  215. // Computes the First-Party Sets metadata, determining which of the cookies for
  216. // `request_site` can be accessed. `isolation_info` must be fully populated. If
  217. // `force_ignore_top_frame_party` is true, the top frame from `isolation_info`
  218. // will be assumed to be same-party with `request_site`, regardless of what it
  219. // is.
  220. //
  221. // The result may be returned synchronously, or `callback` may be invoked
  222. // asynchronously with the result. The callback will be invoked iff the return
  223. // value is nullopt; i.e. a result will be provided via return value or
  224. // callback, but not both, and not neither.
  225. [[nodiscard]] NET_EXPORT absl::optional<FirstPartySetMetadata>
  226. ComputeFirstPartySetMetadataMaybeAsync(
  227. const SchemefulSite& request_site,
  228. const IsolationInfo& isolation_info,
  229. const CookieAccessDelegate* cookie_access_delegate,
  230. bool force_ignore_top_frame_party,
  231. base::OnceCallback<void(FirstPartySetMetadata)> callback);
  232. // Get the SameParty inclusion status. If the cookie is not SameParty, returns
  233. // kNoSamePartyEnforcement; if the cookie is SameParty but does not have a
  234. // valid context, returns kEnforceSamePartyExclude.
  235. NET_EXPORT CookieSamePartyStatus
  236. GetSamePartyStatus(const CanonicalCookie& cookie,
  237. const CookieOptions& options,
  238. bool first_party_sets_enabled);
  239. // Takes a callback accepting a CookieAccessResult and returns a callback
  240. // that accepts a bool, setting the bool to true if the CookieInclusionStatus
  241. // in CookieAccessResult was set to "include", else sending false.
  242. //
  243. // Can be used with SetCanonicalCookie when you don't need to know why a cookie
  244. // was blocked, only whether it was blocked.
  245. NET_EXPORT base::OnceCallback<void(CookieAccessResult)>
  246. AdaptCookieAccessResultToBool(base::OnceCallback<void(bool)> callback);
  247. // Turn a CookieAccessResultList into a CookieList by stripping out access
  248. // results (for callers who only care about cookies).
  249. NET_EXPORT CookieList
  250. StripAccessResults(const CookieAccessResultList& cookie_access_result_list);
  251. // Records port related metrics from Omnibox navigations.
  252. NET_EXPORT void RecordCookiePortOmniboxHistograms(const GURL& url);
  253. // Checks invariants that should be upheld w.r.t. the included and excluded
  254. // cookies. Namely: the included cookies should be elements of
  255. // `included_cookies`; excluded cookies should be elements of
  256. // `excluded_cookies`; and included cookies should be in the correct sorted
  257. // order.
  258. NET_EXPORT void DCheckIncludedAndExcludedCookieLists(
  259. const CookieAccessResultList& included_cookies,
  260. const CookieAccessResultList& excluded_cookies);
  261. } // namespace cookie_util
  262. } // namespace net
  263. #endif // NET_COOKIES_COOKIE_UTIL_H_