logo

Database

Concurrent Sessions Control Bypass

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

1. 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)
      _ ->...

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.

2. Steps

• Maintain a server-side record of active user sessions

• Immediately invalidate any existing sessions for a user when a new login occurs

3. Secure code example

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
        |> redirect(to: "/dashboard")...

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.