Authentication Mechanism Absence or Evasion - OTP - Elixir

Authentication Mechanism Absence or Evasion - OTP - Elixir

Need

Ensure that OTPs are validated properly during user registration.

Context

  • Usage of Elixir (1.12.0 and above) for building scalable and fault-tolerant applications
  • Usage of Phoenix Framework for building web applications (version 1.6.0 and above)

Description

Non compliant code

        defmodule MyAppWeb.UserController do
  use MyAppWeb, :controller

  def verify_otp(conn, %{'otp' => otp}) do
    if String.length(otp) == 6 do
      json(conn, %{status: 'success'})
    else
      json(conn, %{status: 'error'})
    end
  end
end
        
        

This code is insecure because it only checks if the length of the OTP is 6, but it doesn't verify if the OTP matches the one generated by the server. This allows an attacker to bypass the OTP verification by entering any six-digit number.

Steps

  • Implement server-side OTP generation and storage (temporary, expires after a certain time or after it is used).
  • Upon user OTP submission, verify it against the OTP stored on the server.
  • Consider using OTP validation libraries to handle this more securely and efficiently.

Compliant code

        defmodule MyAppWeb.UserController do
  use MyAppWeb, :controller

  def verify_otp(conn, %{'otp' => otp, 'user_id' => user_id}) do
    stored_otp = get_stored_otp_for_user(user_id)
    if otp == stored_otp do
      json(conn, %{status: 'success'})
    else
      json(conn, %{status: 'error'})
    end
  end
end
        
        

This code is secure because it verifies the user's OTP against the one stored on the server, ensuring that only a correct OTP will pass the verification process.

References