Using the SameSite Cookie Attribute to Prevent CSRF Attacks
For a long time, CSRF attacks were considered one of the most dangerous exploits. While still serious, their danger level is decreasing. Read on to find out why.
Join the DZone community and get the full member experience.
Join For FreeIntroduction to Web Cookies
Because HTTP is a stateless protocol, it cannot internally distinguish one user from another. To address this issue, cookie technology was invented in 1994. By using cookies, servers instruct browsers to save a unique key and then send it back with each request made to the server.
When a request is sent from a browser to a website, the browser checks if it has a stored cookie that belongs to that website. While carrying out this process, it checks to see whether the properties and flags of the cookies (domain, path, secure), match the website's data which has been requested. If they match, the browser sends the relevant cookies along with the request.
Cookies Misuse Can Lead to Cross-Site Request Forgery
This behavior is also repeated in the same way for requests made by third parties through the browser. By "third parties," we mean other websites that we don't visit directly. The critical point from a web application security perspective is that when you visit website A, all cookies kept in the browser for site B will be added to the request initiated toward site B by site A. So, a session that belongs to B on the browser can be used and even abused in this way.
In security terminology, abusing this browser behavior is known as Cross-Site Request Forgery (CSRF). It is carried out by misusing a session belonging to an authorized user by using this browser behavior.
This browser behavior can also be misused for other purposes as well, like tracking users or advertising. When you enter a site, for instance, example.com, your browser may make a few requests to different sites because of the HTML elements placed on the page of example.com, for example, Facebook Like buttons, Google Analytics codes, etc. Along with these requests, the cookies in the browser that belong to these other sites will also be sent. Therefore, those third parties can track and log your activity by using Cookie and Referrer information.
Should You Block Cross-Site Requests to Prevent CSRF?
Normally, it is possible to avoid tracking like this in Firefox and Chrome browsers. However, when these browsers block tracking, they prevent the sending of cookies along with the request made by any third party website. But, by doing so, your browsing experience will be very poor. So, by blocking cookies, you can totally prevent CSRF, but is it worth the consequences?
Introducing the Same-Site Cookie Attribute to Prevent CSRF Attacks
Thanks to a new cookie attribute that Google Chrome started supporting on the 29th of March, and other the popular browsers followed, there is now a solution. It is called the SameSite Cookie Attribute. Developers can now instruct browsers to control whether cookies are sent along with the request initiated by third-party websites - by using the SameSite Cookie Attribute, which is a more practical solution than denying the sending of cookies.
Setting a Same-Site attribute to a cookie is quite simple. It consists of adding just one instruction to the cookie. Simply adding 'SameSite=Lax' or 'SameSite=Strict' is enough!
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
Set-Cookie: CookieName=CookieValue; SameSite=Strict;
Differences Between the Strict and Lax SameSite Cookie Attributes
Strict: As the name suggests, this is the option in which the SameSite rule is applied strictly. When the SameSite attribute is set as Strict, the cookie will not be sent along with requests initiated by third party websites.
Setting a cookie as Strict can negatively affect the browsing experience. For example, if you click on a link that points to a Facebook profile page, and if Facebook.com has set its cookie as SameSite=Strict
, you cannot continue navigation on Facebook (view the Facebook page) unless you log in to Facebook again. The reason for this is that Facebook's cookie was not sent by this request.
Lax: When you set a cookie's SameSite attribute to Lax, the cookie will be sent along with the GET request initiated by the third-party website.
The important point here is that, to send a cookie with a GET request, the GET request that is made must cause a top-level navigation. Only in this way can the cookie that is set as LAX be sent. Let me explain more.
Resources can be loaded by iframe
, img
, and script
tags. These requests can also operate as GET requests, but none of them cause TOP LEVEL navigation. Basically, they don't change the URL in your address bar. Because these GET requests do not cause TOP LEVEL navigation, the cookies set to Lax won't be sent along with them.
See the table below for more clarification:
Request Type | Example Code | Cookies sent |
Link | <a href="..."></a> | Normal, Lax |
Perender | <link rel="prerender" href=".."/> | Normal, Lax |
Form GET | <form method="GET" action="..."> | Normal, Lax |
Form POST | <form method="POST" action="..."> | Normal |
iframe | <iframe src="..."></iframe> | Normal |
AJAX | $.get("...") | Normal |
Image | <img src="..."> | Normal |
Does This Really Mean "Goodbye" to CSRF?
Yes, it looks like the SameSite cookie attribute is an effective security measure against CSRF attacks. You can avoid sending your cookies with the request initiated by third parties by using this feature. Let me clarify with an example.
Let's say you are logged in to the website www.badbank.com. Using a phishing attack, an attacker can trick you into entering www.attacker.com in another browser tab. Using a code on www.attacker.com, the attacker tries to transfer money from your account by posting a FORM to www.badbank.com. Your browser sends the cookie belonging to www.badbank.com with this request. If the form on www.badbank.com lacks CSRF tokens to prevent a CSRF attack, your session can be exploited by the attacker.
If the cookie of www.badbank.com had been set to SameSite=Lax
, the cookie in the browser would not have been sent with the POST request and the attack would not be successful.
CSRF Popularity is Going Down
CSRF attacks were at number 5 in the OWASP Top 10 list published in 2010, but they declined to number 8 in the OWASP Top Ten in 2013. People suggested that the reason for this was increased awareness of CSRF and the common use of Anti-CSRF tokens by frameworks.
In 2017, CSFR came in at number 8 on the OWASP Top 10.
Preventing CSRF Vulnerabilities
Although we're now using the SameSite Cookie attribute, we should still be cautious! We should make the changes with a POST request instead of GET.
GET is designed for navigational purposes, not for state changes, so using GET requests is generally considered a safe method. However, when we are performing actions (such as ordering a product, changing a password, or editing profile information), using POST requests is much safer.
There are 3 important reasons for this:
- When the parameters are carried by GET, they stay in the browser history. They also will be placed in server logs and the Referrer header in the request made toward third parties.
- Another reason for not using GET requests is that cookies set to Lax are still sent along with GET requests, giving attackers another opportunity to exploit users.
- Lastly, exploiting a CSRF vulnerability by using GET is much easier. To exploit a CSRF vulnerability in a form using GET, an attacker does not have to own a site. He can inject this payload into a forum message, post comment or image tag.
Published at DZone with permission of Ziyahan Albeniz, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments