$30 off During Our Annual Pro Sale. View Details »

The World of Rails Security - RailsConf 2015

The World of Rails Security - RailsConf 2015

Learning to keep your Rails application secure is an often-overlooked part of learning Rails, so let's take a trip through the world of Ruby on Rails security! The journey will start with an overview of security features offered by the popular web framework, then we'll detour through dangerous pitfalls and unsafe defaults, and finally end with suggestions for improving security in Rails itself. As a bonus, we'll talk about how to integrate security into the development process.

Justin Collins

April 23, 2015
Tweet

More Decks by Justin Collins

Other Decks in Programming

Transcript

  1. Justin Collins
    @presidentbeef
    Justin Collins
    @presidentbeef
    RailsConf 2015
    The World
    of
    Ruby on Rails Security
    The World
    of
    Ruby on Rails Security

    View Slide

  2. View Slide

  3. @presidentbeef
    Agenda
    What Rails Provides
    What Rails Doesn’t Provide
    What to Do About It

    View Slide

  4. @presidentbeef
    What Rails Provides

    View Slide

  5. @presidentbeef
    Rails 2
    Need to use h() everywhere
    Rails 3/4
    Escape template output by default
    Cross Site Scripting Protection

    View Slide

  6. @presidentbeef
    Rails 3/4 Examples
    Escaped <%= params[:q] %>
    Not escaped <%= raw params[:q] %>
    Also not <%= params[:q].html_safe %>

    View Slide

  7. @presidentbeef
    Cross Site Scripting

    View Slide

  8. @presidentbeef
    Lots of Safe(ish) Helpers
    audio_tag
    image_tag
    button_tag
    form_for
    radio_button_tag
    text_area_tag
    tag

    View Slide

  9. @presidentbeef
    Cross Site Request Forgery (CSRF)
    http://bank.com/transfer?amount=100000&to=attacker1337

    View Slide

  10. @presidentbeef
    CSRF Protection
    “Synchronizer Token Pattern”
    Save a CSRF token to the session
    Insert the CSRF token in forms
    Match tokens on POSTs

    View Slide

  11. @presidentbeef
    CSRF Protection







    value="sM/p9qSKLI/aExm7Qyk2yf5j7ssywzwijLW7/aO1/Y8=" />



    View Slide

  12. @presidentbeef
    Mass Assignment
    User.create(params[:user]).save!
    /user/new/?user[admin]=true

    View Slide

  13. @presidentbeef
    Mass Assignment Protection
    Rails 2
    Optional white/black list in models
    Rails 3.1
    Option to require whitelist in models
    Rails 3.2.3
    Whitelist is default in new apps
    Rails 4
    Whitelist on assignment instead

    View Slide

  14. @presidentbeef
    Strong Parameters
    input = params.require(:name).permit(:email)
    User.create(input).save!

    View Slide

  15. @presidentbeef
    Cookie Session Stores
    Rails 2/3
    Signed session cookies
    Rails 4
    Encrypted session cookies
    JSON, not Marshal

    View Slide

  16. @presidentbeef
    SQL Injection Protection
    Rails 2/3
    Parameterized queries
    Rails 4
    Also Arel

    View Slide

  17. @presidentbeef
    Security Headers
    Defaults (Rails 4)
    X-Content-Type-Options: nosniff
    X-Frame-Options: SAMEORIGIN
    X-Xss-Protection: 1; mode=block
    config.force_ssl = true
    Strict-Transport-Security: max_age=31536000

    View Slide

  18. @presidentbeef
    What Rails Doesn’t Provide
    (Not an exhaustive list)

    View Slide

  19. @presidentbeef
    Back to Cross Site Scripting
    .html_safe does not make strings safe
    .html_safe does not make strings safe
    .html_safe does not make strings safe
    .html_safe does not make strings safe
    .html_safe does not make strings safe

    View Slide

  20. @presidentbeef
    JSON Encoding in Rails 3.2
    Loading development environment (Rails 3.2.21)
    2.1.5 :001 > {"" => ""}.to_json
    => "{\"\":\"\"}"

    View Slide

  21. @presidentbeef
    Loading development environment (Rails 4.2.1)
    2.1.5 :001 > {"" => ""}.to_json
    => "{\"\":\"\\u003c/script\\u003e\"}
    JSON Encoding in Rails 4

    View Slide

  22. @presidentbeef
    How About Contextual Encoding?
    h
    j
    CGI.escape
    CGI.escapeHTML
    escape_once
    escape_javascript
    html_escape
    html_escape_once
    json_escape
    sanitize
    sanitize_css

    View Slide

  23. @presidentbeef
    Not Great CSRF Protection
    Doesn’t apply to GET
    Route must disallow GET
    Must use form helpers for CSRF tokens
    CSRF tokens persist per session

    View Slide

  24. @presidentbeef
    CSRF Token Failures
    Rails 2 - 3.0.3
    Raise an exception
    Rails 3.0.4 - 3.2.21
    Call handle_unverified_request
    Reset session (default)
    Rails 4
    Raise an exception (default)

    View Slide

  25. @presidentbeef
    def transfer
    transfer_monies params[:from],
    params[:to],
    params[:amount]
    end
    https://bounty.github.com/researchers/LukasReschke.html
    https://blog.nvisium.com/2014/09/understanding-protectfromforgery.html
    Why Care?

    View Slide

  26. @presidentbeef
    Server-Side Sessions Not Default
    But sqlite is required by default?!

    View Slide

  27. @presidentbeef
    So What?
    Rails session cookies are forever
    Impossible to manage server-side
    Pre-Rails 4 cookies are simple to decode

    View Slide

  28. @presidentbeef
    Decoding Cookies
    require 'base64'
    Marshal.load(Base64.decode64(cookie.split('--')[0]))
    {
    "session_id"=>"87918133699858fa3f23542affcc7862",
    "sensitive_stuff"=>"OOPS DON'T LOOK HERE!",
    "password"=>"password123",
    "_csrf_token"=>"ciWkmnuFQZB7EcipKlX+BMYnze6KzAyw2r3aqWql3fU="
    }

    View Slide

  29. @presidentbeef
    No Account/Session Management
    has_secure_password?

    View Slide

  30. @presidentbeef
    No Authorization Framework
    before_filter?

    View Slide

  31. @presidentbeef
    No Directory Traversal Protection
    ?view=../admin/index
    render params[:view]
    ?file=/etc/password
    send_file params[:file]

    View Slide

  32. @presidentbeef
    Not Enough SQL Injection Protection
    calculate
    exists?
    having
    order
    pluck
    … rails-sqli.org

    View Slide

  33. @presidentbeef
    Rails-SQLi.org
    github.com/presidentbeef/inject-some-sql

    View Slide

  34. @presidentbeef
    Rails-SQLi.org
    github.com/presidentbeef/inject-some-sql

    View Slide

  35. @presidentbeef
    class User < ActiveRecord::Base
    def related_users(name)
    q = "last_name = #{name}"
    User.where(q)
    end
    end
    Sanitizing SQL

    View Slide

  36. @presidentbeef
    Manual SQL Escaping
    Maybe in here?
    Yes…?

    View Slide

  37. @presidentbeef
    Sanitizing SQL?
    class User < ActiveRecord::Base
    def related_users(name)
    q = "last_name = #{sanitize_sql name}"
    User.where(q)
    end
    end NoMethodError: undefined
    method `sanitize_sql' for
    #

    View Slide

  38. @presidentbeef
    Sanitizing SQL??
    self.class.sanitize_sql name
    NoMethodError: protected method
    `sanitize_sql' called for
    #

    View Slide

  39. View Slide

  40. @presidentbeef
    self.class.__send__(:sanitize_sql, name)
    Sanitizing SQL???

    View Slide

  41. @presidentbeef
    name = "') or 1=1 --"
    self.class.__send__(:sanitize_sql, name)
    Sanitizing SQL????
    "') or 1=1 --"

    View Slide

  42. @presidentbeef
    name = "') or 1=1 --"
    self.class.__send__(:sanitize_sql, ["?", name])
    Sanitizing SQL
    "''') or 1=1 --'"

    View Slide

  43. @presidentbeef
    name = "') or 1=1 --"
    self.class.__send__(:sanitize_sql, last_name: name)
    Sanitizing SQL
    "\"users\".\"last_name\" = ''') or 1=1 --'"

    View Slide

  44. @presidentbeef
    No Rate Limiting

    View Slide

  45. @presidentbeef
    No Open Redirect Protection
    Open Redirect
    redirect_to params[:n]
    Safe-ish Redirect
    redirect_to URI.parse(params[:n]).path

    View Slide

  46. @presidentbeef
    Open Redirect
    redirect_to params[:n]
    Safe-ish Redirect
    begin
    redirect_to URI.parse(params[:n]).path
    rescue URI::InvalidURIError
    #...
    end
    No Open Redirect Protection

    View Slide

  47. @presidentbeef
    No Protocol Filtering for Links
    link_to "My home page", user.home_url

    My home page

    View Slide

  48. @presidentbeef
    Even More Missing Security Features
    Code Climate Blog: Rails Insecure Defaults
    blog.codeclimate.com/blog/2013/03/27/rails-insecure-defaults/

    View Slide

  49. @presidentbeef
    @MakotoTheCat

    View Slide

  50. @presidentbeef
    What To Do About It

    View Slide

  51. @presidentbeef
    Learn About Security

    View Slide

  52. @presidentbeef
    Fix All The Rails Things?

    View Slide

  53. @presidentbeef
    Use Security Libraries
    Rate Limiting and Blocking
    rack-attack
    Moar Headers
    secure_headers
    Access Control
    pundit
    cancan/cancancan
    Authentication
    omniauth
    User Management
    devise

    View Slide

  54. @presidentbeef
    Use Static Analysis Tools
    Brakeman
    Check for potential vulnerabilities
    bundler-audit
    Check for vulnerable dependencies

    View Slide

  55. @presidentbeef
    Cost of Fixing Defects

    View Slide

  56. @presidentbeef
    Use static analysis
    Scan all the code all the time
    Don’t fix vulnerabilities, prevent them
    The Plan

    View Slide

  57. @presidentbeef
    Some Options
    File system monitoring (using Guard?)
    Integration into commit tools
    Continuous integration (with Jenkins?)
    Integration into release process

    View Slide

  58. @presidentbeef
    More Info
    “Using Brakeman and Security
    Automation in Practice in the SDLC and
    Stuff”
    youtu.be/kda8RZ5NIlM
    “Putting Your Robots to Work”
    vimeo.com/54250716

    View Slide

  59. @presidentbeef
    Be Safe!
    @presidentbeef / presidentbeef.com
    @brakeman / brakemanscanner.org
    @brakemanpro / brakemanpro.com

    View Slide