Skip to main content

Insecure Functionality

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