Preventing Cross-Site Request Forgery using Synchronizer Token Pattern
In an era where all data are stored in the cloud and transactions are being done online, ensuring the security of those data and transactions is crucial. Cross-site request forgery is a type of attack which targets state changing actions such as fund transfers rather than data theft.
What is Cross-Site Request Forgery(CSRF)?
When a user logs into a bank, the bank website will create a session for the user once he/she is authenticated and the session ID, which is used to uniquely identify the user throughout the session, is set as a cookie in the browser. Only the user can see these cookies. With every action user performs on this page, the cookies set by only the Bank’s site is being sent. Any other site the user visits does not have access to these cookies nor can the Bank’s site access other cookies in user’s browser.
But there can be malicious websites that may provoke users to perform actions such as click some button, that contains a script which triggers a web call to the particular bank. Since the request is being sent Bank’s domain, the browser will add the cookies to the request and send. Bank will authenticate as the user, himself/herself has requested and perform the requested action such as fund transfers.
This is the most common example of CSRF which implies an attack where an undesired action is performed on behalf of the victim, inheriting identity and privileges.
In this case, the security hole in the Bank’s system is that it is unable to distinguish between a forged request and a legitimate one.
How can we prevent it?
There are 2 types of patterns that systems can adapt in order to prevent CSRF.
1) Synchronizer Token Pattern
2) Double Submit Cookies Pattern
In this blog post, we will look at how the Synchronizer Token Pattern prevents CSRF and how it can be implemented in a Java application. The following blog post will discuss Double Submit Cookies Pattern.
Synchronizer Token Pattern
In Synchronizer Token pattern, the application would generate a CSRF token which is one-time use only and store it server side against the sessionID. This token would be sent embedded to the HTML. When the user requests an action such as Transfer Funds, this token will be sent along with other parameters. The server will validate sessionID and this token value. If they match, the request will be completed.
The token is generated uniquely per form. Therefore, the attacker has no way of accessing this. Even if the attacker submits the other parameters, since the token is unavailable, the server will not complete the action. Thereby, CSRF is prevented.
Unsuccessful Methods to prevent CSRF
1) Using POST requests instead of GET.
<form action=”/transfer” method=”POST”>
<input type=”hidden” name=”from” value=”bob234">
<input type=”hidden” name=”to” value=”john123">
<input type=”submit” value=”Click to see cat pictures”>
In the above form, the input fields are hidden therefore users will only see the button. but once the button is selected it will be submitted along with the other parameters.
2) Using secret cookies will not prevent CSRF because even secret tokens are submitted with the request.
This example is a simple Spring boot application and it uses thymeleaf for templating.
The login page will be as follows.
It consists of a simple form that submits the values to /login through a POST call.
We have to next implement the POST /login endpoint to receive these values.
Here, we have the LoginController and the Authentication Service that handles all login requests. Login endpoint is which receives the POST call. The controller consumes the authentication service to authenticate the user using the given username and the password. If the user is authenticated, ‘generateSessionId’ method creates a cookie for the user that contains a uniquely generated session ID. It also generates the CSRF token and stores it against the session ID. Another cookie is created to store his username. And then, he will be redirected to the home page.
After logging in, you can observe the following cookies being added to your browser.
This is the home page that contains another form. For demo purpose, let’s assume it is a form for Fund Transfers. It submits the data to /transfer through a POST call.
In Synchronizer Token pattern, simply submitting the session ID with the username is not sufficient. CSRF token should be provided as well. Therefore, in here, there is an AJAX call to the /token endpoint is included and it will be invoked when the form loads.
Let’s look at the token endpoint next.
In this endpoint, first the sessionID is extracted from the cookie and the token generated for that session ID is retrieved and sent as the response.
The AJAX call, upon receiving the response will extract the token and embed it to a hidden input field as,
$("#submit-btn").before('<input type="hidden" name="csrf" value="'+data+'">');
You can observe this element from the browser.
This is invisible to the user. When the user submits the form, this value is submitted as well.
Now, let’s look at the /transfer endpoint which receives the POST request.
Upon receiving the request, the session ID and the CSRF token is validated and the transaction will be completed if the provided values are correct.
So, in this scenario, even if an attacker can provoke you to complete some action and send an unintended request to the server, although the cookies are sent, the CSRF token is not present. Therefore, the transaction will not be completed, hence preventing CSRF.
The full implementation of this example can be found at,
One drawback of this pattern would be that the server has to store all CSRF tokens. This could be a nuisance when there are multiple sessions at the same time.
In the next blog post, we will look at how Double Submit Cookie pattern can be used to prevent CSRF attacks.