About
A cookie is:
The received cookies by the browser can be seen in their devtool
Example
With the Set-Cookie header, we can create the following session cookie with:
- the name session,
- the value de73c7e08a3753ac6b2f
- that should be deleted at Thu, 18-Apr-19 07:29:28 GMT
- that should not be accessible to javascript (ie httponly)
- and should be send only over HTTPS because of its secure property
Header:
- in a http response returned by the server
Set-Cookie: session=de73c7e08a3753ac6b2f; expires=Thu, 18-Apr-19 07:29:28 GMT; path=/; domain=.example.com; HttpOnly; Secure
- in a http request created by the client (generally the browser).
Cookie: session=de73c7e08a3753ac6b2f; expires=Thu, 18-Apr-19 07:29:28 GMT; path=/; domain=.example.com; HttpOnly; Secure
How does the cookie mechanism work ?
A cookie is:
- set initially:
- by the server side with a HTTP response and the Set-Cookie header
- and eventually on a client-side with the browser web api
- stored in the browser (ie all user’s agent web-enabled device
- send back by the browser for each HTTP request with the Cookies header (via subsequent user interactions). For instance, every time the user loads a page of a website, the browser may send the cookie back to the server that are within the scope.
In a nutshell, a cookie is a mechanism:
- for an server (web server) to send state information (cookie) to a user agent (browser)
- and for the user agent (browser) to return the state information (cookie) to the server.
The (HTTP Cookie and Set-Cookie) header fields can be used by HTTP servers to store state (called cookies) at HTTP user agents, letting the servers maintain a stateful session over the stateless HTTP protocol.
Usage
Identify Individual
Cookies often store behavioral information.
Session Cookie
Cookies are the preferred way for servers to track sessions. The server supplies a cookie, in response to a request. The server expects the client to send that piece of data in a header field with each following request of the same session. The cookie is different for each session, so the server can identify to which session a request belongs by looking at the cookie.
Cookies help to identify individual clients (without being authenticated) behind a shared IP address (HotSpot, Proxy, Vpn, …) and apply functionality on a per-client basis (security,…).
To keep anonymity and not be able to personally identify the client, the End User IP addresses (user-level data) should be stored as a one-way hash.
This sort of cookie is session cookie with an expiration duration generally of 30 days.
Tracking cookie
A tracking cookie does not track a session but a user.
The user cookie is updated with a new expiration date and re-sent on every response, extending the lifetime out.
if ("request contains an id cookie") {
"Record that cookie as the user identifier"
"Set that cookie with a now+1 year cookie expiry"
} else {
"Set the id cookie with a now+1 year cookie expiry"
}
For more information, see this dedicated page: How does a tracking cookie work? A step by step example
You can follow users from site to site by merging various cookie identifiers into a profile. See Cross-site tracking
Authentication
Identifying an individual is not always bad as you need to authenticate a user. Cookies are the most common way to authenticate an individual and to give him some authorization (access to a backend, etc…).
Bad Bot Protection
A cookie may be used in bad bot protection.
When identifying an activity as a potential bad bot activity:
- the user is presented with a challenge. If the End User passes the challenge, a session cookie prevents additional challenges for up to generally 30 minutes.
- a cookie is send and as generally the bot application does not manage the cookie, the cookie is not send back and may help in bad activity detection.
AB Testing
Cookie are used to set the bucket to a user when running an A/B testing.
Load Balancer Session Affinity
On a load balancer, you may want to send every request of the same user session to the same node.
For this purpose, a session cookie can be used to create a session (max 24 hours) and route all future requests of this session to the same origin (same server in the cluster).
This is important when you are keeping user data on the server side.
For instance, suppose that you store a shopping cart on the server side. Without session affinity, every user action will be redirected to another server (node) in the cluster. You may seen this kind of sequence:
- the user adds an item, the load balancer sends it to the server A that stores it locally
- the user want to see its shopping card, the load balancer sends it to the server B. The server B cannot see items from the server A and therefore the user don't see any items in the shopping cart.
In the event of a failover, a new session cookie should be created.
Security Considerations
CSRF
When the browser makes a request (img, form), the cookies are by default send even if the request comes from another page on another domain.
This means that if you set a cookie on your website that identifies you, a malicious request created from another page will also get this cookies and produces a valid request in your name. This attack is know as Cross-site Request Forgery
HttpOnly
When you tag a cookie with the httponly flag, this cookie can not be accessed by the browser api. (ie it's only added in request to the server)
Example:
Set-Cookie: user=t=bfabf0b1c1133a822; path=/; HttpOnly
For historical reasons, cookies contain a number of security and privacy infelicities.
For example:
- a server can indicate that a given cookie is intended for “secure” connections, but the Secure attribute does not provide integrity in the presence of an active network attacker.
- cookies for a given host are shared across all the ports on that host, even though the usual same-origin policy used by web browsers isolates content retrieved via different ports.
First party vs Third Party
If the domain property of the cookie is the same as the domain of the page shown in the address bar of the web browser:
- this is a First-party cookies (ie cookie created by the site you visit)
- otherwise they are Third-party cookies (ie cookie created by other sites. These sites own some of the content, like ads or images, that you see and was included on the webpage you visit.)
Weak Integrity
Cookie value and properties can be changed easily.
This risks can be mitigated by encrypting and signing the contents of the cookies.
No Isolation by Port and Scheme
Cookies are isolated by scope (and not by origin).
Because the scope syntax does not contain the port nor the scheme
- If a cookie is readable by a service running on one port, the cookie is also readable by a service running on another port (scheme) of the same server.
- If a cookie is writable by a service running on one port, the cookie is also writable by a service running on another port (scheme) of the same server.
ie A site running on the http (port 80) can set a cookie for a site running on https (port 443).
Subdomain Overwriting
The foo.example.com server can create / set a cookie with a Domain attribute of example.com:
- even if a previous cookie was created by bar.example.com,
- and the user agent will include/send also that cookie in HTTP requests to bar.example.com.
Definition
Name
The cookie's name.
Value
The cookie's value.
Properties
All below cookies properties defined when and if the cookie should be added to the request via the cookies header created by the user agent (ie browser).
Domain
See Cookie - Scope
Path
See Cookie - Scope
max-age
max-age is a property that is part of the expiration date calculation
More see How is the Cookie Expiration date calculated? (max-age)
Expires
Expires is a property that is part of the expiration date calculation
More see How is the Cookie Expiration date calculated? (max-age)
HttpOnly
The HttpOnly flag tells the browser that this particular cookie should only be accessed by the server (not by the client)
In other words, if this flag is on, the javascript cookie web api cannot read the cookie
Secure
When a cookie has the Secure attribute, the user agent (browser) will include the cookie only if the request is transmitted over a secure channel (typically HTTPS (HTTP over Transport Layer Security)).
SameSite
The SameSite cookie parameters control if the cookie should only be sent with requests initiated from the same origin.
See What is the SameSite Cookie property? First-Party and third-party cookie control
Management
You can manage cookie:
- on the server side
- on the client side (browser)
Server
Cookies: SERVERID108284=104011
set-cookie: SERVERID108284=104011; path=/; max-age=900
- Delete: To delete, you just set an expiration date in the past in a response. For instance: 01/01/1970
set-cookie: DW7fa065a06cb74b536c124cfbe56ac6d3=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; secure; HttpOnly
Client
- You can read/delete/create cookie in a limited way with the web api cookie api
- You can read/delete the cookies with the The devtool is a set of web developer tools embedded in every browser. Chrome example in the application tab
Specification
- The latest Rfc6265 - HTTP State Management Mechanism A. Barth. IETF., This document defines the HTTP Cookie and Set-Cookie header fields.
- The oldest rfc 2109
Support
Why I don't see my cookies on the Application tab?
On the application tab, you will see only the cookies that have been sent with a request from the browser. If you want to see the cookie received with a request, check the cookie tab on the request details of the network tab.
Why my cookie was not set on the browser?
Check in the devtool that the domain of the cookie is the same as the domain of the URL.
If you get the below error message correct the domain send with your cookie.
This set-cookie was blocked because its Domain attribute was invalid with regards to the current host url
Why my Cookie was not sent by the browser?
In the devtool (F12), go to:
- Network
- Request
- Cookie tab
You will see the cookies send and received.