README.md
1# Cookies
2
3*** aside
4_"In the beginning ~~the Universe was~~ cookies were created. This has
5made a lot of people very angry and has been widely regarded as a bad move."_
6
7_"Sometimes me think, what is friend? And then me say: a friend is someone to
8share last cookie with."_
9***
10
11This directory is concerned with the management of cookies, as specified by
12[RFC 6265bis](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis).
13Cookies are implemented mostly in this directory, but also elsewhere, as
14described [below](#Cookie-implementation-classes).
15
16*** promo
17* Those who wish to work with the implementation of cookies may refer to
18 [Life of a cookie](#Life-of-a-cookie) and
19 [Cookie implementation classes](#Cookie-implementation-classes).
20
21* Those who wish to make use of cookies elsewhere in Chromium may refer to
22 [Main interfaces for finding, setting, deleting, and observing cookies](#Main-interfaces-for-finding_setting_deleting_and-observing-cookies).
23***
24
25[TOC]
26
27## Life of a cookie
28
29This section describes the lifecycle of a typical/simple cookie on most
30platforms, and serves as an overview of some important classes involved in
31managing cookies.
32
33This only covers cookie accesses via
34[HTTP requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies).
35Other APIs for accessing cookies include JavaScript
36([`document.cookie`](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie)
37and [CookieStore API](https://wicg.github.io/cookie-store/)) or Chrome
38extensions
39([`chrome.cookies`](https://developer.chrome.com/extensions/cookies)).
40
41### Cookie is received and parsed
42
43*** note
44**Summary:**
45
461. An HTTP response containing a `Set-Cookie` header is received.
472. The `Set-Cookie` header is processed by `URLRequestHttpJob`.
483. The header contents are parsed into a `CanonicalCookie` and passed to the
49 `CookieStore` for storage.
50***
51
52A cookie starts as a `Set-Cookie` header sent in the server's response to an
53HTTP request:
54
55```
56HTTP/1.1 200 OK
57Date: ...
58Server: ...
59...
60Set-Cookie: chocolate_chip=tasty; Secure; SameSite=Lax; Max-Age=3600
61```
62
63The response passes through the `HttpNetworkTransaction` and
64`HttpCache::Transaction` to the `URLRequestHttpJob`. (See
65[Life of a `URLRequest`](/net/docs/life-of-a-url-request.md#send-request-and-read-the-response-headers)
66for more details.) The `URLRequestHttpJob` then reads any `Set-Cookie` headers
67in the response (there may be multiple) and processes each `Set-Cookie` header
68by calling into `//net/cookies` classes for parsing and storing:
69
70First, the cookie, which has been provided as a string, is parsed into a
71`ParsedCookie`. This struct simply records all the token-value pairs present in
72the `Set-Cookie` header and keeps track of which cookie attribute each
73corresponds to. The first token-value pair is always treated as the cookie's
74name and value.
75
76The `ParsedCookie` is then converted into a `CanonicalCookie`. This is the main
77data type representing cookies. Any cookie consumer that does not deal directly
78with HTTP headers operates on `CanonicalCookie`s. A `CanonicalCookie` has some
79additional guarantees of validity over a `ParsedCookie`, such as valid
80expiration times, valid domain and path attributes, etc. Once a
81`CanonicalCookie` is created, you will almost never see a `ParsedCookie` used
82for anything else.
83
84If a valid `CanonicalCookie` could not be created (due to some illegal syntax,
85inconsistent attribute values, or other circumstances preventing parsing), then
86we stop here, and `URLRequestHttpJob` moves on to the next `Set-Cookie` header.
87
88The `NetworkDelegate` also gets a chance to block the setting of the cookie,
89based on the user's third-party cookie blocking settings. If it is blocked,
90`URLRequestHttpJob` likewise moves on to the next `Set-Cookie` header.
91
92If this did result in a valid and not-blocked `CanonicalCookie`, it is then
93passed to the `CookieStore` to be stored.
94
95### Cookie is stored
96
97*** note
98**Summary:**
99
1001. The `CookieStore` receives the `CanonicalCookie` and validates some
101 additional criteria before updating its in-memory cache of cookies.
1022. The `CookieStore` may also update its on-disk backing store via the
103 `CookieMonster::PersistentCookieStore` interface.
1043. The result of the cookie storage attempt is reported back to the
105 `URLRequestHttpJob`.
106***
107
108The `CookieStore` lives in the `URLRequestContext` and its main implementation,
109used for most platforms, is `CookieMonster`. (The rest of this section assumes
110that we are using a `CookieMonster`.) It exposes an asynchronous interface for
111storing and retrieving cookies.
112
113When `CookieMonster` receives a `CanonicalCookie` to be set, it queues a task to
114validate and set the cookie. Most of the time this runs immediately, but it may
115be delayed if the network service has just started up, and the contents of the
116`PersistentCookieStore` are still being loaded from disk. It checks some
117criteria against the cookie's source URL and a `CookieOptions` object (which
118contains some other parameters describing the "context" in which the cookie is
119being set, such as whether it's being accessed in a same-site or cross-site
120context).
121
122If everything checks out, the `CookieMonster` proceeds with setting the cookie.
123If an equivalent cookie is present in the store, then it may be deleted.
124Equivalent is defined as sharing a name, domain, and path, based on the
125invariant specified by the RFC that no two such cookies may exist at a given
126time. `CookieMonster` stores its `CanonicalCookie`s in a multimap keyed on the
127registrable domain (eTLD+1) of the cookie's domain attribute.
128
129The cookie may also be persisted to disk by a
130`CookieMonster::PersistentCookieStore` depending on factors like whether the
131cookie is a persistent cookie (has an expiration date), whether session cookies
132should also be persisted (e.g. if the browser is set to restore the previous
133browsing session), and whether the profile should have persistent storage (e.g.
134yes for normal profiles, but not for Incognito profiles). The
135`SQLitePersistentCookieStore` is the main implementation of
136`CookieMonster::PersistentCookieStore`. It stores cookies in a SQLite database
137on disk, at a filepath specified by the user's profile.
138
139After the cookie has been stored (or rejected), the `CookieMonster` calls back
140to the `URLRequestHttpJob` with the outcome of the storage attempt. The
141`URLRequestHttpJob` stashes away the outcomes and stores them in the
142`URLRequest` after all `Set-Cookie` headers in the response are processed, so
143that interested parties (e.g. DevTools) can subsequently be notified of cookie
144activity.
145
146### Cookie is retrieved and sent
147
148*** note
149**Summary:**
150
1511. A network request reaches the net stack and generates a `URLRequestHttpJob`,
152 which queries the `CookieStore` for cookies to include with the request.
1532. The `CookieStore` evaluates each of its candidate cookies for whether it can
154 be included in the request, and reports back to the `URLRequestHttpJob` with
155 included and excluded cookies.
1563. `URLRequestHttpJob` serializes the included cookies into a `Cookie` request
157 header and attaches it to the outgoing request.
158***
159
160Some time later, a (credentialed) request to the same eTLD+1 triggers a cookie
161access in order to retrieve the relevant cookies to include in the outgoing
162`Cookie` request header. The request makes its way to the net stack and causes a
163`URLRequestHttpJob` to be created. (See
164[Life of a `URLRequest`](/net/docs/life-of-a-url-request.md#check-the-cache_request-an-httpstream)
165for more details.) Upon being started, the `URLRequestHttpJob` asks the
166`CookieStore` to retrieve the correct cookies for the URL being requested.
167
168The `CookieMonster` queues a task to retrieve the cookies. Most of the time this
169runs immediately, except if the contents of the `PersistentCookieStore` are
170still being loaded from disk. The `CookieMonster` examines each of the cookies
171it has stored for that URL's registrable domain and decides whether it should be
172included or excluded for that request based on the requested URL and the
173`CookieOptions`, by computing a `CookieInclusionStatus`. Criteria for inclusion
174are described in
175[RFC 6265bis](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis#section-5.5)
176and include: the URL matching the cookie's `Domain` and `Path` attributes, the
177URL being secure if the cookie has the `Secure` attribute, the request context
178(i.e. `CookieOptions`) being same-site if the cookie is subject to `SameSite`
179enforcement, etc. If any of the requirements are not met, a
180`CookieInclusionStatus::ExclusionReason` is recorded.
181
182After the exclusion reasons have been tallied up for each cookie, the cookies
183without any exclusion reasons are deemed suitable for inclusion, and are
184returned to the `URLRequestHttpJob`. The excluded cookies are also returned,
185along with the `CookieInclusionStatus` describing why each cookie was excluded.
186
187The included cookies are serialized into a `Cookie` header string (if the
188`NetworkDelegate` is ok with it, based on the user's third-party cookie blocking
189settings). The `URLRequestHttpJob` attaches this `Cookie` header to the outgoing
190request headers:
191
192```
193GET /me/want/cookie/omnomnomnom HTTP/1.1
194Host: ...
195User-Agent: ...
196Cookie: chocolate_chip=tasty
197...
198```
199
200The included cookies, excluded cookies, and their corresponding
201`CookieInclusionStatus`es are also stored in the `URLRequest` to notify
202consumers of cookie activity notifications.
203
204## Cookie implementation classes
205
206This section lists classes involved in cookie management and access.
207
208The core classes are highlighted.
209
210### In this directory (//net/cookies)
211
212*** note
213* **[`CanonicalCookie`](/net/cookies/canonical_cookie.h)**
214
215 The main data type representing cookies. Basically everything that's not
216 directly dealing with HTTP headers or their equivalents operates on these.
217
218 These are generally obtained via `CanonicalCookie::Create()`, which parses a
219 string (a `Set-Cookie` header) into an intermediate `ParsedCookie`, whose
220 fields it canonicalizes/validates and then copies into a `CanonicalCookie`.
221***
222
223*** note
224* **[`CookieStore`](/net/cookies/cookie_store.h)**
225
226 The main interface for a given platform's cookie handling. Provides
227 asynchronous methods for setting and retrieving cookies.
228
229 Its implementations are responsible for keeping track of all the cookies,
230 finding cookies relevant for given HTTP requests, saving cookies received in
231 HTTP responses, etc., and need to know quite a bit about cookie semantics.
232***
233
234*** note
235* **[`CookieMonster`](/net/cookies/cookie_monster.h)**
236
237 The implementation of `CookieStore` used on most platforms.
238
239 It stores all cookies in a multimap keyed on the eTLD+1 of the cookie's
240 domain. Also manages storage limits by evicting cookies when per-eTLD+1 or
241 global cookie counts are exceeded.
242
243 It can optionally take an implementation of
244 `CookieMonster::PersistentCookieStore` to load and store cookies
245 persisently.
246***
247
248* [`CookieOptions`](/net/cookies/cookie_options.h)
249
250 Contains parameters for a given attempt to access cookies via
251 `CookieStore`, such as whether the access is for an HTTP request (as opposed
252 to a JavaScript API), and the same-site or cross-site context of the request
253 (relevant to enforcement of the `SameSite` cookie attribute).
254
255* [`SiteForCookies`](/net/cookies/site_for_cookies.h)
256
257 Represents which origins should be considered "same-site" for a given
258 context (e.g. frame). This is used to compute the same-site or cross-site
259 context of a cookie access attempt (which is then conveyed to the
260 `CookieStore` via a `CookieOptions`).
261
262 It is generally the eTLD+1 and scheme of the top-level frame. It may also be
263 empty, in which case it represents a context that is cross-site to
264 everything (e.g. a nested iframe whose ancestor frames don't all belong to
265 the same site).
266
267* [`CookieInclusionStatus`](/net/cookies/cookie_inclusion_status.h)
268
269 Records the outcome of a given attempt to access a cookie. Various reasons
270 for cookie exclusion are recorded
271 (`CookieInclusionStatus::ExclusionReason`), as well as informational
272 statuses (`CookieInclusionStatus::WarningReason`) typically used to emit
273 warnings in DevTools.
274
275 May be used as a member of a `CookieAccessResult`, which includes even more
276 metadata about the outcome of a cookie access attempt.
277
278* [`CookieAccessDelegate`](/net/cookies/cookie_access_delegate.h)
279
280 Interface for a `CookieStore` to query information from its embedder that
281 may modify its decisions on cookie inclusion/exclusion. Its main
282 implementation allows `CookieMonster` to access data from the network
283 service layer (e.g. `CookieManager`).
284
285* [`CookieChangeDispatcher`](/net/cookies/cookie_monster_change_dispatcher.h)
286
287 Interface for subscribing to changes in the contents of the `CookieStore`.
288 The main implementation is `CookieMonsterChangeDispatcher`.
289
290### Elsewhere in //net
291
292*** note
293* **[`SQLitePersistentCookieStore`](/net/extras/sqlite/sqlite_persistent_cookie_store.h)**
294
295 Implementation of `CookieMonster::PersistentCookieStore` used on most
296 platforms. Uses a SQLite database to load and store cookies, potentially
297 using an optional delegate to encrypt and decrypt their at-rest versions.
298 This class is refcounted.
299
300 `CookieMonster` loads cookies from here on startup. All other operations
301 attempting to access cookies in the process of being loaded are blocked
302 until loading of those cookies completes. Thus, it fast-tracks loading of
303 cookies for an eTLD+1 with pending requests, to decrease latency for
304 cookie access operations made soon after browser startup (by decreasing the
305 number of cookies whose loading is blocking requests).
306***
307
308*** note
309* **[`URLRequestHttpJob`](/net/url_request/url_request_http_job.h)**
310
311 A `URLRequestJob` implementation that handles HTTP requests; most
312 relevantly, the `Cookie` and `Set-Cookie` HTTP headers. It drives the
313 process for storing cookies and retrieving cookies for HTTP requests.
314
315 Also logs cookie events to the NetLog for each request.
316***
317
318* [`URLRequest`](/net/url_request/url_request.h)
319
320 Mostly relevant for its two members, `maybe_sent_cookies_` and
321 `maybe_stored_cookies_`, which are vectors in which `URLRequestHttpJob`
322 stashes the cookies it considered sending/storing and their
323 `CookieInclusionStatus`es. These then get mojo'ed over to the browser
324 process to notify observers of cookie activity.
325
326### In //services/network
327
328*** note
329* **[`CookieManager`](/services/network/cookie_manager.h)**
330
331 The network service API to cookies. Basically exports a `CookieStore` via
332 mojo IPC.
333
334 Owned by the `NetworkContext`.
335***
336
337*** note
338* **[`RestrictedCookieManager`](/services/network/restricted_cookie_manager.h)**
339
340 Mojo interface for accessing cookies for a specific origin. This can be
341 handed out to untrusted (i.e. renderer) processes, as inputs are assumed to
342 be unsafe.
343
344 It is primarily used for accessing cookies via JavaScript.
345 It provides a synchronous interface for
346 [`document.cookie`](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie),
347 as well as an asynchronous one for the [CookieStore API](https://wicg.github.io/cookie-store/).
348***
349
350* [`CookieSettings`](/services/network/cookie_settings.h)
351
352 Keeps track of the content settings (per-profile
353 [permissions](/components/permissions/README.md) for types of
354 content that a given origin is allowed to use) for cookies, such as the
355 user's third-party cookie blocking settings, origins/domains with
356 third-party cookie blocking exceptions or "legacy" access settings.
357
358 It is not to be confused with `content_settings::CookieSettings`, which
359 manages the browser's version of the cookie content settings, of which
360 `network::ContentSettings` is approximately a copy/mirror. The
361 `ProfileNetworkContextService` populates its contents upon `NetworkContext`
362 construction from the browser-side content settings, and also updates it
363 whenever the browser-side content settings change.
364
365* [`SessionCleanupCookieStore`](/services/network/session_cleanup_cookie_store.h)
366
367 Implements `CookieMonster::PersistentCookieStore`, by wrapping a
368 `SQLitePersistentCookieStore`. Keeps an in-memory map of cookies per eTLD+1
369 to allow deletion of cookies for sites whose cookie content setting is
370 "session-only" from the persistent store when the session ends.
371
372
373### Elsewhere
374
375* [`CookieAccessObserver`](/services/network/public/mojom/cookie_access_observer.mojom)
376 and [`WebContentsObserver`](/content/public/browser/web_contents_observer.h)
377
378 `CookieAccessObserver` is a mojo interface used to observe attempts to
379 access (read or write) cookies. It is implemented by `NavigationHandle` and
380 `RenderFrameHost`.
381
382 The cookie accesses are attributable to a committed document that called
383 `document.cookie` or made a network request (if notified through
384 `RenderFrameHost`), or a not-yet-committed navigation that resulted in a
385 network request (if notified through `NavigationHandle`).
386
387 The `CookieAccessObserver`s forward the notifications to `WebContents`,
388 which then notifies its `WebContentsObserver`s. One such
389 `WebContentsObserver` that cares about this information is
390 `PageSpecificContentSettings`, which displays information about allowed and
391 blocked cookies in UI surfaces (see next item).
392
393* [`CookiesTreeModel`](/chrome/browser/browsing_data/cookies_tree_model.h)
394
395 Stores cookie information for use in settings UI (the Page Info Bubble and
396 various `chrome://settings` pages). Populated with info from
397 `PageSpecificContentSettings`.
398
399* [`CookieJar`](/third_party/blink/renderer/core/loader/cookie_jar.h)
400
401 Implements the `document.cookie` API in the renderer by requesting a
402 `RestrictedCookieManager` from the browser.
403
404* [`CookieStore`](/third_party/blink/renderer/modules/cookie_store/cookie_store.h)
405
406 Implements the JavaScript
407 [CookieStore API](https://wicg.github.io/cookie-store/) in the renderer by
408 requesting a `RestrictedCookieManager` from the browser. (Not to be confused
409 with `net::CookieStore`.)
410
411* [`CookiesAPI`](/chrome/browser/extensions/api/cookies/cookies_api.h)
412
413 Implements the
414 [`chrome.cookies`](https://developer.chrome.com/extensions/cookies) API for
415 Chrome extensions. Gives extensions with the proper permissions essentially
416 unfettered access to the `CookieStore`.
417
418### Platform-specific
419
420* [`CookieStoreIOS` and `CookieStoreIOSPersistent`](/ios/net/cookies)
421
422 iOS-specific `CookieStore` implementations, mainly relying on the iOS native
423 cookie implementation (`NSHTTPCookie`).
424
425* [`android_webview::CookieManager`](/android_webview/browser/cookie_manager.h)
426
427 Manages cookies for Android WebView. It typically wraps a
428 `network::mojom::CookieManager`, but it can also be used before a
429 `NetworkContext` even exists, thanks to Android WebView's
430 [cookie API](https://developer.android.com/reference/kotlin/android/webkit/CookieManager),
431 which means it is sometimes initialized with a bare `net::CookieStore`.
432
433 Also notable for allowing cookies for `file://` scheme URLs (normally they
434 are only allowed for HTTP and websocket schemes and `chrome-extension://`),
435 though this is non-default and deprecated.
436
437## Main interfaces for finding, setting, deleting, and observing cookies
438
439This section summarizes interfaces for interacting with cookies from various
440parts of the codebase.
441
442### From //net or //services/network
443
444*** note
445Use [`net::CookieStore`](/net/cookies/cookie_store.h) to save and retrieve
446[`CanonicalCookie`](/net/cookies/canonical_cookie.h)s.
447***
448
449* `CanonicalCookie`s are the main data type representing cookies. Get one using
450 `CanonicalCookie::Create()`.
451
452* The `CookieStore` can be accessed via its owning `URLRequestContext`, which
453 can be accessed through `NetworkContext`.
454
455* To access cookies, you need a `CookieOptions`. The main things in this object
456 are the `HttpOnly` access permission and the `SameSite` context. The latter
457 can be obtained from [`cookie_util`](/net/cookies/cookie_util.h) functions.
458
459* Retrieve cookies using `GetCookieListWithOptionsAsync()`.
460
461* Save cookies using `SetCanonicalCookieAsync()`.
462
463*** note
464Use `CookieStore` to selectively delete cookies.
465***
466
467* `DeleteCanonicalCookieAsync()` deletes a single cookie.
468
469* `DeleteAllCreatedInTimeRangeAsync()` deletes cookies created in a time range.
470
471* `DeleteAllMatchingInfoAsync()` deletes cookies that match a filter.
472
473*** note
474Use the [`CookieChangeDispatcher`](/net/cookies/cookie_change_dispatcher.h)
475interface to subscribe to changes.
476***
477
478* Use `AddCallbackForCookie()` to observe changes to cookies with a given name
479 that would be sent with a request to a specific URL.
480
481* Use `AddCallbackForUrl()` to observe changes to all cookies that would be sent
482 with a request to a specific URL.
483
484* Use `AddCallbackForAllChanges()` to observe changes to all cookies in the
485 `CookieStore`.
486
487### From the browser process
488
489*** note
490Use [`CookieManager`](/services/network/cookie_manager.h)
491(which basically exports a `net::CookieStore` interface via mojo) to save
492and retrieve [`CanonicalCookie`](/net/cookies/canonical_cookie.h)s.
493***
494
495* The profile's `CookieManager` can be accessed from the browser process through
496 `StoragePartition::GetCookieManagerForBrowserProcess()`.
497
498* You can also get get a `CookieManager` pipe from the `NetworkContext` using
499 `GetCookieManager()`.
500
501* Retrieve cookies using `CookieManager::GetCookieList()`.
502
503* Save cookies using `CookieManager::SetCanonicalCookie()`.
504
505*** note
506Use `CookieManager` to selectively delete cookies.
507***
508
509* If you have a copy of the `CanonicalCookie` to delete (e.g. a cookie
510 previously fetched from the store), use
511 `CookieManager::DeleteCanonicalCookie()`.
512
513* To delete cookies with certain characteristics, construct a
514 [`CookieDeletionFilter`](/services/network/public/mojom/cookie_manager.mojom)
515 and use `CookieManager::DeleteCookies()`.
516
517*** note
518Use `CookieManager`'s change listener interface to subscribe to changes (this
519parallels the `net::CookieChangeDispatcher` interface).
520***
521
522* Add a `CookieChangeListener` registration for a URL (and optionally a cookie
523 name) via `AddCookieChangeListener()`
524
525* Add a `CookieChangeListener` registration for all cookies via
526 `AddGlobalChangeListener()`.
527
528### From untrusted (e.g. renderer) processes
529
530*** note
531Use a
532[`network::mojom::RestrictedCookieManager`](/services/network/public/mojom/restricted_cookie_manager.mojom)
533interface to access cookies for a particular origin.
534***
535
536* Request a `RestrictedCookieManager` interface from the browser. This creates a
537 `RestrictedCookieManager` bound to a `RenderFrameHost`, which can only access
538 cookies on behalf of the corresponding origin.
539
540* Cookies can be read and written asynchronously (`GetAllForUrl()`,
541 `SetCanonicalCookie()`) or synchronously (`SetCookieFromString()`,
542 `GetCookiesString()`).
543
544* [Compromised renderers](/docs/security/compromised-renderers.md#Cookies)
545 shouldn't be able to access cookies of another site, or `HttpOnly` cookies
546 (even from the same site).
547