Insecure Functionality - Elixir

Insecure Functionality - Elixir

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

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.

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.

Compliant code

        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
    send_resp(conn, :unauthorized, 'Incorrect security code')
  end
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.

References