tamphh / secure_rails

Rails security best practices

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Secure Rails

Everyone writing code must be responsible for security. đź”’

Start with the Rails Security Guide to see how Rails protects you.

Best Practices

  • Keep secret tokens out of your code - ENV variables are a good practice

  • Even with ActiveRecord, SQL injection is still possible if misused

    User.group(params[:column])

    is vulnerable to injection. Learn about other methods

  • Use SecureHeaders

  • Protect all data in transit with HTTPS - you can get free SSL certificates from Let’s Encrypt

    Add the following to config/environments/production.rb

    config.force_ssl = true
  • Add your domain to the HSTS Preload List

    config.ssl_options = {hsts: {subdomains: true, preload: true, expires: 1.year}}
  • Protect sensitive data at rest with a library like attr_encrypted and possibly KMS Encrypted

  • Prevent host header injection - add the following to config/environments/production.rb

    config.action_controller.default_url_options = {host: "www.yoursite.com"}
    config.action_controller.asset_host = "www.yoursite.com"
  • Set autocomplete="off" for sensitive form fields, like credit card number

  • Make sure sensitive request parameters aren’t logged

    Rails.application.config.filter_parameters += [:credit_card_number]
  • Use a trusted library like Devise for authentication (see Hardening Devise if applicable)

  • Notify users of password changes

  • Notify users of email address changes - send an email to both the old and new address

  • Rate limit login attempts with Rack Attack

  • Log all successful and failed login attempts and password reset attempts (check out Authtrail if you use Devise)

  • Rails has a number of gems for authorization - we like Pundit

  • Ask search engines not to index pages with secret tokens in the URL

    <meta name="robots" content="noindex, nofollow">
  • Ask the browser not to cache pages with sensitive information

    response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Sat, 01 Jan 2000 00:00:00 GMT"
  • Use json_escape when passing variables to JavaScript, or better yet, a library like Gon

    <script>
      var currentUser = <%= raw json_escape(current_user.to_json) %>;
    </script>
  • Be careful with html_safe

  • Don’t use assets from a public CDN, as this creates unnecessary availability and security risk

  • If you still use attr_accessible, upgrade to strong_parameters

Open Source Tools

  • Brakeman is a great static analysis tool - it scans your code for vulnerabilities

  • bundler-audit checks for vulnerable versions of gems

    gem install bundler-audit
    bundle audit check --update

    To fix Insecure Source URI issues with the github option, add to the top of your Gemfile:

    git_source(:github) do |repo_name|
      repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
      "https://github.com/#{repo_name}.git"
    end

    And run bundle install.

  • npm audit checks for vulnerable versions of JavaScript packages (if you use package.json)

  • git-secrets prevents you from committing sensitive info

    brew install git-secrets
    git secrets --register-aws --global
    git secrets --install
    git secrets --scan

Mailing Lists

Subscribe to ruby-security-ann to get security announcements for Ruby, Rails, Rubygems, Bundler, and other Ruby ecosystem projects.

Services

  • Observatory scans your site for best practices
  • Hakiri monitors for dependency and code vulnerabilities
  • CodeClimate provides a hosted version of static analysis
  • HackerOne allows you to enlist hackers to surface vulnerabilities

Additional Reading

Contributing

Have other good practices? Know of more great tools? Help make this guide better for everyone.

Also check out Production Rails.

About

Rails security best practices