Secure better your website with SameSite cookies

vzuburlis profile image Vasilis Zoumpourlis ・2 min read

Cross-site request forgery (CSRF) attacks is a type of malicious exploit of a website where unauthorized commands are transmitted from a user that the web application trusts.

Let's see the following example: You have an endpoint that updates a user: mysite.com/user/update/2

The new data should come from a POST method, so if you open the endpoint from a link, the update will not happen because the request method in this case is GET. But someone could build this simple html file:

This index.html can be placed in any website (like clickhereandseewhathappens.com), and the link is send it to the website administrator with an email. When the administrator opens this html in the browser, the form will be submited to mysite.com and the user will be updated.

This will happen because the sessionId cookie of the user will be sent to the server and the application understands that this request was made from the administrator.

The SameSite is a cookie key that tells browser to send the cookie value to the server only when the request is made from the same domain of the website.

For example, when you dont want to sent the cookie from a different url.

mycookie=value; expires=Wen, 1 Jan 2019 12:00:00 UTC; path=/; SameSite=Strict

When you want to send it with simple links (GET method) but not with POST/PUT/DELETE etc

mycookie=value; expires=Wen, 1 Jan 2019 12:00:00 UTC; path=/; SameSite=Lax

The default scenario is to sent it always.

This feature is already supported from all major browsers https://caniuse.com/#feat=same-site-cookie-attribute

So this is an extra layer of security for your website and very easy to implement.

To create a samesite cookie with php:

header("Set-cookie: mycookie=value; path=/; HttpOnly; SameSite=Lax");

From php 7.3 you can use setcookie function with the options (8th) parameter:

setcookie('mycookie', 'value', time()+86400, '/', null, null, true, ['samesite'=>'Strict']);

Note: the above examples also adds the HttpOnly key for the cookie, that key prevents from your javascript to access the value of your cookie. So even you have a XSS script run in your website, it wont be able to see the cookie's value.

To set the expiration date with header() you must print date with the expected format

$expire = date('D, d M Y H:i:s', time() + (86400 * 30)); // one month from now
header("Set-cookie: mycookie=value; expires=$expire; path=/; HttpOnly; SameSite=Lax");


Editor guide