Rails Security Pitfalls
Jerome Basa
@jldbasa
March 2014
Slide 2
Slide 2 text
whoami
2014
2.6 years
many to
mention
3 years
7 years
hire me! ^^;
Slide 3
Slide 3 text
Web Application Security
Slide 4
Slide 4 text
Web Application Security
source: Cenzic Vulnerability Report 2014
Slide 5
Slide 5 text
Web Application Security
“96% of tested applications in 2013
have vulnerabilities” - CENZIC
developer usually prioritise feature
completion rather than security certification
not all companies hire dedicated
security experts
Slide 6
Slide 6 text
is Rails secure?
Slide 7
Slide 7 text
Is Rails secure?
relatively secure by default
Attack Type Rails Countermeasure
SQL Injection SQL Escape
XSS HTML Escape
CSRF Authenticity Token
Slide 8
Slide 8 text
Is Rails secure?
one framework is not more secure
than another
flawed coding = successful attack
Slide 9
Slide 9 text
Security Pitfalls
Slide 10
Slide 10 text
SQL Injection
Slide 11
Slide 11 text
SQL Injection
exploits of a mom » xkcd.com/327
Slide 12
Slide 12 text
SQL Injection
User.where("username LIKE '%#{params[:q]}%'")
!
!
SELECT
`users`.*
FROM
`users` WHERE (username LIKE '%jerome%')
!
!
Slide 13
Slide 13 text
SQL Injection
!
params[:q] = "') UNION SELECT username, password,1,1,1 FROM
users --"
!
!
SELECT
`users`.*
FROM
`users`
WHERE (username LIKE '%')
UNION
SELECT
username,
password,
1,1,1
FROM users --%')
Slide 14
Slide 14 text
SQL Injection
!
params[:q] = "') UNION SELECT username, password,1,1,1 FROM
users --"
!
!
SELECT
`users`.*
FROM
`users`
WHERE (username LIKE '%')
UNION
SELECT
username,
password,
1,1,1
FROM users --%')
Slide 15
Slide 15 text
SQL Injection
User.where("username LIKE ?", "%#{params[:q]}%")
countermeasure
countermeasure
Slide 16
Slide 16 text
Cross-site Scripting (XSS)
Slide 17
Slide 17 text
XSS
!
<%= raw @post.content %>
template code
params[:content] = "alert('hello');"
content from user
Slide 18
Slide 18 text
XSS
Slide 19
Slide 19 text
XSS
<%= sanitize(@post.content, tags: %w(a),
attributes: %w(href)) %>
countermeasure
sanitize user input; use Rails method such
as sanitize
look for: raw and .html_safe
Slide 20
Slide 20 text
Cross-site Request Forgery (CSRF)
Slide 21
Slide 21 text
CSRF
attacker sends request on victim’s
behalf
User Your Site
logs in Malicious
Site
navigates to
Your Site
hidden image,
post back to
doesn’t depend on XSS
Slide 22
Slide 22 text
CSRF
use HTTP (GET, POST) methods
appropriately
countermeasure
use Rails default CSRF protection
Slide 23
Slide 23 text
‘match’ in Routing
# Example in config/routes.rb
match ':controller(/:action(/:id))(.:format)'
match matches all HTTP verb and Rails CSRF
protection doesn’t apply to GET requests.
route will allow GET method to delete posts
match ‘/posts/delete/:id',
:to => “posts#destroy",
:as => "delete_post"
Slide 24
Slide 24 text
‘match’ in Routing
# Example in config/routes.rb
# match ':controller(/:action(/:id))(.:format)'
!
match '/posts/delete/:id',
:to => "posts#destroy",
:as => “delete_post",
:via => :delete
use correct HTTP verb in routing e.g. ‘get’,
‘post’, etc.
countermeasure
use :via
Slide 25
Slide 25 text
Mass Assignment
Slide 26
Slide 26 text
Mass Assignment
!
def create
# ...
@user = User.new(params[:user])
# ...
end
!
!
Slide 27
Slide 27 text
Mass Assignment
!
class User < ActiveRecord::Base
attr_protected :admin
!
# ...
end
blacklist attributes using attr_protected
countermeasure
Slide 28
Slide 28 text
Mass Assignment
!
class User < ActiveRecord::Base
attr_accessible :username, :email
# ...
end
whitelist attributes using attr_accessible
!
config.active_record.whitelist_attributes = true
Slide 29
Slide 29 text
Mass Assignment
!
def create
# ...
@user = User.new(params_user)
# ...
end
!
private
!
def params_user
params.require(:user).permit(
:username,
:email)
end
use strong parameters
Slide 30
Slide 30 text
Secret Token
Slide 31
Slide 31 text
Secret Token
!
MyApp::Application.config.secret_token = '38d07e4b…'
config/initializers/secret_token.rb
this token is used to sign cookies that the
application sets. for more info, read:
http://bit.ly/hack_rails_app_using_secret_token
Slide 32
Slide 32 text
Secret Token
!
MyApp::Application.config.secret_token = ENV['TOKEN']
config/initializers/secret_token.rb
* generate new secret by running $ rake secret
countermeasure
Slide 33
Slide 33 text
Logging Parameters
Slide 34
Slide 34 text
Logging Parameters
!
Rails.application.config.filter_parameters += [:password, :ssn]
:password & :ssn will be replaced with “[FILTERED]”
logs
Slide 35
Slide 35 text
Scopes
Slide 36
Slide 36 text
Scopes
!
class User < ActiveRecord::Base
has_many :posts
end
!
def edit
@post = Post.find_by id: params[:id]
end
Slide 37
Slide 37 text
Scopes
!
def edit
@post = current_user.posts.find_by id: params[:id]
end
use authorization gem such as cancan or pundit
look for :edit, :update, :destroy methods
countermeasure
Slide 38
Slide 38 text
Admin
Slide 39
Slide 39 text
Admin URL
http://yourapp.com/admin
“old habits die hard”
Slide 40
Slide 40 text
Admin URL
whitelist IP address
recommendation
use sub-domain
separate application
VPN or intranet access only
Slide 41
Slide 41 text
Conclusion
Slide 42
Slide 42 text
Conclusion
keep your application up to date on all layers
never trust any data from a user
code review
use brakeman gem - brakemanscanner.org