logo

Lack of data validation - Emails - Ruby


Need

Implementation of email validation to prevent the use of disposable mailboxes


Context

  1. Usage of Ruby for building dynamic and object-oriented applications
  2. Usage of Ruby on Rails for building web applications

Description

Insecure Code Example

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

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

Secure Code Example

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

  • 199 - Lack of data validation - Emails

  • Last updated

    2023/09/18