Learn Cookie From Chrome 80 Samesite
Chrome 80 enable a new flag by default, SameSite. Although revert this change later.
Let’s start with some concepts.
- Cookie Setter
- Cookie Keeper
- Cookie Sender
- Cookie Reader
- Cookie Origin
Cookie can be set by either Web Server or Front-end codes.
When request for
GET /index.html HTTP/1.1, the Web Server can send this back:
Content-type: text/html Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
Then cookie with key
sessionToken will be set on the client browser side.
Cookie is kept and only kept by browser. Thus the cookie can be accessed and kept among different web pages, after restart the brower.
Cookie is sent by and only by browser.
You shouldn’t and can’t sepcify the cookie you want to send using the front-end codes.^1
Browser is the gate-keeper, safe-guard of the cookie!
Cookie is usually read/used by Web Server or front-end codes.
Web Server use line like
request.cookies.get() to read the cookie sent by the client browser.
On the front-end, JS code can read the
cookie from the current
document.location is where the JS code is running at, aka the URL shown on the address bar. (Except for
IFrame and cookie with
Orgin, as a namespacing strategy, happens on both Web Server and client browser sides.
Set Within The Specific Orgin
On the browser sides, there are two kinds of cookies, first-party and third-party cookies.
Cookies that match the domain of the current site, i.e. what’s displayed in the browser’s address bar, are referred to as first-party cookies. Similarly, cookies from domains other than the current site are referred to as third-party cookies.
For example, if the user requests
http://example.com/index.html and return is,
<!-- http://example.com/index.html --> <html> ... <img src="http://cdn.com/cat.png" /> <ul id="list-of-books"></ul> ... <script> ... response = AJAX_REQUEST_FOR("https://example.com/books"); document.getElementById.innerHTML=FORMAT(response); ... </script> </html>
If all three web servers on
https://example.com response with
Set-Cookie: token=xxx header,
- For Orgin
http://example.com, browser received, set and kept a cookie
- For Orgin
http://cdn.com, browser received, set and kept a cookie
- For Orgin
https://example.com, browser received, set and kept a cookie
https: for the same domain actually belongs to different origin,
An origin is defined as a combination of URI scheme, host name, and port number.
https://example.com are different origin because of two differences,
- URI differs at the beginning, as
URI[0:5] == "http:" or "https"
- TCP connection is to
Send Within The Specific Orgin
Let’s say, when user refresh this page, (with cache disabled), the browser sends requests, (shown in curl grammer),
curl -b 'token=abc' http://example.com
curl -b 'token=cute' http://cdn.com/cat.png
curl -b 'token=123' https://example.com/books
So we can see that browser only send the cookie corresponding to the request origin, regardless the fact that the current
document.location == http://example.com.
Say on another page,
http://example99.com/index.html is also using the cute image on
http://cdn.com/cat.png, browser will also send the
token=cute with the request happens on that page.
If a cookie’s
Pathattributes are not specified by the server, they default to the domain and path of the resource that was requested.
For example, if the Web Server response to
Domain set, the request for
sessionToken=abc123 will NOT be sent.
If the response is,
Set-Cookie: sessionToken=abc123; Domain=.example.com;
the cookie will be sent.
The prepending dot
"."example.comis optional in recent standards, but can be added for compatibility.
Let’s explain the following topics using the concepts introduced above.
Samesite Policy Enabled By Default In Chrome 80
site terminology in the
samesite is NOT just origin, but also the public suffix.
This policy uses two attributes when set the cookie,
SameSite attibute works only when
Secure is also set. e.g.
Set-Cookie: token=123; SameSite=None; Secure.
If you set
SameSite=Strict, your cookie will only be sent in a first-party context.
SameSite=Laxwould not restrict originating site.
SameSite=Nonewould allow third-party (cross-site) cookies.
SameSite=Lax, in the above Origin example, requesting for
http://example.com won’t send the
token=cute which belongs to origin
If you use
SameSite=Strict, the restriction is even harder: by clicking a link on the
<a href="http://cdn.com"></a>, browser won’t send
token=cute on the initial request for
SameSite=Strict, the browsers should only send these cookies with requests originated from the same domain/site as the target domain.
A Complete Example
If you are still confused, see this.
SameSite=Laxcomes in by allowing the cookie to be sent with these top-level navigations. Let’s revisit the cat article example from above where another site is referencing your content. They make use of your photo of the cat directly and provide a link through to your original article.
<!-- exmaple.com/index.html --> <p>Look at this amazing cat!</p> <img src="https://blog.example/blog/img/amazing-cat.png" /> <p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
And the cookie has been set as so:
Set-Cookie: promo_shown=1; SameSite=Lax
When the reader is on the other person’s blog the cookie will not be sent when the browser requests
amazing-cat.png. However when the reader follows the link through to
cat.htmlon your blog, that request will include the cookie. This makes
Laxa good choice for cookies affecting the display of the site with
Strictbeing useful for cookies related to actions your user is taking.
Effect On Front-End Code
SameSite=Lax setting, will fail the request for external resources. For example in the case of,
- User login to
http://bookshelf.com/loginand save the cookie
- User browses
bookreviews.comand want to GET
bookshelf.com/user1/favoriteshown in the widget.
bookshelf.comneeds the token to see user’s favorites, this request will fail as the
token=123is not sent by the Chrome 80.
To solve this, the developer of
bookshelf.com needs to,
- Change the login page using https,
- Send the above cookie when login successfully,
Set-Cookie: token=123; Secure; SameSite=None
Force Opt-Out From This Feature In User’s Side
chrome://flagson address bar and press
samesite by default cookiesusing searching feature on the top of the page.
- Change the highlighted item in the filtered list (should be the first item), from
A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos. Certain “cross-domain” requests, notably AJAX requests, are forbidden by default by the same-origin security policy. CORS defines a way in which a browser and server can interact to determine whether it is safe to allow the cross-origin request.
On the browser side, for “cross-domain” requests, for example, during opening the page:
<!-- http://www.exmaple.com/index.html --> <p>Look at this amazing cat!</p> <img src="https://blog.example/blog/img/amazing-cat.png" />
browser send http requst
OPTIONS https://blog.example/blog/img/amazing-cat.png with
On the Web Server side,
- Which origin are allowed to make the requests?
You can simply send
Access-Control-Allow-Origin: * back for allowing all requests.
Cookie Theft And Abuse
- DNS cache poisoning. An attacker could use DNS cache poisoning to create a fabricated DNS entry of
attacker.www.example.comthat points to the IP address of the attacker’s server and send user an email with the link to attacker.www.example.com.
- Cross-site request forgery. Attacker send email with an image