Lack of data validation - Emails - Ruby

Lack of data validation - Emails - Ruby

Need

Implementation of email validation to prevent the use of disposable mailboxes

Context

  • Usage of Ruby for building dynamic and object-oriented applications
  • Usage of Ruby on Rails for building web applications

Description

Non compliant code

        class UsersController < ApplicationController
  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to @user, notice: 'User was successfully created.'
    else
      render :new
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end
        
        

In the code above, we have a typical create action of a UsersController in a Rails application. This action is responsible for creating new users in the system. The user's details are passed in as parameters, including the email address.

The vulnerability lies in the fact that the code does not validate the email addresses being used to register new users. More specifically, it does not check if the email addresses belong to disposable mailboxes such as yopmail. This could lead to a number of issues, including abuse of the system by users who register with disposable emails and then engage in spamming or other malicious activities.

The user_params method is a private method that simply whitelists the parameters for creating a new user, including the email. There is no validation being done on these parameters. This is where the lack of data validation vulnerability comes into play.

To fix this vulnerability, we need to add a validation step to the create action that checks if the email address belongs to a disposable mailbox before proceeding with the user creation.

Steps

  • Implement server-side email validation to check if the email belongs to a disposable mailbox.
  • Use a reliable email validation library or regex pattern to validate the email format.
  • Consider implementing additional validation checks such as checking for email uniqueness.
  • Display appropriate error messages to the user if the email is invalid or belongs to a disposable mailbox.
  • Consider implementing rate limiting or CAPTCHA to prevent abuse of the email validation process.

Compliant code

        class UsersController < ApplicationController
  before_action :validate_email, only: :create

  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to @user, notice: 'User was successfully created.'
    else
      render :new
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end

  def validate_email
    email = params[:user][:email]
    if email =~ /\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z/i && !email.include?("yopmail")
      return true
    else
      flash[:error] = "Invalid or disposable email address."
      redirect_to new_user_path
    end
  end
end
        
        

The updated code includes a new private method validate_email that is called before the create action. This method checks if the email provided in the user parameters is in a valid format and does not belong to a disposable mailbox (in this case, "yopmail").

The email validation is done using a regex pattern that checks for a standard email format. If the email is not in a valid format or is a disposable email, an error message is flashed to the user and they are redirected back to the new user registration page.

This solution helps to ensure that only valid and non-disposable emails are used for user registration, thereby mitigating the risk of abuse.

For further security, consider implementing additional checks such as email uniqueness validation and rate limiting or CAPTCHA to prevent abuse of the email validation process.

References