Lack of data validation - OTP - Elixir

Lack of data validation - OTP - Elixir

Need

To prevent unauthorized actions by ensuring the OTP used is valid and used only once.

Context

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

Description

Non compliant code

        defmodule MyAppWeb.AuthController do
  use MyAppWeb, :controller

  def verify_otp(conn, %{"otp" => otp}) do
    if MyApp.Auth.verify_otp(otp) do
      render(conn, "success.html")
    else
      render(conn, "error.html")
    end
  end
end
        
        

In this example, the OTP is verified, but not invalidated after use. This means that the same OTP can be used multiple times, allowing for potential unauthorized access.

Steps

  • Add an additional step to invalidate the OTP after it has been used.
  • Update the verify_otp function in the Auth context to handle invalidating the OTP.
  • Update the controller to handle cases where the OTP is already invalidated.

Compliant code

        defmodule MyAppWeb.AuthController do
  use MyAppWeb, :controller

  def verify_otp(conn, %{"otp" => otp}) do
    case MyApp.Auth.verify_and_invalidate_otp(otp) do
      :ok ->
        render(conn, "success.html")
      _ ->
        render(conn, "error.html")
    end
  end
end

defmodule MyApp.Auth do
  def verify_and_invalidate_otp(otp) do
    if is_valid_and_not_invalidated(otp) do
      invalidate_otp(otp)
      :ok
    else
      :error
    end
  end
end
        
        

In this secure code, after the OTP is used, it is invalidated by the verify_and_invalidate_otp function in the Auth context. If an invalidated OTP is used again, it is treated as an invalid OTP.

References