After reading our last article about how to secure your cookies, you may (should?) already be using Secure and HttpOnly flags. As a reminder, ‘Secure’ allows to prevent a cookie to be sent on a non-secure web page, whereas ‘HttpOnly’ prevents any client-side usage of a given cookie.
It is now time to take your website security to the next level with one more attribute for your cookies! Let’s talk about SameSite instruction, allowing to prevent Cross-Site Request Forgery (CSRF) attacks and Cross-Site Script Inclusion (XSSI).
SameSite attribute, to manage when a cookie should or should not be sent
The main concept behind Same-Site is similar to HTTPOnly and Secure features: getting control over the cookie behaviour, more precisely, defining when the cookie should not be sent.
There are two policies for SameSite attribute, defined by its values (case-insensitive): Strict (default) and Lax.
Strict policy for Same-Site Cookie
The defined cookie will only be sent if the request is originating from the same site.
Set-Cookie: SID=31d4d96e407aad42; SameSite=Strict
Lax policy for Same-Site Cookie
Lax mode is adding one exception for the cookie to be sent if we’re not in a Same-Site context: the defined cookie will also be sent for requests using a safe method (GET method for most) for top-level navigation (basically something resulting in the URL changing in the web browser address bar).
The Strict mode would prevent any session cookie to be sent for a website reached by following an external link (from an email, from search engines results, etc.), resulting for a user not being logged in.
(if we were using Strict Same-Site on dareboost.com, by clicking this link, you would not be detected as logged in, whether you were connected or not).
The behaviour can be confusing for the final user, so you would prefer using the Lax mode.
Set-Cookie: SID=31d4d96e407aad42; SameSite=Lax
WARNING : Strict being the default mode, any typo writing the Lax value would result in Strict behaviour.
Cross-Site Request Forgery, the initial problem
As defined by the OWASP, Cross-Site Request Forgery (CSRF) is an attack that forces an end-user to execute unwanted actions within a web application they’re currently authenticated.
Let’s consider a predictable URL such as this one (that we can assume will provoke the user’s email to be updated):
An attacker succeeding in having this request executed by an user being logged in, but with the attacker email as a param, would get access to the user’s account.
Social Engineering is often used to trick end-users and get them to trigger similar requests, for example by including an image having this URL as an SRC attribute.
(by the way, most of the mail clients are now blocking images by default to limit CSRF attacks).
So far, preventing Cross-Site Request Forgery attacks was achieved by checking the Referer header and CSRF tokens (a token provided by the server to the web browser, and that will be sent by the browser within the protected request. If the request does not embed a valid token, it will be rejected).
Using a Same-Site Cookie (with Strict mode) would prevent CSRF attacks, except – as pointed out by the spec – if the attacker is combining its attack with an XSS one (do not forget to use CSP!).
There are other limitations for Same-Site to be Bullet proof against CSRF attacks, and the first one would be the current status of Same-Site support by web browsers.
Even if Firefox have shown clear signs of supporting Same-Site, Chrome and Opera are for now the only browsers dealing with the new instruction.
A web browser that is not supporting the attribute will simply ignore it, you don’t have to worry of any compatibility issue.
Great feature, but not bullet proof
As a conclusion, Same-Site is definitively something you should consider if your website offers sensitive actions to your users, or if you have significant traffic.
You have to note that Same-Site, also allows to mitigate XSSI (Cross-site script inclusion) and Timing attacks as stated by the spec.
Keep in mind that it’s just an extra layer of security: it can’t be your only site’s defense against those attacks. And that’s explicitly detailed in the spec:
“Developers are strongly encouraged to deploy the usual server-side defenses (CSRF tokens, ensuring that “safe” HTTP methods are idempotent, etc) to mitigate the risk more fully.”