SameSite cookies - Everything You Need to Know

What will I cover in this post?

Google Chrome recently released an update that began enforcing a new cookie policy. The new update affects the SameSite cookie attribute, making it Lax by default.

This change will also be enforced by all other major browsers.

In this post, I plan on:

  • Describing the SameSite cookie attribute and its settings
  • Explaining the new cookie policy and why it is important
  • Providing some best practices

Personally, from a security perspective, I think this is a great policy and that the new changes make the internet a much safer place.

What is the SameSite cookie attribute?

The SameSite cookie attribute prevents cross-site request forgery (CSRF) attacks by stopping browsers from sending cookies to other sites.

A CSRF is an attack that forces end-users to execute unwanted actions on the web applications where they are currently authenticated. For more information, see the OWASP site.

The attribute was first introduced by Chrome in 2016 as an optional attribute. By end of 2017, it was adopted by all major browsers.

What are the supported settings?

The SameSite attribute supports two settings:

  • Strict: The browser does not send a cookie to other sites when following a link
  • Lax: There are a limited set of circumstances in which a browser will send a cookie
    • Link (HTTP Get) <a href="…">
    • Prerender (HTTP Get) <link rel="prerender" href="…">
    • Form HTTP Get <form method="get" action="…">

With Lax, the most important thing to remember is that a browser only sends cookies with top-level get requests.

A top-level get request means that the URL in the address bar changes.

This means that browsers will not send a cookie for:

  • AJAX requests
  • POST requests

What is the new cookie policy?

The new cookie policy introduces two major changes:

  • Important: If the SameSite attribute is not configured, the default setting is Lax.
  • The attribute now supports three settings: Strict, Lax and None.

The new None setting enables browsers to send cookies to other sites.

The Chromium blog does a great job of explaining these changes, and the security and transparency benefits they introduce.

Chrome

Chrome started enforcing the new cookie policy in Chrome 80 for a limited number of users. Enforcement will be gradually increased until the new policy is enforced for all users. For more information and updates, see this Chrome post.

Firefox

Firefox started supporting the policy in version 69. The policy is not enforced by default. That’s why you need to keep on reading!

Chrome

Browse to chrome://flags and enable #same-site-by-default-cookies and #cookies-without-same-site-must-be-secure

Firefox

Browse to about:config and enable network.cookie.sameSite.laxByDefault and network.cookie.sameSite.noneRequiresSecure

Why is this policy so important?

If your web application uses cookies (and it does) - this change is important to you.

From now on, all cookies without the SameSite attribute are considered as Lax.

If your web application sends requests to other applications (or is deployed on multiple hosts), these requests may stop working. Therefore, I strongly recommend testing related cases in your application to check which ones have been affected by Google’s new policy update. These related cases include, for example, initial requests sent to external applications, such as:

  • HTML frames that are opened via a link to another application.
  • Applications that are accessed via an AJAX request.

After the change, the requests may not be authenticated because the cookies are no longer being sent, and the request will fail.

If you discover that any of your application functionalities have stopped working, the simplest solution is to change the SameSite attribute setting of an appropriate cookie to None. However, this should only be done as a last resort (see details below).

What are the best practices?

When should I use Strict?

If your application is deployed on a single host and does not link to other hosts or sites - the new policies will not effect your application. As I mentioned above, the cookies will be treated as Lax.

However, you may want to consider the Strict setting, especially if you have applications that deal with confidential information (for example, banks). The Strict setting will provide your application with extra security and will always prevent cookies from being sent to other websites.

Set-Cookie: key=value; SameSite=Strict

Personally, I recommend setting all cookies as Secure and HttpOnly.

Set-Cookie: key=value; SameSite=Strict; Secure; HttpOnly

When should I use Lax?

I strongly recommend using Lax when your application requests other applications only using the limited set of circumstances described above.

From a security perspective, Lax is a great setting, as the cookies sent by the browsers cannot be used in CSRF attacks.

One caveat

When using Lax, you need to ensure that HTTP Get requests do not change the state of your application.

Using Get to change the state of your application is a very bad practice, but it becomes even more dangerous when your application uses Lax, and you make the false assumption that you are now protected against CSRF attacks.

Set-Cookie: key=value; SameSite=Lax

As mentioned previously, I recommend setting all cookies as Secure and HttpOnly.

Set-Cookie: key=value; SameSite=Lax; Secure; HttpOnly

When can I use None?

None should be used only as a last resort setting: if your application needs to send cookies to other applications that are not included in the circumstances permitted by Lax.

From a security perspective, it is better to convert your application to only send cookies in the circumstances supported by Lax. Using None, makes your application vulnerable to CSRF attacks.

Two caveats

  1. None is only valid when using HTTPS. This means that if you are using HTTP you will need to switch to HTTPS (which is also strongly recommended from a security perspective).

  2. None does not work with old browsers. Therefore, you will need to upgrade the browsers in your environment. You can find the list of incompatible browsers here.

Set-Cookie: key=value; SameSite=None; Secure

The same as before: I recommend setting all cookies as Secure and HttpOnly.

Set-Cookie: key=value; SameSite=None; Secure; HttpOnly

Take-aways

You should now have a better knowledge of SameSite Cookies and the changes that were recently introduced to all browsers. Most importantly, you need to remember that if the SameSite setting is not configured, the default is now Lax.

Stay tuned for next posts!