Security controls bypass or absence - Data creation - Ruby

Security controls bypass or absence - Data creation - Ruby

Need

Enforcement of security controls for data creation

Context

  • Requirement of Ruby 2.0 or higher for executing the code
  • Usage of Ruby on Rails for building web applications

Description

Non compliant code

        class PolicyController < ApplicationController
  def create
    @policy = Policy.new(policy_params)
    if @policy.save
      params[:beneficiaries].each do |beneficiary|
        @policy.beneficiaries.create(name: beneficiary[:name])
      end
      redirect_to @policy
    else
      render 'new'
    end
  end

  private
  def policy_params
    params.require(:policy).permit(:name, :description)
  end
end
        
        

The above code represents a Policy Controller in a Ruby on Rails application. It has a create method that is responsible for creating a new policy and its associated beneficiaries.

The vulnerability lies in the section of the code where the beneficiaries are created. The code does not limit the number of beneficiaries that can be associated with a policy. This means a malicious user could potentially create a policy with more than the intended limit of four beneficiaries, bypassing the application's security controls and affecting the integrity of the data.

                params[:beneficiaries].each do |beneficiary|
  @policy.beneficiaries.create(name: beneficiary[:name])
end

            
In the above snippet, the code is looping through each beneficiary in the params[:beneficiaries] array and creating a new beneficiary associated with the policy. There is no check to ensure that the number of beneficiaries does not exceed the intended limit.

This could lead to potential data integrity issues, as the system may not be designed to handle policies with more than four beneficiaries. Additionally, it could also result in performance issues if a malicious user creates a policy with a large number of beneficiaries.

Steps

  • Implement server-side validation to limit the number of beneficiaries that can be created per policy
  • Add a check in the create method to ensure that the number of beneficiaries does not exceed the allowed limit
  • Display an error message to the user if the number of beneficiaries exceeds the limit
  • Consider using a constant or configuration parameter to define the maximum number of beneficiaries allowed per policy

Compliant code

        class PolicyController < ApplicationController
  MAX_BENEFICIARIES = 4

  def create
    @policy = Policy.new(policy_params)
    if @policy.save
      if params[:beneficiaries].count <= MAX_BENEFICIARIES
        params[:beneficiaries].each do |beneficiary|
          @policy.beneficiaries.create(name: beneficiary[:name])
        end
        redirect_to @policy
      else
        flash[:error] = "You can only add up to #{MAX_BENEFICIARIES} beneficiaries per policy."
        render 'new'
      end
    else
      render 'new'
    end
  end

  private
  def policy_params
    params.require(:policy).permit(:name, :description)
  end
end
        
        

The updated code now includes a constant MAX_BENEFICIARIES which is set to 4. This constant represents the maximum number of beneficiaries that can be associated with a policy.

In the create method, before creating the beneficiaries, we now check if the number of beneficiaries in the request is less than or equal to MAX_BENEFICIARIES. If the number of beneficiaries is within the limit, we proceed to create the beneficiaries and associate them with the policy. If the number of beneficiaries exceeds the limit, we set an error message in the flash and render the 'new' view again.

This way, we ensure that the number of beneficiaries associated with a policy never exceeds the allowed limit, thereby maintaining the integrity of the data sent.

References