Insecure session expiration time - Ruby

Insecure session expiration time - Ruby

Need

Enforce secure session expiration time

Context

  • Requirement of Ruby version 2.0 or higher
  • Usage of ActionPack for handling web requests and managing controllers in a Ruby on Rails application
  • Usage of ActiveRecord for Object-Relational Mapping (ORM) in database operations
  • Usage of ActiveSupport for extending Ruby on Rails with additional utility methods and functionalities

Description

Non compliant code

        # app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :set_session

  private

  def set_session
    session[:user_id] = current_user.id
  end
end
        
        

In the above code, the set_session method is setting the user_id in the session. This is done for every request that is made to the application. However, there is no code to expire the session after a certain period of inactivity.

In this case, if a user logs in and then leaves their computer without logging out, their session will remain active indefinitely. This can be a security risk because if an attacker somehow gains access to the user's computer, they can use the still-active session to impersonate the user and perform actions on their behalf.

This vulnerability is known as "Insecure session expiration time". It's important to have a timeout for user sessions to prevent potential unauthorized access.

Steps

  • Set a proper session expiration time for user sessions.
  • Implement a mechanism to track user activity and reset the session expiration time on each user interaction.
  • Use a secure session storage mechanism to store session data.
  • Consider implementing additional security measures such as session invalidation on logout or password change.

Compliant code

        # app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :set_session

  private

  def set_session
    session[:user_id] = current_user.id
    session[:expires_at] = Time.current + 5.minutes
  end

  def check_session
    if session[:expires_at] < Time.current
      reset_session
    else
      session[:expires_at] = Time.current + 5.minutes
    end
  end
end
        
        

The updated code now includes a session expiration time. When the session is set, an expiration time is also set 5 minutes into the future. This is done with the line session[:expires_at] = Time.current + 5.minutes.

A new method check_session is also added. This method checks if the current time is greater than the session expiration time. If it is, the session is reset, effectively logging out the user. If it is not, the session expiration time is reset to 5 minutes into the future. This means that any interaction from the user will reset the session expiration time, keeping them logged in as long as they are active.

This code should be called at the beginning of each action in your controllers to ensure the session is always checked. This can be done by adding before_action :check_session to your controllers.

This solution ensures that user sessions will expire after 5 minutes of inactivity, addressing the identified vulnerability.

References