Skip to main content

Lack of data validation - Emails

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