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
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!
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
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.
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.
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.
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.
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.
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.
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.
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
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:
protect_from_forgery with: :exception
<%= 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.