Never interpolate user input directly in a SQL statement.
Don't:
User.where("name = #{params[:search][:name]}")
Do:
User.where(name: params[:search][:name])
User.where("name = ?", params[:search][:name])
Never interpolate user input directly in a shell command. There are two ways to prevent attackers from running arbitrary code on your servers:
- Supply an array to
system
orexec
instead of a single string, breaking up the command and its arguments. This way, your arguments won't be interpreted by the shell. - Use
Shellwords.shellescape(str)
(or the shorthandString#shellescape
) to sanitize the user input.
Don't:
system("ls repositories/#{params[:project]}")
`ls repositories/#{params[:project]}`
Do:
system("ls", "repositories/#{params[:project]}")
require "shellwords"
`ls repositories/#{params[:project].shellescape}`
Using to_sym
on user input is vulnerable to denial-of-service attacks. Unlike strings, ruby symbols are never garbage collected,
so an attacker could issue a bunch of requests with different values and fill
up your app's memory. Only use to_sym
on controlled values.
Don't:
if params[:foo].to_sym == :bar
Do:
if params[:foo].to_s == "bar"
Don't use MD5 or SHA1 for hashing passwords and other sensitive information. Use BCrypt.
Don't:
<script>
var objects = <%= @objects.to_json.html_safe %>;
var items = <%= raw @items.to_json %>;
</script>
Do:
class ActionView::Base
def json_escape(s)
result = s.to_s.gsub('/', '\/')
s.html_safe? ? result.html_safe : result
end
alias j json_escape
end
<script>
var objects = <%= j @objects.to_json %>;
var items = <%= j @items.to_json %>;
</script>
This monkey patch should be included in rails 4.1.