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

More Decks by Anthony Lewis

Other Decks in Programming


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

    Rails 3.1 Features https://github.com/anthonylewis/hackme
  2. # don’t do this... def self.authenticate( username, password ) where(

    "username = '#{username}' " + "AND password = '#{password}'" ).first end SQL Injection?
  3. 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
  4. 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
  5. # 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
  6. Rails - Safe by Default Thankfully, Rails 3 HTML escapes

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

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

    HTML. Most have failed, often spectacularly.
  9. 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.
  10. 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.
  11. 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.
  12. 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
  13. 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
  14. Session Hijacking Stealing a session ID allows an attacker to

    impersonate another user. The free Firefox plugin Firesheep makes this one-click easy.
  15. 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.
  16. Restrict Access def update # user can update any post

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

    their own posts @post = current_user.posts.find(params[:id]) ... end
  18. 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.
  19. 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
  20. <!-- 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">
  21. CSRF Prevention Never use an HTTP GET request to change

    state Include a secret, user-specific token in all requests which change state
  22. Definition Model methods update_attributes and new accept a hash of

    attributes and will set or update them all attributes by default.
  23. # 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
  24. 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
  25. 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
  26. 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
  27. 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)
  28. 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
  29. Disabling Protection # in an import action or script @user

    = User.new(params[:user], :without_protection => true)
  30. 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
  31. OWASP • Open Web Application Security Project • OWASP Top

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