Better security with SameSite cookies

Posted on December 13, 2019

The SameSite is a cookie attribute that tells browser if the cookie value should be send to the server or not when the request is made from a different 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.

 

The great benefit of this feature is the extra security it provides from CSRF attacks.

Like 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 fromm a  link, the update will not happen because the request method in this case is GET. But someone could build this simple html file:

<form id="f" action="http://mysite.com/user/update/2" method="post">
  <input type="hidden" name="name" value="New Username">
  <input type="hidden" name="email" value="qseqwe@dds.com">
  <input type="hidden" name="password" value="new-password">
</form>
<script>
f.submit()
</script>

This index.html can be placed in any website (like clickhereandwhathappens.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 understants that this request was made from the administrator.

With SameSite the sessionId cookie will not be sent from a different domain from mysite.com

 

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 strict 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 user's session id value for example.

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; epires=$expire; path=/; HttpOnly; SameSite=Lax");