Insecure Use of Dangerous Function
This vulnerability category covers the following issues:
Command Injection
Why is this important?
Ruby, like any other programming language, has dangerous functions. If these functions are not used properly, it can have a catastrophic impact on your app. Ruby offers several ways to execute operating system commands, such as:
exec(command)
syscall(command)
system(command)
eval()
constantize()
render()
Attacker controlled input, that is processed by any of these functions, can lead to attackers getting full access to your production environment.
Check out this video for a high-level explanation:
Read below to find out how to fix this issue in your code.
Fixing Insecure Use of Dangerous Function
Option A: Replace the dangerous function with a secure alternative
- Go through the issues that GuardRails identified in the PR.
- Locate the dangerous function. For example:
# One example is exec, but many other dangerous functions exist in Ruby.
exec("/path/to/cmd #{params[:input]}")
- If the functionality is not required, then remove it.
- Otherwise, replace the dangerous function with the following:
# The key point is that the user input is in the second part of the Array
# that is passed to the system function.
# Make sure that no user input is in the first part of the Array that
# contains the command itself.
system("/path/to/cmd","#{params[:input]}")
- Test it and ensure the functionality works as expected
- Ship it 🚢 and relax 🌴
constantize
safely
Option B: Using - Go through the issues that GuardRails identified in the PR.
- Locate the
constantize
method. A vulnerable example is:
class AlertsController < ApplicationController
def create
params[:alert][:type].constantize.new(params[:alert][:value]) # <-- bad code don't do this!
# ... other work
# render page
end
end
- If the functionality is not required, then remove it.
- Otherwise, apply the following pattern:
# Some file where a constant definition is appropriate.
ALERTS = {
'info' => InfoAlert,
'warn' => WarnAlert,
'error' => ErrorAlert
}
class AlertsController < ApplicationController
def create
ALERTS.fetch(params[:alert][:type])).new(params[:alert][:value]))
# ... other work
# render page
end
end
- Test it and ensure the functionality works as expected
- Ship it 🚢 and relax 🌴
Render()
Option C: Restrict Allowed Input to - Go through the issues that GuardRails identified in the PR.
- Locate the
render
method. A vulnerable example is:
def show
render params[:template]
end
- Apply the following pattern:
def show
template = params[:id]
valid_templates = {
"dashboard" => "dashboard",
"profile" => "profile",
"deals" => "deals"
}
if valid_templates.include?(template)
render " #{valid_templates[template]}"
else
# throw exception or 404
end
end
- Test it and ensure the functionality works as expected
- Ship it 🚢 and relax 🌴