Share
Embed
Transcript
41 slides
-
Rails & Security People should know it Insecure-by-default means insecure
http://homakov.blogspot.com -
Agenda • GET Accessible Actions(method “match”, CSRF) • Mass Assignment(attr_accessible,
“SQL Inject”) • JS(ON) and DOM Injects, Responders and XSS • Regular Expressions and Validators • Common Tips • Headers • [bonus?] OAuth -
• CSRF Protection by default (authenticity_token) • XSS Protection(HtmlSafe, sanitize
by default) • SQL Injects are impossible(active record) • Hundreds of commits with security improvements, etc Rails ARE Secure -
• if I see PHP site with (proper)CSRF protection than
.. it's facebook.com • SQL Injects, XSS, includes, zomg etc • "secure by default" just impossible thus rails is more secure than most php sites are... PHP(and others) is not -
#routes.rb #match usage is a common mistake match “/follow”, to:
“followings#create” match “/followers, to: “followings#index” case 1 -
>This commit disallows calling +match+ without an HTTP verb constraint
by default. To explicitly match all verbs, this commit also adds a :via => :all option to +match+. (@wycats) #update code: post “/follow”, to: “followings#create” get “/followers, to: “followings#index” match “/getpost_endpoint”, via: :all, to: “etc#etc” case 1 -
Make sure to set “post” for state-changing requests. Avoid using
of “match” Use “get” for all data retrieval requests. Scope your routes, be RESTful, please. case 1 tips -
#comments/index.haml :javascript var comments = #{@comments.to_json} OR :javascript var value
= "#{current_user.name}" case 2 -
@comments = {k:"</script><script>alert(1) </script>"} JSON Encoder and ':javascript' (:css too!)
both don't escape anything - output is RAW. case 2 -
Update rails to 4(now html entities are escaped by default)
or set manually ActiveSupport.escape_html_entities_in_html = true in initializers or don't use .to_json in templates. case 2 tips -
Pitfall. That is a pure DOM XSS - you didn't
sanitize it! Escaping \u only helps JSON parser but you should sanitize it before you insert into DOM Don't trust/use any input param until you sanitized it. case 3 -
Use $.text()/innerText instead of $.html() /innerHTML when possible, always sanitize
any user input even in JS(Rails just escapes). I strongly recommend this patch: ActiveSupport::JSON::Encoding:: ESCAPED_CHARS.merge! '<' => '<' case 3 tips -
Keep in mind - in ruby $^ always match new
lines. Your manuals and books lie. Use \A\z This passes: javascript:alert(1)/* http://hi.com */ added warning/exception in RoR case 4 tips -
protect_from_forgery is a MUST. It is a hassle to deal
with tokens but don't be stupid. No, presence of authenticity_token input doesn't scare a hacker. case 5 tips -
found an XSS for auto_link, remember, always *whitelist* everything -
protocols too javascript://%0Aalert(1) Update your bundle, if you use auto_link or rails_autolink gem case 6 -
Github and Assembla shared the same vulnerability. It was easy
to steal or push code into anybody’s repo 'dropping' your public key. Also you could(still can) set “created/updated_at” to 3012 in *really* a lot of applications to have fun and get the 1st place in 'order by *_at' case 7 -
If use update_attributes/new/create+hash - you should set attr_accessible(If you don’t
use mass assignment - don’t care.) gem 'strong_parameters' whitelist_attributes = true by default. it takes slightly more time to write an app but it’s worth it. IT IS NOT attr_accessor :± case 7 tips -
don't give out private data via JSONP avoid - render
text: contains_user_input XSS - ?callback=<script>..</script> use - render json: data, callback: params[: cb] case 8 tips -
Mass assignment[extended edition]. You can send nested arrays/hashes in any
param. params[:token] can be a huge array(brute): ?token[]=1&token[]=2&token[]=3... it also may contain nils! ?token[] <- nil case 9 - CVE-2012-2660 -
• use system('ls', '.') instead of `ls .` • before_filter{headers['X-Frame-Options']
='SAMEORIGIN'}#application_controller. rb • hide config/initializers/secret_token.rb • obvious: check permissions • WHITELIST • RTFM common tips -
CSRF + GET. code/token getting into master-account with no fingerprints.
omniauth fb strategy vulnerability depends on server side logic bonus OAuth -
Mitigation: CSRF token in 'state' param. Checking $_SESSION['state']==$_REQUEST ['session'] IS
NOT WORKING Check existence and equality both. OR use client side JS based authentication. bonus OAuth