SameSite Cookies Explained
The SameSite
attribute of cookies controls how they are sent in cross-site (slightly different from cross-origin) requests in web browsers through which we can reduce the risk of cross-site request forgery (CSRF) attacks and hence enhance user privacy and security.
Before looking at the different values we can pass to this attribute, please read this web.dev article to thoroughly understand what exactly defines same-site vs cross-site and how they’re different from same-origin vs cross-origin.
But to summarise, two domains with the same scheme and domain (the “TLD + one level” part like example.com
in foo.example.com
and bar.example.com
) are considered to be the same sites. Any difference in the scheme (http
vs https
) or domain (foo.com
vs bar.com
) will be considered cross-site.
Now while creating a cookie, the following values can be set for the SameSite
attribute:
SameSite=None
: This value indicates that the browser will send the cookie in the HTTP requests for both same-site and cross-site requests. So if you set a cookie with this value onfoo.com
and then embed an image, iframe, script, etc. forfoo.com
onbar.com
, the cookie will be sent in the request (cross-site). Even when you navigate frombar.com
tofoo.com
the cookie will be sent. However, when using this value, theSecure
attribute of the cookie must also be set, meaning the cookie will only be sent over HTTPS connections.SameSite=Strict
: With this value, the cookie will only be sent in a first-party context (same-site requests). It means that the cookie will be sent only for requests from the same-site (any referrer that has the same scheme and domain as described above). Hence, any embeddings (scripts, iframes, images), navigations (through a link or JS redirect), form submissions or XHR/fetch requests frombar.com
tofoo.com
(cross-site) will not send the cookies that were stored forfoo.com
earlier.SameSite=Lax
: This (default) value provides a balance between security and usability. The cookie will be sent in all same-site requests (likeStrict
) and some cross-site requests where the user is navigating to the site from a different domain through a standard link, JS redirect orwindow.open()
. In other words,Lax
cookies are sent for requests that have top-level navigations (URL in address bar changes) and are safe HTTP methods (HEAD
,OPTION
,GET
). It won’t be sent for requests triggered by third-party websites (cross-site) while loading scripts, iframes, images, making form submissions (POST
) or sending XHR/fetch requests.
Strict
(same-site only and most secure) is a good choice for cookies that are required for user actions like session cookies that allows a user to perform certain write operations on the website – change profile, write a tweet, post a photo, push a commit, make a payment, order food, etc.
Lax
on the other hand can be used for other use cases like showing promo offers, changing the display of the site, etc. so that when a user navigates from bar.com
to foo.com
the display is still consistent.
None
is how browsers used to behave earlier by default when the SameSite
attribute did not exist. Although now this is only allowed on https
connections.
Note: For requests (navigations, embeddings, AJAX) where Strict
or Lax
cookies will not be sent, any Set-Cookie
response headers of type Strict
or Lax
will also be ignored. Only SameSite=None
cookies can be set in such requests.