Concurrent Sessions Control Bypass - Elixir

Concurrent Sessions Control Bypass - Elixir

Need

Prevent concurrent sessions from a single user account to maintain traceability

Context

  • Usage of Elixir 1.12 for building scalable and fault-tolerant applications
  • Usage of Phoenix Framework 1.6 for web development

Description

Non compliant code

        defmodule MyAppWeb.SessionController do
  use MyAppWeb, :controller
  def create(conn, %{"user" => user_params}) do
    case MyApp.Auth.authenticate(user_params) do
      {:ok, user} ->
        conn
        |> put_session(:user_id, user.id)
        |> redirect(to: "/dashboard")
      _ ->
        conn
    end
  end
end
        
        

The code snippet depicts a controller in a Phoenix application where users can log in without the application terminating their previous sessions. This would allow an attacker who gained access to a user's account to use it concurrently with the legitimate user, causing potential loss of traceability.

Steps

  • Maintain a server-side record of active user sessions
  • Immediately invalidate any existing sessions for a user when a new login occurs

Compliant code

        defmodule MyAppWeb.SessionController do
  use MyAppWeb, :controller
  def create(conn, %{"user" => user_params}) do
    case MyApp.Auth.authenticate(user_params) do
      {:ok, user} ->
        MyApp.Session.invalidate_user_sessions(user)
        conn
        |> put_session(:user_id, user.id)
        |> redirect(to: "/dashboard")
      _ ->
        conn
    end
  end
end
        
        

In the fixed code, upon successful authentication, any existing sessions for the user are invalidated before a new one is created. This ensures that only one session can be active at a time for each user, preventing concurrent session control bypass.

References