Same-site cookie, a new protection against CSRF

CSRF has long been a well-known topic in the OWASP Top 10. Many protections and mitigations exist and are more or less easy to implement (synchronized token, custom request header, encrypted token, double submit cookie pattern,…). A new kid on the block has recently emerged and is increasingly supported by recent browsers: a very simple mitigation based on the SameSite cookie attribute.

CSRF - Reminder

We will not define CSRF in details nor describe the list of existing mitigations . This is not the purpose of this article, but let’s just focus on the main points.

According to owasp.org :

Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious web site, email, blog, instant message, or program causes a user’s web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.

To be very concise, let’s say that this kind of attack is possible mainly because:

  • Cookies are automatically sent by browsers to third parties in cross origin requests
  • Web applications can’t really distinguish between user-initiated actions and those initiated by third-party scripts.
  • Since browsers include cookies with every request to a website, most sites rely on this mechanism to determine whether users are logged in.

There are many defenses and protections against CSRF. These solutions are declined in many implementations and strategies: from the most common (synchronized token) to the most adapted to a given context (double submit cookie, encrypted token), through the most constraining (user interaction).

All of these protections are efficient if well implemented. They have to be chosen depending on the application’s constraints and context (“Traditional” webapp/single page application, stateful/stateless architecture , project sensitive data/high security level, public/private websites …). But they all have in common that they are relatively non trivial to implement (token encryption, …) or may have some impacts on the user experience.

The SameSite cookie attribute can be used to disable third-party usage for a specific cookie. It is presented as a simple mitigation strategy that allows servers to declare certain cookies as they could not be attached to cross-site requests. In the principle, when another site tries to request something from the web application, the cookie is simply not sent. This effectively makes CSRF impossible, because a potential attacker can’t use the user’s session from his malicious site anymore.

Concretely, to implement this feature, just make the server set the SameSite=… attribute to the Set-Cookie header from the HTTP response:

Set-Cookie: SID=89d4y96e502abd42; HttpOnly; SameSite=strict

The SameSite attribute allows two possible values:

  • strict: The cookie is blocked for any cross-site usage, even for links and images.
  • lax: Some cross-site usages are allowed. Mainly, GET requests and top-level navigation. Top-level navigation occurs when the URL in the address bar changes through your navigation, contrary to ajax request, images, css links or iframes.

The following table, from the excellent Sjoerd Langkemper’s article , shows when cookies are sent with cross-origin requests, depending on corresponding HTML elements:

HTML elementExample codeNormalStrictLax
link<a href="…">XX
prerender<link rel="prerender" href="…">XX
form get<form method="get" action="…">XX
form post<form method="post" action="…">X
iframe<iframe src="…">X
ajax$.get('…')X
image<img src="…">X

From this table, we notice the following points:

  • Cookies without the SameSite attribute (“Normal” column) are always sent.
  • Strict cookies are never sent.
  • Lax cookies are only sent for top-level navigations and GET requests.

As you can guess, strict mode offers better security, but limits some functionalities: links to protected resources (e.g. which require authentication process) won’t work in a cross-site request context. Thus, even if you are logged in, cookies, with such setting, won’t be sent when the request comes from another site. As an alternative, the lax mode will overcome these restrictions, while providing decent security, by blocking cross-site POST requests.

Limitations and other considerations

As any new feature, there are some limitations that you should have in mind:

  • Regarding browsers support, note that, as same-site cookie is still recent, it is not yet implemented by all browsers. Actually, only last versions of Chrome (51), Firefox (60) and Opera (39) implement this feature. But, no doubt that the other browsers will follow soon. You can regularly consult the list of supported browsers here

  • Some embedded components (social networking widgets, …) require cross-site cookies in order to work well, as they need user’s state. Same thing for forms of Single-Sign-On which require authentication… For those reasons, many websites will still resort to usual server-side defenses (anti-CSRF token, ensure that “safe” HTTP methods are idempotent, …) in order to avoid breaking existing functionalities.

And finally, don’t forget that whatever the CSRF protection you implement, if your application is XSS vulnerable, you are over. Make sure that all inputs are sanitized.

Conclusion

Despite some identified limitations and a relatively limited, but in a constant growing, browser support, the same-site cookie is a promising, simple and good protection against CSRF attacks by giving the possibility to disable, completely or partially, third-party usage for any cookie, such as it seems to the attacker that you are no longer logged in to the website under attack.

Simple and efficient!

References: