- What are first-party and third-party cookies?
- Explicitly state cookie usage with the SameSite attribut
- Changes to the default behavior without SameSite
- SameSite cookie recipes
Modern browsers (including Chrome, Firefox, and Edge) are changing their bahavior to enforce more privacy-preserving defaults.
Servers set cookies by sending the aptly-named Set-Cookie
header in their response.
The header looks like this:
1 | Set-Cookie: promo_shown=1; Max-Age=2600000; Secure |
When users on a secure connection and the cookie is less than a month old, then their browser will send this header in its request:
1 | Cookie: promo_shown=1 |
You can also access the cookies available to that site in JavaScript using document.cookie
. Making an assignment to document.cookie
will create or overwrite a cookie with that key.
1 | > document.cookie = "promo_shown=1; Max-Age=2600000; Secure" |
Reading document.cookie
will output all the cookies accessible in the current context, with each cookie separated by a semicolon:
1 | > document.cookie; |
What are 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.
This isn’t an absolute label but is relative to the user’s context; the same cookie can be either first-party or third-party depending on which site the user is on at the time.
Cross-site request forgery (CSRF) attacks rely on the fact that cookie are attached to any requests to a given origin, no matter who initiates the request. For example, if you visit evil.example
then it can trigger requests to your-blog.example
, and your browser will happily attach the associated cookies. If your blog isn’t careful with how it validates those requests then evil.example
could trigger actions like deleting posts or adding their own content.
Explicitly state cookie usage with the SameSite attribut
The introduction of the SameSite
attribute allows you to declare if your cookie should be restricted to a first-party or same-site context. It’s helpful to understand exactly what ‘site’ means here. The site is the combination of the domain suffix and the part of the domain just before it. For example, the www.web.dev
domain is part of the web.dev
site.
If the user is on www.web.dev
and requests an image from static.web.dev
then that is a same-site request.
The public suffix list defines this, so it’s not just top-level domains like .com
but also includes services like github.io
. That enables your-project.github.io
and my-project.github.io
to count as separate sites.
If the user is on your-project.github.io
and requests an image from my-project.github.io
that’s a cross-site request.
- Strict: Cookies will only be sent in a first-party context.
In user terms, the cookie will only be sent if the site for the cookie matches the site currently shown in the browser’s URL bar.
This is good when you have cookies relating to functionality that will always be behind an initial navigation. - Lax: Allows the cookie to be sent with these top-level navigations.
This is a good choice for cookies affecting the display of the site. - None: No restrictions will applied. The cookie will be sent in all requests - both cross-site and same-site.
This means you can useNone
to clearly communicate that you intentionally want the cookie sent in a third-party context.
If you provide a service that other sites consume such as widgets, embedded content, affiliate programes, advertising, or sign-in across multipile sites then you should useNone
to ensure your intent is clear.
Changes to the default behavior without SameSite
- Cookies without a
SameSite
attribute will be treated asSameSite=Lax
. - Cookies with
SameSite=None
must also specifySecure
, meaning they require a secure context.
Both of these changes are backwards-compatible with browsers that have correctly implemented the previous version of the SameSite
attribute, or just do not support it at all. By applying these changes to your cookies, you are making their intended use explicit rather than relying on the default behavior of the browser. Likewise, any clients that do not recognize SameSite=None
as of yet should ignore it and carry on as if the attribute was not set.
Warning
A number of older versions of browsers including Chrome, Safari, and UC browser are incompatible with the new None
attribute and may ignore or restrict the cookie. This behavior is fixed in current versions, but you should check your traffic to determine what proportion of your users are affected. You can see the list of known incompatible clients on the Chromium site.
SameSite cookie recipes
For further detail on exactly how to update your cookies to successfully handle these changes to SameSite=None
and the difference in browser behavior, head to the follow up article, SameSite cookie recipes.
Ref:
https://web.dev/samesite-cookies-explained/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite