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:

  1. 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 on foo.com and then embed an image, iframe, script, etc. for foo.com on bar.com, the cookie will be sent in the request (cross-site). Even when you navigate from bar.com to foo.com the cookie will be sent. However, when using this value, the Secure attribute of the cookie must also be set, meaning the cookie will only be sent over HTTPS connections.
  2. 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 from bar.com to foo.com (cross-site) will not send the cookies that were stored for foo.com earlier.
  3. SameSite=Lax: This (default) value provides a balance between security and usability. The cookie will be sent in all same-site requests (like Strict) and some cross-site requests where the user is navigating to the site from a different domain through a standard link, JS redirect or window.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.

Leave a Reply

Your email address will not be published. Required fields are marked *