The code example below is vulnerable to Follina
class ExampleController < ApplicationController
def index
@users = User.all
render json: @users
end
def create
@user = User.new(user_params)
if @user.save
render json: @user
else
render json: { errors: @user.errors }, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
The vulnerability in this code comes from the user_params
method, which uses the require
and permit
methods to extract and whitelist parameters from the incoming request. If an attacker can submit a request with an unexpected parameter key, the require
method will raise an error, but Rails will catch that error and silently ignore the unexpected parameter. This means that an attacker can inject arbitrary parameters into the request and bypass the whitelisting mechanism.
Check for unexpected parameters and raise an error if any are found
class ExampleController < ApplicationController
def index
@users = User.all
render json: @users
end
def create
@user = User.new(user_params)
if @user.save
render json: @user
else
render json: { errors: @user.errors }, status: :unprocessable_entity
end
end
private
def user_params
# Check for unexpected parameters and raise an error if found
unexpected_params = params.keys - ['controller', 'action', 'user']
if unexpected_params.any?
raise ActionController::UnpermittedParameters.new(unexpected_params)
end
# Extract and whitelist expected parameters
params.require(:user).permit(:name, :email)
end
end