Insecurely generated token - OTP - Ruby

Insecurely generated token - OTP - Ruby

Need

Secure generation and transmission of OTP tokens

Context

  • Usage of Ruby 2.7.0 for Ruby programming
  • Usage of Rails framework for building web applications

Description

Non compliant code

        class OtpController < ApplicationController
  def generate_otp
    otp = rand(100000..999999)
    render json: { otp: otp }
  end
end
        
        

In the above code, an OTP (One Time Password) is generated on the client-side within the generate_otp method of the OtpController. This OTP is a random number between 100000 and 999999. The generated OTP is then sent to the client as a JSON response.

The vulnerability here is that the OTP is generated on the client-side and sent to the server. This means that if an attacker intercepts the request, they can access the OTP directly. This makes it possible for an attacker to continue the application flow without needing access to the phone number used.

In a secure system, the OTP should be generated server-side and sent directly to the user's phone number. The server should then wait for the user to submit the OTP for verification. This way, even if an attacker intercepts the request, they won't have access to the OTP because it's sent directly to the user's phone and not included in the server's response.

Steps

  • Generate the OTP server-side instead of client-side.
  • Use a secure random number generator to generate the OTP.
  • Do not expose the OTP in the response to the client.
  • Send the OTP securely to the client using a secure communication channel.
  • Implement proper authentication and authorization mechanisms to ensure that only authorized users can generate and use the OTP.

Compliant code

        class OtpController < ApplicationController
  def generate_otp
    otp = SecureRandom.random_number(1_000_000..9_999_999)
    # Send OTP securely to the client, e.g., via SMS or email
    # ...
    render json: { message: 'OTP has been generated and sent.' }
  end
end
        
        

The original code was generating the OTP (One-Time Password) on the client-side and sending it to the server. This is a security vulnerability because an attacker could intercept the request and gain access to the OTP, allowing them to continue the application flow without needing access to the phone number used.

The fixed code generates the OTP on the server-side using Ruby's SecureRandom module, which generates a truly random number in a secure manner. This OTP is then sent to the client via a secure communication channel (e.g., SMS or email). The specifics of this step are not shown in the code and would depend on the specifics of your application and infrastructure.

The response to the client no longer includes the OTP. Instead, it simply confirms that the OTP has been generated and sent. This prevents the OTP from being exposed in the client-server communication, adding an additional layer of security.

Finally, it's important to ensure that proper authentication and authorization mechanisms are in place to ensure that only authorized users can generate and use the OTP. This is not shown in the code, but it's a crucial part of securing the OTP generation and usage process.

References