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

Rails 4 Application Security

Rails 4 Application Security

Slides from my O'Reilly Webcast.

http://www.oreilly.com/pub/e/3247

Anthony Lewis

November 12, 2014
Tweet

More Decks by Anthony Lewis

Other Decks in Programming

Transcript

  1. Ruby on Rails 4
    Application Security
    Anthony Lewis

    View Slide

  2. Overview
    • Authorization Attacks
    • Injection Attacks
    • SQL Injection
    • Cross-Site Scripting
    • Cross-Site Request Forgery Attacks
    • Mass Assignment Attacks

    View Slide

  3. Examples
    • The examples in this presentation are based on a
    simple social network application
    • Users sign up for accounts and create posts
    • Assume User and Post models
    • A user has many posts
    • A post belongs to a user

    View Slide

  4. Authorization Attacks
    Authentication is not authorization

    View Slide

  5. Definitions
    • Authentication identifies a user
    • Authorization specifies what a logged-in user can
    access within your application

    View Slide

  6. Authorization Attack
    • This attack is sometimes called an Insecure Direct
    Object Reference
    • In other words, a user might change the URL from
    posts/1 to posts/2 and try to edit another user’s
    post

    View Slide

  7. Example
    # This method lets any logged-in
    # user update any post.
    def update
    @post = Post.find(params[:id])
    # ...
    end

    View Slide

  8. Example
    # This method ensures that a user
    # can only update their own post
    def update
    @post = current_user.posts.find(params[:id])
    # ...
    end

    View Slide

  9. Injection Attacks
    Never trust the user

    View Slide

  10. Injection Attacks
    • An injection attack occurs when user input is
    executed as part of the application
    • Injection attacks are extremely common, especially
    in older applications
    • The first rule of avoiding injection attacks is never
    trust input from the user

    View Slide

  11. SQL Injection
    The most common attack

    View Slide

  12. SQL Injection
    # Never trust user input
    class User
    def self.authenticate(username, password)
    where("username = '#{username}'" +
    " AND password = '#{password}'").first
    end
    end

    View Slide

  13. So Far, So Good
    User.authenticate("tony", "secret")
    SELECT * FROM users WHERE (username = 'tony'
    AND password = 'secret') LIMIT 1
    => #

    View Slide

  14. So Far, So Good
    User.authenticate("tony", "wrong")
    SELECT * FROM users WHERE (username = 'tony'
    AND password = 'wrong') LIMIT 1
    => nil

    View Slide

  15. Magic Words
    • Attackers know a magic phrase for exploiting SQL
    Injection vulnerabilities.
    • What if we enter this for the password?
    ' OR '1' = '1

    View Slide

  16. Uh Oh
    User.authenticate("tony", "' OR '1' = '1")
    SELECT * FROM users WHERE (username = 'tony'
    AND password = '' OR '1' = '1') LIMIT 1
    => #

    View Slide

  17. What Happened?
    • My password isn’t an empty string, but the addition
    of OR '1' = '1' made the expression true
    • The attacker is now logged in as me

    View Slide

  18. Solution
    # Switch to hash conditions
    class User
    def self.authenticate(username, password)
    where(username: username,
    password: password).first
    end
    end

    View Slide

  19. Solution
    • Rails automatically SQL escapes strings in hash
    conditions
    • If you see string interpolation inside a where
    method, assume it is dangerous

    View Slide

  20. Cross-Site Scripting
    Also known as XSS

    View Slide

  21. Cross-Site Scripting
    • A vulnerability that allows attackers to inject client-
    side JavaScript into web pages viewed by others
    • When another user views the page, the JavaScript
    is executed as if it were part of your application

    View Slide

  22. Safe By Default
    • Thankfully, Rails HTML escapes all output by
    default
    • Symbols such as < are replaced with character
    entities such as <
    • But what if your application needs to show HTML
    output?

    View Slide

  23. Example
    # Create a new post with
    # JavaScript in the body
    Post.create(
    title: "XSS Test",
    body: "alert('XSS');"
    )

    View Slide

  24. Example
    # This view code...
    <%= @post.body %>
    # Becomes this HTML...
    <script>alert('XSS');</script>
    # This will not execute

    View Slide

  25. Safe By Default
    • But what if your application needs to show HTML
    output?
    • Users want to use HTML to format their posts

    View Slide

  26. Example
    # This view code...
    <%= raw @post.body %>
    # Becomes this HTML...
    alert('XSS');
    # This WILL execute

    View Slide

  27. Remove Unsafe Tags
    • Rails includes the sanitize method to automatically
    remove unsafe HTML tags
    • The sanitize method uses a whitelist of allowed
    tags to clean up potentially unsafe strings
    • In Rails 4.2, sanitize is based on the Loofah gem

    View Slide

  28. Example
    # Use helper.sanitize in a console
    helper.sanitize "Hello"
    => "Hello"
    # pass a list of allowed tags
    tags = ['em', 'strong']
    helper.sanitize "Hello", tags: tags
    => "Hello"

    View Slide

  29. Example
    # This view code...
    <%= sanitize @post.body %>
    # Becomes an empty string...
    # Obviously, this will not execute

    View Slide

  30. Cross-Site
    Request Forgery
    Also known as CSRF

    View Slide

  31. CSRF Attacks
    • Occurs when one of your application’s users visits
    another site that has been modified by an attacker
    to target your site
    • The attacker must trick your application’s users into
    visiting the malicious page and activating the link
    • The malicious page uses your application’s trust in
    this user to accept requests

    View Slide

  32. Example
    • Imagine you are building an online payment
    application
    • Your application includes a transfer action that
    accepts amount and to parameters that specify
    how much money to transfer to another user
    • An attacker studies the requests generated by your
    site and attempts to replicate those requests on his
    own site

    View Slide

  33. Example


    View Slide

  34. Example
    • If one of your users visits this site, and your site is
    vulnerable to CSRF attacks, $100 is transferred
    from their account to the attackers account
    • This could also be done with a script on the
    attacker’s site that issues requests

    View Slide

  35. CSRF Prevention
    • Never use a GET request to change state
    • Use a POST request to update data
    • Include a user-specific token with all requests that
    change state in your application
    • Ignore requests that do not include this token

    View Slide

  36. CSRF Prevention
    • Rails includes helper methods for generating a
    user-specific token automatically
    • Rails calls this an authenticity_token
    • The token is stored in a meta tag on each page
    • The token is also included in a hidden field on
    every form

    View Slide

  37. CSRF Prevention
    # Your application layout includes
    # a per-user token by default...
    <%= csrf_meta_tags %>
    # That renders this HTML
    name="csrf-param" />
    name="csrf-token" />

    View Slide

  38. CSRF Prevention
    # Your application controller raises
    # an exception if the token is not
    # included with a POST request...
    protect_from_forgery with: :exception

    View Slide

  39. Mass Assignment
    Attacks
    Protect your attributes

    View Slide

  40. Mass Assignment
    • Model methods such as update_attributes and
    new accept a hash of attributes and update or set
    all attributes by default
    • Older Rails versions used the attr_accessible
    model method to define attributes that could be
    mass assigned
    • Rails 4 uses the Strong Parameters gem to move
    this responsibility to the controller

    View Slide

  41. Example
    • An attacker can modify your application’s forms or
    use a tool such as cURL to send parameters you
    aren’t expecting
    • For example, the attacker might try sending
    admin=true to your user signup form

    View Slide

  42. Example
    # The params variable in your
    # controller now looks like this:
    params = {
    user: {
    name: "Tony",
    admin: true
    }
    }

    View Slide

  43. Example
    # In older Rails versions this assigns
    # all attributes unless attr_accessible
    # is setup on the User model
    @user = User.new(params[:user])
    # Assuming your User model has an admin
    # flag, the new user is now an admin

    View Slide

  44. Example
    # In Rails 4 this raises an exception
    # because it is a mass assignment
    # without a call to permit
    @user = User.new(params[:user])
    # The new user is not created

    View Slide

  45. Example
    # The preferred pattern is to call
    # a private user_params method that
    # uses the permit and require methods
    # to setup allowed params
    @user = User.new(user_params)

    View Slide

  46. Example
    private
    def user_params
    params.require(:user).permit(:name, :email)
    end
    # this method returns this hash:
    # { name: "Tony" }
    # the admin flag is silently removed

    View Slide

  47. Summary
    • As your application gains popularity, the risk of
    attack rises
    • Rails provides the tools you need to protect your
    application and your users from attacks
    • Stay up-to-date on security issues

    View Slide

  48. Resources
    • The examples in this presentation are based on
    Chapter 11 of my book Rails Crash Course
    • The security vulnerabilities were taken from the
    OWASP Top 10 List
    • The Open Web App Security Project
    • www.owasp.org

    View Slide

  49. Thank you!

    View Slide