Posted over 4 years ago. Visible to the public. Repeats.

Devise: Invalidating all sessions for a user

Background information about session storage in Rails

Rails has a default mechanism to store the session Archive in the CookieStore. This is a cookie which holds the entire user session hash in the browser. This cookie is serialized, encoded with base64, and signed.

How Devise handles authentication

Devise uses this CookieStore. To track a users session, a salt is stored in the session cookie when a user logs in.
When a user logs out this CookieStore is overwritten and current_user is set to nil.

But what about the old session cookie?

This session cookie is still valid! If this cookie is stolen before it gets overwritten, it can be reused to get access to the application again.

How can we invalidate old session cookies on logout with Devise?

1) Reset password

The only option provided per default by Devise is to change the password of a user. The salt stored in the session cookie by Devise relies on the password. So if you want to logout a user AND invalidate old session cookies you need to reset her password.

2) Extend the salt with a token

Add a session_token column to your devise model (e.g. User) and override Devise #authenticatable_salt method to contain your session token:

class User < ApplicationRecord devise :database_authenticatable, :recoverable, :rememberable def authenticatable_salt "#{super}#{session_token}" end def invalidate_all_sessions! update_attribute(:session_token, SecureRandom.hex) end ... end

You can now invalidate the session cookie by resetting the session_token of a user, when she logs out:

class Users::SessionsController < Devise::SessionsController def destroy current_user.invalidate_all_sessions! super end end

Note that changing the session_token will invalidate all session cookies of this user. If she is logged in on other devises (e.g. tablet, mobile phone, ...) she will be logged out on all of them.

3) Switch to a persisted storage for sessions on the server

Another option to prevent this session replay attack is to switch to persisted storage for sessions. Therefore you can use either a database, memcache or redis. (e.g. with ActiveRecord::SessionStore Archive )
But this means, you need to take care of adding, accessing, and removing the session data. This may has an impact on performance on high traffic sites since a session may be allocated even for anonymous browsing traffic.

Your development team has a full backlog of feature requests, chores and refactoring coupled with deadlines? We are familiar with that. With our "DevOps as a Service" offering, we support developer teams with infrastructure and operations expertise.

Owner of this card:

Natalie Zeumann
Last edit:
over 1 year ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Natalie Zeumann to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more