第1页
The World of
Ruby on Rails Security
JJustin Collinss @@presidentbeeeff
RailsConf 2015
第3页
Agenda
What Rails Provides What Rails Doesn’t Provide What to Do About It
@presidentbeef
第4页
What Rails Provides
@presidentbeef
第5页
Cross Site Scripting Protection
Rails 2 Need to use h() everywhere
Rails 3/4 Escape template output by default
@presidentbeef
第6页
Rails 3/4 Examples
Escaped <%= params[:q] %> Not escaped <%= raw params[:q] %> Also not <%= params[:q].html_safe %>
@presidentbeef
第7页
Cross Site Scripting
@presidentbeef
第8页
Lots of Safe(ish) Helpers
audio_tag image_tag button_tag form_for radio_button_tag text_area_tag tag …
@presidentbeef
第9页
Cross Site Request Forgery (CSRF)
http://bank.com/transfer?amount=100000&to=attacker1337
@presidentbeef
第10页
CSRF Protection
“Synchronizer Token Pattern” Save a CSRF token to the session Insert the CSRF token in forms Match tokens on POSTs
@presidentbeef
第11页
CSRF Protection
<html> <head> <meta content="authenticity_token" name="csrf-param" /> <meta content="sM/p9qSKLI/aExm7Qyk2yf5j7ssywzwijLW7/aO1/Y8=" name="csrf-token" /> </head> <body> <form accept-charset="UTF-8" action="login" method="post"> <input name="authenticity_token" type="hidden" value="sM/p9qSKLI/aExm7Qyk2yf5j7ssywzwijLW7/aO1/Y8=" /> </form> </body>
</html>
@presidentbeef
第12页
Mass Assignment
User.create(params[:user]).save! /user/new/?user[admin]=true
@presidentbeef
第13页
Mass Assignment Protection
Rails 2 Optional white/black list in models
Rails 3.1 Option to require whitelist in models
Rails 3.2.3 Whitelist is default in new apps
Rails 4 Whitelist on assignment instead
@presidentbeef
第14页
Strong Parameters
input = params.require(:name).permit(:email) User.create(input).save!
@presidentbeef
第15页
Cookie Session Stores
Rails 2/3 Signed session cookies
Rails 4 Encrypted session cookies JSON, not Marshal
@presidentbeef
第16页
SQL Injection Protection
Rails 2/3 Parameterized queries
Rails 4 Also Arel
@presidentbeef
第17页
Security Headers
Defaults (Rails 4) X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-Xss-Protection: 1; mode=block
config.force_ssl = true
Strict-Transport-Security: max_age=31536000
@presidentbeef
第18页
What Rails Doesn’t Provide
(Not an exhaustive list)
@presidentbeef
第19页
Back to Cross Site Scripting
.html_safe does not make strings safe .html_safe does not make strings safe .html_safe does not make strings safe .html_safe does not make strings safe .html_safe does not make strings safe
@presidentbeef
第20页
JSON Encoding in Rails 3.2
Loading development environment (Rails 3.2.21) 2.1.5 :001 > {"<x>" => "</script>"}.to_json
=> "{\"<x>\":\"</script>\"}"
@presidentbeef
第21页
JSON Encoding in Rails 4
Loading development environment (Rails 4.2.1) 2.1.5 :001 > {"<x>" => "</script>"}.to_json
=> "{\"<x>\":\"\\u003c/script\\u003e\"}
@presidentbeef
第22页
How About Contextual Encoding?
h j CGI.escape CGI.escapeHTML escape_once escape_javascript html_escape html_escape_once json_escape sanitize sanitize_css
@presidentbeef
第23页
Not Great CSRF Protection
Doesn’t apply to GET Route must disallow GET Must use form helpers for CSRF tokens CSRF tokens persist per session
@presidentbeef
第24页
CSRF Token Failures
Rails 2 - 3.0.3 Raise an exception
Rails 3.0.4 - 3.2.21 Call handle_unverified_request Reset session (default)
Rails 4 Raise an exception (default)
@presidentbeef
第25页
Why Care?
def transfer transfer_monies params[:from], params[:to], params[:amount]
end
https://bounty.github.com/researchers/LukasReschke.html https://blog.nvisium.com/2014/09/understanding-protectfromforgery.html
@presidentbeef
第26页
Server-Side Sessions Not Default
But sqlite is required by default?!
@presidentbeef
第27页
So What?
Rails session cookies are forever Impossible to manage server-side Pre-Rails 4 cookies are simple to decode
@presidentbeef
第28页
Decoding Cookies
require 'base64' Marshal.load(Base64.decode64(cookie.split('--')[0]))
{ "session_id"=>"87918133699858fa3f23542affcc7862", "sensitive_stuff"=>"OOPS DON'T LOOK HERE!", "password"=>"password123", "_csrf_token"=>"ciWkmnuFQZB7EcipKlX+BMYnze6KzAyw2r3aqWql3fU="
}
@presidentbeef
第29页
No Account/Session Management
has_secure_password?
@presidentbeef
第30页
No Authorization Framework
before_filter?
@presidentbeef
第31页
No Directory Traversal Protection
?view=../admin/index render params[:view] ?file=/etc/password send_file params[:file]
@presidentbeef
第32页
Not Enough SQL Injection Protection
calculate exists? having order pluck
… rails-sqli.org
@presidentbeef
第33页
Rails-SQLi.org
github.com/presidentbeef/inject-some-sql
@presidentbeef
第34页
Rails-SQLi.org
github.com/presidentbeef/inject-some-sql
@presidentbeef
第35页
Sanitizing SQL
class User < ActiveRecord::Base def related_users(name) q = "last_name = #{name}" User.where(q) end
end
@presidentbeef
第36页
Manual SQL Escaping
Maybe in here?
@presidentbeef
Yes…?
第37页
Sanitizing SQL?
class User < ActiveRecord::Base def related_users(name) q = "last_name = #{sanitize_sql name}" User.where(q) end
end NoMethodError: undefined
method `sanitize_sql' for #<User:0x00000007566470>
@presidentbeef
第38页
Sanitizing SQLjQuery110209056375133418074_1454547443613
self.class.sanitize_sql name
NoMethodError: protected method `sanitize_sql' called for #<Class:0x00000001a20f70>
@presidentbeef
第40页
Sanitizing SQL???
self.class.__send__(:sanitize_sql, name)
@presidentbeef
第41页
Sanitizing SQL????
name = "') or 1=1 --" self.class.__send__(:sanitize_sql, name)
"') or 1=1 --"
@presidentbeef
第42页
Sanitizing SQL
name = "') or 1=1 --" self.class.__send__(:sanitize_sql, ["?", name])
"''') or 1=1 --'"
@presidentbeef
第43页
Sanitizing SQL
name = "') or 1=1 --" self.class.__send__(:sanitize_sql, last_name: name)
"\"users\".\"last_name\" = ''') or 1=1 --'"
@presidentbeef
第44页
No Rate Limiting
@presidentbeef
第45页
No Open Redirect Protection
Open Redirect redirect_to params[:n]
Safe-ish Redirect
redirect_to URI.parse(params[:n]).path
@presidentbeef
第46页
No Open Redirect Protection
Open Redirect redirect_to params[:n]
Safe-ish Redirect
begin redirect_to URI.parse(params[:n]).path
rescue URI::InvalidURIError #...
end
@presidentbeef
第47页
No Protocol Filtering for Links
link_to "My home page", user.home_url <a href="javascript:alert(1)">
My home page </a>
@presidentbeef
第48页
Even More Missing Security Features
Code Climate Blog: Rails Insecure Defaults
blog.codeclimate.com/blog/2013/03/27/rails-insecure-defaults/
@presidentbeef
第49页
@presidentbeef
@MakotoTheCat
第50页
What To Do About It
@presidentbeef
第51页
Learn About Security
@presidentbeef
第52页
Fix All The Rails Things?
@presidentbeef
第53页
Use Security Libraries
Rate Limiting and Blocking rack-attack
Moar Headers secure_headers
Access Control pundit cancan/cancancan
Authentication omniauth
User Management devise
@presidentbeef
第54页
Use Static Analysis Tools
Brakeman Check for potential vulnerabilities
bundler-audit Check for vulnerable dependencies
@presidentbeef
第55页
Cost of Fixing Defects
@presidentbeef
第56页
The Plan
Use static analysis Scan all the code all the time Don’t fix vulnerabilities, prevent them
@presidentbeef
第57页
Some Options
File system monitoring (using Guard?) Integration into commit tools Continuous integration (with Jenkins?) Integration into release process
@presidentbeef
第58页
More Info
“Using Brakeman and Security Automation in Practice in the SDLC and Stuff” youtu.be/kda8RZ5NIlM
“Putting Your Robots to Work” vimeo.com/54250716
@presidentbeef
第59页
Be Safe!
@presidentbeef / presidentbeef.com @brakeman / brakemanscanner.org @brakemanpro / brakemanpro.com
@presidentbeef