Double Submit Cookies Pattern - Node.js
😊
Hello! I hope you had
a good day and an awesome week.
In this post, we are going to talk about how to prevent Cross-site Request Forgery (CSRF) using Double Submit Cookies Pattern and its Node.js implementation. If you are unaware of CSRF, I recommend you to read my previous post here as it is crucial to understand Double Submit Cookies Pattern.
Prerequisites are the knowledge about cookies, CSRF and Synchronizer Token Pattern.
As discussed earlier, there are some drawbacks of Synchronized Token Pattern, namely,
To overcome the aforementioned reasons and to prevent CSRF, Double Submit Cookies Pattern can be used.
Prerequisites are the knowledge about cookies, CSRF and Synchronizer Token Pattern.
As discussed earlier, there are some drawbacks of Synchronized Token Pattern, namely,
- The requirement of excessive storage space in the server due to the fact that all the CSRF tokens are stored.
- Useless if the server supports cross-domain AJAX requests.
To overcome the aforementioned reasons and to prevent CSRF, Double Submit Cookies Pattern can be used.
Double Submit Cookies Pattern
![]() |
Double Submit Cookies Pattern |
When Harry signs in to the bank’s website using his username and password, the bank’s server would create a session and a unique CSRF token for him. Unlike in Synchronizer Token Pattern, CSRF token would not be saved in the server. Instead, it is sent in a cookie to the browser along with the session cookie. Both cookies can be created at the same time or CSRF token cookie can be created after the session cookie. Once Harry requests the ‘Money Transfer’ page, the server returns the related HTML page. JavaScript inside the returned page would read the cookie and put CSRF token value in a hidden field like in Synchronizer Token Pattern.
<form>
<input type=”hidden” name=”X-CSRF-TOKEN” value=”PQR” />
</form>
When Harry submits the money transfer form, CSRF token is sent in the body with rest of the data along with all the cookies created by the destination domain, which in this scenario is ‘unionsavingsbank’. So, both session cookie and CSRF token cookie would be transmitted in the header of the request. The server then validates the request by comparing the received CSRF token value against the value of received CSRF token cookie. If valid, the request is processed.
How this prevent CSRF is due to the fact that cookies from one domain can’t be accessed by other domains. So, if a malicious website tries to attack, it won’t be able to read the cookies created by ‘unionsavingsbank’ domain resulting it not being able to read CSRF token cookie.
One drawback in this method is that we can’t set ‘httpOnly’ flag to CSRF token cookie as JavaScript won’t be able to read the cookie if it is applied.
How this prevent CSRF is due to the fact that cookies from one domain can’t be accessed by other domains. So, if a malicious website tries to attack, it won’t be able to read the cookies created by ‘unionsavingsbank’ domain resulting it not being able to read CSRF token cookie.
One drawback in this method is that we can’t set ‘httpOnly’ flag to CSRF token cookie as JavaScript won’t be able to read the cookie if it is applied.
Node.js Implementation
The template I used for this application can be found
at,
![]() |
Login Page |
Shown above is the login page, which simply accepts username
and password. Once the ‘LOGIN’ button is
clicked, the application sends a POST request to the ‘/home’ endpoint of the
server where the user is validated and redirected to the home page where transferring
money can happen.
![]() |
/home Endpoint |
Above shows the ‘/home’ endpoint where it can be seen that
during the login, three cookies, session-id, date and csrf-token will be
created. In the generation of session-id UUID (universally unique identifier), the timestamp is used and csrf-token UUID is generated randomly. Cookies are seen in the browser as follows.
![]() |
Created Cookies |
When successfully logged in, the user is directed to the following home page.
![]() |
Home Page |
![]() |
Home Page HTML |
Above shows the HTML code of the home page which contains a
form for money transfer. There it can be seen during the form load, JavaScript reads the
csrf-token cookie and put it in a hidden field as below.
Once ‘TRANSFER’ button is clicked, a POST request is sent to
‘/transfer’ endpoint where the CSRF token value is validated with csrf-token
cookie value as below.
![]() |
/transfer Endpoint |
In this scenario, transferring of money happens only if the
two values are equal.
This way Cross-site Request Forgery can be prevented through
Double Submit Cookies Pattern.
The full implementation of this example can be found at,
I hope now you an idea
what Double Submit Cookies Pattern is and how to implement it using Node.js.
Although the web application is now CSRF protected, there
are so many other vulnerabilities it can contain. You can read about them at,
I wish you
all an amazing week ahead! Adios 😊
Comments
Post a Comment