DEV Community

Cover image for Secure CSRF Token Storage in Rails 7 using Encrypted Cookies
Abinash Panda
Abinash Panda

Posted on

Secure CSRF Token Storage in Rails 7 using Encrypted Cookies

What is a CSRF token?

A CSRF token is a unique value that is generated by the server and stored on the client’s session. This token is included in every subsequent request made by the client, either in an HTTP header or as a hidden field on a form submission. The Rails server then compares this token against the one stored in its session store. If the token on the request does not match the one on the server, the request is considered illegitimate and is not processed.

Why do we need to store the CSRF token outside of the session?

The default CSRF protection in Rails stores the token in the user’s session, which is secure but may cause issues when using a cache such as Redis. This is because sessions for unauthenticated users may be created in large numbers, containing only the CSRF token, which can lead to cache thrashing and decreased performance. This may cause eviction of old sessions, which can negatively impact the overall performance of the application.

In order to solve this problem, Rails version 7 introduces a new feature where CSRF tokens are stored in an encrypted cookie rather than the session. This method is more efficient as it only stores tokens for authenticated users.

How to use it?

To use this feature, we need to set config.action_controller.use_custom_csrf_token to a lambda that returns the token to be used for the request. The lambda will then be called with the request object as an argument.

Add the below code in config/application.rb to use an encrypted cookie to store the CSRF token.

config.action_controller.use_custom_csrf_token = lambda do |request|
request.cookies['csrf_token'] = Encryption.encrypt(request.session[:_csrf_token])
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

philsmy profile image
Phil Smy

If I do this I get the following runtime error:

Puma caught this error: Invalid option key: use_custom_csrf_token= (RuntimeError)
Enter fullscreen mode Exit fullscreen mode

How does this work?