Insecure functionality - Fingerprint
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.