Skip to main content

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

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