SameSite attribute in cookie

Summary

The SameSite cookie attribute, introduced in Chrome 51, helps mitigate CSRF attacks and reduce user tracking by restricting third-party cookie usage. It offers three values: Strict, Lax, and None. Strict completely prevents cross-site cookie sending, potentially impacting user experience, while Lax is more permissive, allowing cookies for top-level navigations via GET requests like links or GET forms. Setting SameSite to None requires the Secure attribute, ensuring cookies are only sent over HTTPS, with Chrome 76 defaulting to Lax for enhanced security.

Starting from Chrome 51, a new attribute SameSite has been introduced for browser cookie. This attribute is to prevent CSRF attack.

Cookie is normally used to store data exchanged between client and server. It frequently stores user login information. If a malicious website can forge a HTTP request with the valid third party website cookie, it may be called a CSRF attack.

For example, if a user logins to a bank website your-bank.com, the bank server responds a cookie:

Set-Cookie:id=a3fWa;

Later the user somehow visits malicious.com and there is a form on the website.

<form action="your-bank.com/transfer" method="POST">
  ...
</form>

Once the user is lured to submit the form, the bank website will receive a request to transfer amount with valid cookie containing the user login information. To prevent this kind of attack, normally a form should contain a hidden field with a random token to prove to server it's a real valid request.

<form action="your-bank.com/transfer" method="POST">
  <input type="hidden" name="token" value="dad3weg34">
  ...
</form>

This type of cookie which is sent because of a third party website trigger is called third party cookie. Apart from CSRF attack, it can be used to track user as well.

For example, assume Facebook inserts an invisible image in a third party website with below code.

<img src="facebook.com" style="visibility:hidden;">

When the browser loads the page with above code, it will send a request to Facebook as the image src tag points to facebook.com, this request would normally contain some cookie containing the user information and website information. Hence Facebook could track user web history.

The SameSite attribute introduced by Chrome is to reduce security risk by restricting third party cookie. It can have three values:

  • Strict
  • Lax
  • None

Strict as it means it will completely restrict third party cookie. When cross site accessing, it will not send cookie to another website in any circumstance. It will only send cookie when the target page and current page have the same origin.

Set-Cookie: CookieName=CookieValue; SameSite=Strict;

This value is so strict which may bring bad user experience. For example, if the current page contains a link to Github, in this case the user will not be in logged in state if the user clicks the link and visits Github.

Instead Lax is a bit less strict, it will not send third party cookie in most cases unless the target link is a GET request.

Set-Cookie: CookieName=CookieValue; SameSite=Lax;

It has three scenarios: link, preload request and GET form.

Request type Example Normal case Lax case
Link <a href="..."></a> Send cookie Send cookie
Preload request <link rel="prerender" href="..."/> Send cookie Send cookie
GET form <form method="GET" action="..."> Send cookie Send cookie
POST form <form method="POST" action="..."> Send cookie None
iframe <iframe src="..."></iframe> Send cookie None
AJAX $.get("...") Send cookie None
Image <img src="..."> Send cookie None

When Strict or Lax is set, most of the CSRF attacks can be prevented, but it requires the browser to support this attribute.

Lax will be the default value in Chrome 76 and the user needs to set it to None if s/he wants to explicitly turn off the SameSite attribute. However, it must come along with the Secure attribute so that the cookie can only be sent when using HTTPS protocol in this case. Otherwise it will have no effect.

Below setting will not work.

Set-Cookie: widget_session=abc123; SameSite=None

Below setting works.

Set-Cookie: widget_session=abc123; SameSite=None; Secure

Reference:

JAVASCRIPT CHROME COOKIE SAMESITE CSRF

  RELATED

  COMMENTS

0

No comment for this article.