logo

Database

Need

Secure session management

Context

• Usage of Ruby 2.5.0 as the programming language for development

• Usage of Ruby on Rails for building web applications

Description

1. Non compliant code

class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:email])

    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to root_url, notice: "Logged in!"
      flash.now.alert = "Email or password is invalid"...

In this Ruby on Rails application, a session is created when a user logs in. The user's ID is stored in the session object, which is a hash that Rails provides to track data over multiple requests from the same user. When a user logs out, their user ID is simply set to `nil` in the session hash. However, this code does not properly manage the session token. The session token is not expired or invalidated when the user logs out. This means that if an attacker were to gain access to a session token, they could use it to make requests on behalf of the user even after the user has logged out. This is a significant security vulnerability, as it could allow an attacker to impersonate a user and perform actions on their behalf. This type of attack is known as session hijacking or session sidejacking.

2. Steps

• Implement session expiration mechanism

• Set an expiration time for the session token

• Invalidate the session token when the user logs out

• Use secure session storage mechanism

• Encrypt the session token to prevent tampering

• Implement session token regeneration after login

3. Secure code example

class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:email])

    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      session[:expires_at] = Time.current + 2.hours
    else...

The updated code now includes a session expiration mechanism. When a user logs in, an expiration time is set for the session token (`session[:expires_at] = Time.current + 2.hours`). This means that the session will automatically expire 2 hours after it was created, even if the user does not manually log out. In the `destroy` method, which is called when a user logs out, the session token and its expiration time are both set to `nil`. This invalidates the session token, so it can no longer be used to post requests. A new private method `check_session_expiration` is added to check if the session has expired every time a request is made. If the session has expired, the user is logged out and redirected to the login page with a flash message informing them that their session has expired. This code does not yet include secure session storage, session token encryption, or session token regeneration after login. These features would require additional changes to the application's configuration and possibly the use of additional gems.