Insecure functionality - Fingerprint - Elixir

Insecure functionality - Fingerprint - Elixir

Need

Ensure that only authorized fields can be updated by the user

Context

  • Usage of Elixir (v1.12+) for building scalable and fault-tolerant applications
  • Usage of Ecto for data persistence

Description

Non compliant code

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

The code below is insecure because it allows any field of the user to be updated without checking if the field is allowed to be updated. This could lead to unauthorized updates to fields that should be read-only after account creation, like 'email', or worse, 'admin' status.

Steps

  • Define a whitelist of fields that can be updated.
  • Use the `Ecto.Changeset.cast/4` function to only allow updates to the whitelisted fields.

Compliant code

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

The code below is secure because it only allows 'username' and 'age' to be updated. The 'admin' and 'email' fields are not included in the whitelist, so they cannot be updated even if they are included in the user_params map.

References