logo

Database

Need

Prevent unauthorized password change

Context

• Usage of Elixir (1.10 and above) for building scalable and fault-tolerant applications

• Usage of Phoenix Framework for building scalable web applications

Description

1. Non compliant code

def change_password(conn, %{'security_code' => _security_code, 'new_password' => new_password}) do
  user = conn.assigns.current_user
  user = User.changeset(user, %{password: new_password})
  Repo.update!(user)
  send_resp(conn, :ok, 'Password updated')
end

In the insecure code example, the server changes the user's password without verifying the security code provided by the user. This allows an attacker to change a user's password without the correct security code.

2. Steps

• Always validate the security code on the server-side before changing the password.

• Ensure that the security code expires after a certain time period to limit the time window for an attack.

• Lock the account or require additional verification if there are too many failed attempts to enter the security code.

3. Secure code example

def change_password(conn, %{'security_code' => security_code, 'new_password' => new_password}) do
  user = conn.assigns.current_user
  if check_security_code(user, security_code) do
    user = User.changeset(user, %{password: new_password})
    Repo.update!(user)
    send_resp(conn, :ok, 'Password updated')
  else
  end...

In the secure code example, the server first checks if the provided security code matches the one stored in the database for that user. If it does not, the server returns an 'Unauthorized' response. This ensures that an attacker can't change a user's password without the correct security code.