If you want to know what an XSRF token is, you are in the right place. In this brief guide we will explain how an XSRF token is implemented, and why it is important. This guide can be useful for both website developers and hackers trying to understand how a website may be vulnerable to attack.
What is an XSRF Token?
A brief definition
We can start with a simple definition:
XSRF token is a small random string designed to prevent cross-site request forgery attacks.
In fact, XSRF (sometimes known also as CSFR) is the acronym of Cross-Site Request Forgery, a type of attack where the hacker tricks the user’s computer in making requests to a third-party website. Doing so, the hacker can have the user perform some actions on the third-party website, unconsciously. This is not a vulnerability of the user’s PC, but of the website itself. Hence, it is up to the website owner and developer to protect against this type of attack, and this is done with the XSRF token.
Before we dive deeper into the XSRF token itself, we should discuss how XSRF attacks work.
How does an XSRF Attack works?
XSRF attacks, or cross-site request forgery, happens through a third-party website owned by the hacker, and they can leverage either JavaScript or simple HTML. The attack involves three parties: the user’s computer, the website which is being attacked, and the malicious website operated by the hacker.
The hacker needs to create a webpage that, when displayed by the user, engages the target website. This is simple, it can be done with a simple image HTML tag that, as src property, contains a URL of the website being attacked. When the user displays the page, the browser will automatically try to load that image – because the browser does not know yet if that URL is really an image or not.
<img src="https://targetwebsite.com/clearly/not/an/image"/ alt="This is a GET XSRF Attack"/>
Hence, it will make a GET HTTP request to the URL indicated in the HTML tag, and since that it likely not to be an image, the image won’t display. But that’s no problem for the hacker, and it is too late for the user – the request has been already made. Since the request is initiated directly from the user, any cookie he has with the target website will be sent with it, so the request will run as authenticated.
Fortunately, what you can do with a GET request is limited. However, if the hacker gets elaborate with JavaScript rather than just plain HTML, he might be able to make POST requests. Making a post request it means the users may unconsciously execute actual actions, such as placing an order, deleting an item, issuing a wire transfer or payment, and more.
How an XSRF Solves This Problem
With an XSRF token, we want to make sure the request coming is legitimate. To put it another way, we want to know if the request coming has originated from our own code that we sent to the user’s browser, or if it was created by a third-party malicious website.
This is possible by using a random string (the XSRF token), some basic encryption and two cookies, one which is httpOnly and the other which is not. In case you need a refresher, a cookie marked as httpOnly is managed secretly by the browser and automatically sent in every request – but it cannot be accessed by JavaScript code in the frontend.
The fact that an httpOnly cookie is not accessible by JavaScript is great for security, but it means the browser always sends it automatically in every request. Hence, if a request originates through an XSRF attack, this cookie will be present. As a result, we cannot consider this alone as a good authentication mechanism, because it is vulnerable to XSRF. We need to pair it with an XSRF token.
The XSRF token is generated randomly and sent to the browser as a standard cookie. Then, in every request we made through JavaScript, we include it manually to be sent. The only thing we need to do is then pair on the backend side the XSRF token with the authentication token sent as httpOnly. If they come together, and we know they are paired, we know the request is legitimate.
This is because the XSRF token is not secure, but it cannot be set by an external attacker. In other words, it ensures the request is legitimate but cannot grant authentication. On the other hand, the httpOnly cookie can grant authentication because it is secure, but it cannot grant XSRF protection because it is always sent. Having them both at the same time means protecting against attacks.
How is an XSRF token implemented
To implement an XSRF token, you need to do several things. First, you need to generate this token as a random long string on the backend side. This should be done right after authentication, as soon as you verify username and password are correct (as well as any other authentication mechanism, if you have any).
If authentication succeeds, you should generate the XSRF token. Then, you should take this and include its text as part of an authentication cookie, sent to be httpOnly. This cookie contains information about the user, and should also include the XSRF token. It is important that we sign this cookie with a private key, so we can verify it is legitimate every time it is presented to authorize a request. A good approach is to work with JWT.
Once this is taken care of, we send the JWT as httpOnly cookie and the XSRF token as a normal cookie. In the frontend (JavaScript), we ensure every request is sent with the XSRF token. We don’t need to do anything on the frontend side with the JWT because it is sent automatically, being httpOnly.
The final part we need to take care about is verifying the token. We should do this on the backend, whenever we receive a request. First, we check if there is a token at all. If so, we extract the token from the JWT and verify it is the same as the one provided separately, and then verify the signature of the JWT. If the two tokens are equal and the JWT signature is correct, then the request is legitimate and we can honour it.
And this is how you implement and XSRF token!
XSRF Token in a Nutshell
In short, an XSRF token is a normal HTTP cookie you set to pair it with another authentication cookie to prevent cross-site forgeries. Those are attacks where a hacker can induce the user to make requests to your site unconsciously.
To implement this, all you need to do is create a random string cookie sent as non-httpOnly, and an authentication cookie which is signed and which includes the token as well. This one should be httpOnly instead.