Lack of data validation - OTP
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.