Lack of data validation - Special Characters - Ruby

Lack of data validation - Special Characters - Ruby

Need

Implementation of data validation to prevent the entry of special characters in fields

Context

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

Description

Non compliant code

        class UserController < ApplicationController
  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end
end
        
        

In the above code, we are creating a new user in our Ruby on Rails application. We are using the params[:user] to get the user data from the request and directly saving it to the database.

This code is vulnerable because it does not validate the data that is being entered by the user. For example, a user could enter special characters in the name field, which could potentially lead to issues such as SQL Injection or Cross-Site Scripting (XSS) if those characters are not properly handled in other parts of the application.

Specifically, the code is missing a validation step before the save operation, where we should check if the user input contains any special characters and handle them accordingly.

Steps

  • Implement input validation for the user input fields.
  • Use regular expressions or built-in validation methods to ensure that special characters are not allowed in the input.
  • Validate the input on both the client-side and server-side to provide a layered approach to data validation.
  • Display appropriate error messages to the user when special characters are detected in the input fields.
  • Consider implementing a whitelist approach where only specific characters are allowed in the input fields.
  • Regularly update and maintain the validation rules to account for new special characters or patterns that may arise.

Compliant code

        class UserController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end

  private

  def user_params
    params.require(:user).permit(:username, :email).tap do |whitelisted|
      whitelisted[:username] = params[:user][:username].gsub(/[^0-9a-z ]/i, '')
      whitelisted[:email] = params[:user][:email].gsub(/[^0-9a-z@.]/i, '')
    end
  end
end
        
        

The updated code includes a private method user_params that is used to whitelist and sanitize the user input. The user_params method uses the permit method to whitelist the :username and :email parameters.

The tap method is then used to modify these whitelisted parameters. The gsub method is used with a regular expression to replace any special characters in the :username and :email fields with an empty string. This effectively removes any special characters from the user input.

The create method now uses user_params instead of params[:user] to create a new user. This ensures that only sanitized and validated input is used to create a new user.

This approach provides a server-side solution to the lack of data validation vulnerability. It is also recommended to implement client-side validation to provide a layered approach to data validation.

References