Security controls bypass or absence - Data creation
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.