Skip to main content

Insecure object reference - Personal information

Need

Prevent unauthorized modification of other user's information

Context

  • Usage of Elixir (version 1.12 and above) for building scalable and fault-tolerant applications
  • Usage of Phoenix Framework for building web applications
  • Usage of Plug for session handling
  • Usage of Ecto for data persistence

Description

Non compliant code

defmodule UserController do
def update(conn, %{'id' => id, 'user' => user_params}) do
user = Repo.get(User, id)
changeset = User.changeset(user, user_params)
Repo.update(changeset)
end
end

The code below is insecure because it uses the user_id from the request parameters to fetch and update a user. An attacker can change the user_id parameter to update another user's information.

Steps

  • Store the authenticated user's id in the session after successful login.
  • Instead of getting the user id from request parameters, get it from the session.
  • Use the user id from the session to fetch and update the user.

Compliant code

defmodule UserController do
def update(conn, %{'user' => user_params}) do
id = get_session(conn, :user_id)
user = Repo.get(User, id)
changeset = User.changeset(user, user_params)
Repo.update(changeset)
end
end

The code below is secure because it uses the user_id stored in the session to fetch and update the user. Even if an attacker changes the user_id in the request parameters, it won't affect which user is updated because the user_id in the session is used.

References