Ganga Sumanth
September 7, 2021

TOP 4 Ways to Defeat CSRF

Introduction

CSRF (Cross site request forgery) or XSRF is an attack vector that would trick an unsuspecting user into performing unwanted actions with/without interaction in their browser session. These actions could be as serious as

  • Changing their email address without their knowledge.
  • Changing their PII information to benefit the malicious user.
  • Deleting Important account related information.

In short, the malicious user aims at gaining maximum impact from the state changing action they were allowed to perform due to lack of security measures in place.Let’s look at some of the latest, used and proven ways of tackling CSRF. If you have an application that allows for multiple users to perform multiple state changing actions to their account, then make sure to read through!

1.Using Strict and Lax Same-Site Cookie Attribute

Browsers worldwide now support the Strict and Lax same-site cookie attribute. The SameSite attribute of the Set-Cookie HTTP response header let’s one set the context of the cookie scope i.e this attribute disables blindly sending of cookies to a third party site. This attribute accepts 3 values

  1. Lax
  2. Strict
  3. None

If the attribute isn’t set, then the value Lax is assumed by default. This is a good change as previously browsers would send all cookies by default which would open a gateway to first class CSRF.

Lax

The Lax attribute allows cookies to be sent only if the request initiated by a third party is a GET request. Do note that there are various ways a GET request can be achieved. For instance, an iframe src / image src does generate GET requests as such. The Lax attribute prevents cookies being sent through such requests. Cookies are only sent in cases concerning top level navigation i.e where the address in the url bar is to be modified thus causing the browser to generate a GET request.

Strict

Cookies will only be sent in a first-party context and not be sent along with requests initiated by third party websites. With a strict value set, there is no way for cookies to be transported along requests generated by a third part.

None

Cookies will be sent in all contexts, i.e in responses to both first-party and cross-origin requests. In order to use this value, one would need to set the Secure attribute as well.

2. Make Use of CSRF Tokens with High Entropy

CSRF tokens need to be highly unpredictable, secretive and unique per session. These tokens also need to be passed in a secure way such as HTTP headers or in a POST request body. Never pass csrf tokens with your set of cookies if you aren’t keen on using the SameSite attribute.Also, never pass CSRF tokens via GET requests as it is quite easy to leak them.Examples of a strong CSRF token - A string of high entropyVmpGV1MwMVhSbk5qUlRWVlRXczFNbFpxU21GVVJUVkdaRVZhVjFOSFVtOVdiWGhPVUZFOVBRPT0124Qwert12easTo strengthen the defense, these tokens can be re-generated per page or before every state changing action.

ex csrf token image screenshot

As we can see, the authenticity_token parameter is highly unpredictable. This parameter, if verified properly on the server side, would ensure that no other malicious user would be able to forge the particular request in another unsuspecting user’s session.

3.Make use of Custom Headers

It is known that only Javascript within the same origin of the parent domain can be used to set custom headers and make a request. By default, browsers do not allow JavaScript to make cross origin requests with custom headers. This means added protection as the malicious user would now be required to execute javascript under the target domain’s context to forge a request with custom headers. With CORS properly configured, the malicious user would never get their forged request through in the unsuspecting user’s browser session from their own domain as CORS would prevent it.

csrf header image screeshot

The image above shows passing the CSRF token via the “X-CSRF-Token” header by using an AJAX / javascript request.This method also includes sending Authorization headers i.e Bearer tokens (JWT) on every state changing request.So this method would behave as a good protection mechanism against CSRF attacks. But some caveats to be considered

  • A solid CORS Configuration is a must else an arbitrary domain could fake a javascript request.
  • This technique only works for requests that are made by javascript. <form> tags still need protection via the use of tokens. But adding both would definitely add a superior front against CSRF.

4.Make Use of Any in-built CSRF protection provided

What’s better than having all your defenses at your doorstep waiting for you to just enable it.Well Ruby, Django and a couple more frameworks have in-built csrf protections that just require your configurations.Once enabled, the framework takes care of both the generation of the cryptographic csrf token and also it’s validation.To enable CSRF protection mechanism in ruby:

  • Go to the file application_controller.rb and add the line

protect_from_forgery with: :exception

  • Now go to application.html.erb and add the line

<%= csrf_meta_tags %>In Django,One needs to change the middleware configuration settings.Once enabled, place the below meta in any of the forms to induce the csrf token<form method="post">{% csrf_token %}The above shouldn’t be done when using a POST form with an external URL as that would leak the csrf token.In the view functions, we need to make sure that we use RequestContext to render our view. This would ensure that {% csrf_token %} would get it’s value and work properly.ConclusionAs use of the internet will only increase in the future to carry out all sorts of financial transactions and fund transfer, CSRF attacks will continue to grow. Following the actions I have listed, will reduce the possibility of you becoming a victim of a CSRF attack.