Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails Application Security

Rails Application Security

Presentation given at the Austin on Rails meeting on July 26, 2011. I discussed the first five vulnerabilities from the OWASP Top 10 Web Application Security Risks.


Anthony Lewis

September 26, 2011


  1. Ruby on Rails Application Security Anthony Lewis – @anthonylewis

  2. Overview Top Five Vulnerabilities Mass Assignment Definitions, Examples & Solutions

    Rails 3.1 Features https://github.com/anthonylewis/hackme
  3. Injection Still the most common way to get hacked

  4. # don’t do this... def self.authenticate( username, password ) where(

    "username = '#{username}' " + "AND password = '#{password}'" ).first end SQL Injection?
  5. So Far So Good User.authenticate( "tony", "secret" ) => #<User

    id: 1, username: ... User.authenticate( "tony", "wrong" ) => nil SELECT * FROM "users" WHERE (username = 'tony' AND password = 'secret') LIMIT 1 SELECT * FROM "users" WHERE (username = 'tony' AND password = 'wrong') LIMIT 1
  6. Magic Words ‘ OR ‘1’=’1

  7. Uh Oh User.authenticate( "' OR '1' = '1", "' OR

    '1' = '1" ) => #<User id: 1, username: ... SELECT * FROM "users" WHERE (username = '' OR '1' = '1' AND password = '' OR '1' = '1') LIMIT 1
  8. # array conditions def self.authenticate( username, password ) where( "username

    = ? AND password = ?", username, password ).first end Injection Solutions # hash conditions def self.authenticate( username, password ) where( :username => username, :password => password ).first end
  9. Cross-Site Scripting Also known as XSS

  10. Definition A vulnerability that allows attackers to inject client-side script

    into web pages viewed by others
  11. Rails - Safe by Default Thankfully, Rails 3 HTML escapes

    all output by default. But what if your application needs to show unescaped output?
  12. Some people, when confronted with a problem, think ‘I know,

    I'll use regular expressions.’ Now they have two problems. “ – Jamie Zawinski
  13. Many have tried to write a regex that removes bad

    HTML. Most have failed, often spectacularly.
  14. Sanitize Rails includes a whitelist-based filter to remove all potentially

    dangerous tags and attributes from user input. The sanitize method is easy to use and thoroughly tested.
  15. Usage sanitize "<p>Foo<script>alert('Bar')</script></p>" => "<p>Foo</p>" sanitize "<sc<script>ript>alert('Bar')</script>" => "" sanitize

    "<p>Foo</p>", :tags => %w(a b i) => "Foo"
  16. Broken Authentication & Session Management They let sheep in Starbucks?

  17. Hashing Passwords should always be encrypted. A hash is a

    one-way encryption. Once encrypted, the original password cannot be recovered. If a site e-mails you your password, they’re doing it wrong.
  18. bcrypt bcrypt is highly recommended. bcrypt includes a work factor

    to adjust its speed as hardware continues to get faster. bcrypt also has built-in salts to prevent rainbow table attacks.
  19. bcrypt in Rails 3.1 Rails 3.1 includes secure encryption in

    ActiveModel::SecurePassword Add a string field to your model called password_digest Call class method has_secure_password
  20. bcrypt in Rails 3.1 Passwords are encrypted with bcrypt and

    stored in password_digest Adds authenticate instance method that takes the unencrypted password as a parameter
  21. bcrypt in Rails 3.1 class User < ActiveRecord::Base has_secure_password validates

    :password, :presence => { :on => :create } end
  22. Session Hijacking Stealing a session ID allows an attacker to

    impersonate another user. The free Firefox plugin Firesheep makes this one-click easy.
  23. Firesheep

  24. Solutions Always use SSL. Set an expiration date for sessions.

    Destroy sessions when users log out.
  25. SSL in Rails 3.1 To ensure that a controller is

    always accessed with HTTPS, we add a call to the force_ssl class method. To restrict this to only certain actions, we can use the :only or :except options.
  26. SSL in Rails 3.1 class ApplicationController < ActionController::Base protect_from_forgery #

    always use SSL force_ssl end
  27. Insecure Direct Object References Users will play with your URLs

  28. Authorization Authentication != Authorization Authentication identifies a user. Authorization specifies

    what they can access within the application.
  29. Restrict Access def update # user can update any post

    # by manipulating the URL @post = Post.find(params[:id]) ... end
  30. Restrict Access def update # user can only update #

    their own posts @post = current_user.posts.find(params[:id]) ... end
  31. CanCan CanCan is a role-based authorization plugin by Ryan Bates.

    Authorization can be enforced in the Model, View, and Controller. There is (obviously) a RailsCast covering exactly how it works.
  32. Cross-Site Request Forgery Also known as CSRF

  33. Definition CSRF is almost the opposite of XSS It exploits

    the trust that a site has in an authorized user Tricks the victim into submitting a request to another site
  34. <!-- Include this image tag on your site and everyone

    visiting will be automatically logged out of their Google accounts --> <img src="http://www.google.com/ig/logout">
  35. CSRF Prevention Never use an HTTP GET request to change

    state Include a secret, user-specific token in all requests which change state
  36. CSRF Prevention class ApplicationController < ActionControll... protect_from_forgery end <!DOCTYPE html>

    <html> <head> ... <%= csrf_meta_tag %>
  37. Mass Assignment A Rails-Specific Problem

  38. Definition Model methods update_attributes and new accept a hash of

    attributes and will set or update them all attributes by default.
  39. # by default a user can set any # attribute

    in the user model @user = User.new(params[:user]) # by default a user can update any # attribute in the post model @post.update_attributes(params[:post]) Mass Assignment
  40. Never Trust User Input.

  41. Seriously.

  42. The Exploit An attacker will use Firebug to edit your

    form and add fields in seconds A clever attacker will use a tool like cURL to automate sending their data to your update action
  43. Restricting Access attr_protected specifies attributes that are not accessible via

    mass update attr_accessible specifies attributes that are accessible via mass update Always prefer the whitelist approach
  44. Rails 3.1 Adds Scopes Add :as => :admin to specify

    attributes that are accessible in the admin scope The user controller will remain the same and the scope will be applied in an admin controller
  45. Accessible With Scope class User < ActiveRecord::Base attr_accessible :username, :password

    attr_accessible :username, :password, :role, :as => :admin end # in the admin controller @user = User.new(params[:user], :as => :admin)
  46. Disabling Protection In Rails 3.1 you can completely disable attribute

    protection This could be useful in an import script where you control the incoming data
  47. Disabling Protection # in an import action or script @user

    = User.new(params[:user], :without_protection => true)
  48. In Closing... • Security is a functional requirement • Test

    security – success and failure • Prefer whitelists to blacklists • Never Trust User Input • Keep up-to-date on security issues
  49. OWASP • Open Web Application Security Project • OWASP Top

    10 - 2010 • OWASP Secure Coding Practices Quick Reference Guide • Lone Star Application Security Conference (LASCON)
  50. None