Skip to main content

Insecurely generated token - OTP

Need

To securely generate OTP and protect it from interception by attackers

Context

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

Description

Non compliant code

defmodule MyApp.ClientSideOTP do
def generate_otp do
otp = :rand.uniform(100000..999999)
MyApp.Server.validate_otp(otp)
end
end

In this insecure code example, the OTP is generated on the client side, which means that it can be intercepted before it even reaches the server. If the OTP is intercepted, an attacker can continue the application flow without having access to the phone number.

Steps

  • Generate the OTP on the server side, not on the client side.
  • Once generated, immediately store the OTP in a secure server-side session.
  • Validate the OTP directly from this secure server-side session.

Compliant code

defmodule MyApp.ServerSideOTP do
def generate_otp do
otp = :rand.uniform(100000..999999)
Plug.Conn.put_session(conn, :otp, otp)
end

def validate_otp(conn, input_otp) do
session_otp = Plug.Conn.get_session(conn, :otp)
input_otp == session_otp
end
end

In this secure code example, the OTP is generated and stored on the server side. When validating the OTP, it's compared directly with the OTP stored in the server-side session, which prevents interception and unauthorized application flow continuation.

References