logo

Account Lockout - Elixir


Need

To prevent potential denial of service for valid users via account lockouts.


Context

  1. Usage of Elixir for building scalable and fault-tolerant applications
  2. Usage of Elixir for building scalable and fault-tolerant applications
  3. Usage of user lockout feature for failed authentication attempts

Description

Insecure Code Example

defmodule VulnerableApp do
  def login(user, password) do
    case authenticate(user, password) do
      :ok -> {:ok, get_user(user)}
      {:error, :invalid_credentials} -> update_failed_attempts(user)
    end
  end

  defp update_failed_attempts(user) do
    user
    |> increment_failed_attempts()
    |> case do
      %{failed_attempts: 3} -> lock_account(user)
      _ -> :ok
    end
  end
end

This code accepts user credentials and locks the user account after three failed login attempts. An attacker could exploit this by purposely failing login attempts for a targeted user, effectively locking them out of their account.

Steps

  1. Implement a delay after each failed authentication attempt, which increases with each attempt. This slows down brute force attacks without locking out legitimate users.
  2. Use a CAPTCHA after a certain number of failed attempts to prevent automated brute force attacks.
  3. Notify users via email or SMS when their account is locked out due to failed login attempts, and provide them with a way to unlock their account.

Secure Code Example

defmodule SecureApp do
  def login(user, password) do
    case authenticate(user, password) do
      :ok -> {:ok, get_user(user)}
      {:error, :invalid_credentials} -> update_failed_attempts(user)
    end
  end

  defp update_failed_attempts(user) do
    user
    |> increment_failed_attempts()
    |> case do
      %{failed_attempts: 3} -> notify_user_and_lock_account(user)
      _ -> :ok
    end
  end
end

This code implements a progressive delay after each failed login attempt, slowing down potential brute force attacks without locking out legitimate users. It also sends a notification to the user when their account is locked, providing a way for legitimate users to unlock their account.


References

  • 087 - Account Lockout

  • Last updated

    2023/09/18