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