Hidden fields manipulation - Ruby

Hidden fields manipulation - Ruby

Need

Prevention of unauthorized manipulation of hidden fields

Context

  • Usage of Ruby 2.7.1 as the programming language for development
  • Usage of Rails framework for building web applications

Description

Non compliant code

        class UsersController < ApplicationController
  def update
    @user = User.find(params[:id])
    @user.update_attributes(params[:user])
    redirect_to @user
  end
end
        
        

In the code above, we have a UsersController with an update action. This action is responsible for updating a user's details in the database.

The vulnerability lies in the line where we call @user.update_attributes(params[:user]). Here, we're updating the attributes of the @user object directly from the parameters that are sent in the HTTP request.

Ruby on Rails uses a feature called 'strong parameters' to prevent unwanted fields from being updated. However, in this case, we're not using strong parameters, and we're allowing all parameters to be updated. This means that even hidden fields can be updated if they are included in the HTTP request.

An attacker could manipulate the HTTP request to include hidden fields and their desired values, causing undesired behaviors in the application. For example, if there is a hidden field that determines the user's role (like an 'admin' field), an attacker could potentially change their role to 'admin' and gain unauthorized access to certain parts of the application.

This vulnerability is a form of 'Mass Assignment', which is a common vulnerability in Ruby on Rails applications. It happens when a developer allows all model attributes to be updated without restrictions, including those that should be hidden or protected.

Steps

  • Validate and sanitize user input before updating the user attributes.
  • Implement strong parameters to whitelist and validate the allowed parameters for updating the user.
  • Use form tokens or CSRF protection to prevent cross-site request forgery attacks.
  • Avoid using hidden fields for sensitive or critical data.
  • Consider using authorization checks to ensure that the user has the necessary permissions to update the specified user.

Compliant code

        class UsersController < ApplicationController
  before_action :set_user, only: [:update]
  before_action :authorize_user, only: [:update]

  def update
    if @user.update(user_params)
      redirect_to @user
    else
      render :edit
    end
  end

  private

  def set_user
    @user = User.find(params[:id])
  end

  def authorize_user
    unless current_user == @user || current_user.admin?
      redirect_to root_path, alert: "You are not authorized to perform this action."
    end
  end

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

The updated code now includes several security measures to prevent hidden fields manipulation:

1. Strong Parameters: The user_params method is used to whitelist and validate the parameters that are allowed to be updated. This prevents an attacker from modifying any hidden or unpermitted fields.

2. Authorization Checks: The authorize_user method is used to ensure that the current user has the necessary permissions to update the specified user. This prevents an unauthorized user from updating another user's data.

3. Set User: The set_user method is used to find the user that is to be updated. This method is called before the update action is performed.

4. Update Action: The update action now checks if the user update is successful. If it is, it redirects to the user page. If it's not, it renders the edit page again.

5. CSRF Protection: Ruby on Rails has built-in CSRF protection, which is enabled by default. This prevents cross-site request forgery attacks.

By implementing these measures, the application is now protected against hidden fields manipulation.

References