Ruby on Rails Security Guide

Please refer the following for Ruby on Rails best practices on the security. CSRF and XSS are the most important ones:-

 

1) CSRF – https://selvaonrails.wordpress.com/2012/04/03/ruby-on-rails-security-csrf-3/

2) XSS – https://selvaonrails.wordpress.com/2012/04/03/ruby-on-rails-security-xss-2/

3) Protection flags on cookies – https://selvaonrails.wordpress.com/2012/04/03/ruby-on-rails-security-protection-flags-on-session-cookies/

4) Filter parameter logging – https://selvaonrails.wordpress.com/2012/04/03/ruby-on-rails-security-filtering-parameter-logging/

Ruby on Rails Security – Protection Flags on Session Cookies

Analysis:

When an unsuspecting user visits the site, the JavaScript executes, stealing the ‘sessionId’ cookie and sending it to the malicious user. Using the victim’s session ID, the malicious user can hijack the victim’s session and perform actions on their behalf.

Solution and Fix:

Add the ‘HttpOnly’ flag to the Set-Cookie directive for the session ID. When we  tag a cookie with the HttpOnly flag, it tells the browser that this particular cookie should only be accessed by the server. Any attempt to access the cookie from client script is strictly forbidden. Of course, this presumes you have:

  1. A modern web browser
  2. A browser that actually implements HttpOnly correctly

Example and Testing:

The following details are extracted from the ‘Live HTTP Headers’

Before setting the ‘HttpOnly’ flag:-

Set-Cookie: sessionId=EUID%3DLTU3Zjg3YTA3OjEzNj

After setting the ‘HttpOnly’ flag:-

Set-Cookie: sessionId=EUID%3DLTU3Zjg3YTA3OjEzNj; HttpOnly

Links for References:-

1)      http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html

Ruby on Rails Security – XSS

Analysis:

An entry point to this kind of attack is a vulnerable URL and its parameters where an attacker can start attack. An attacker injects some code, the web application saves it and displays it on a page. XSS can steal the cookie, hijack the session, redirect the victim to a fake website, display advertisements, change elements on the web site or install malicious software through security holes in the web browser. The most common XSS language is of course the most popular client-side scripting Javascript, often in combination with HTML. Escaping the user input is essential.

Solution and Fix:

Multiple fixes is needed for this, 1) Escaping on the parameters and 2) Escaping on the output values.

1)      Escaping on the parameters (Refer:- https://selvaonrails.wordpress.com/2012/04/03/ruby-on-rails-sanitize-4/)

A check has to be done for escaping the malicious scripts in the parameters with the help of ‘Sanitize’ gem. For example, an attacker can pass some script like below in the scope parameter.

https://www.domain.com/user/login?scope=<script>document.write(document.cookie);</script>.

If the above is executed successfully means, the attacker will stole the cookie from the web page. To avoid this, parameters needs to be checked and the scripts needs to be escaped. This can be achieved with the help of ‘Sanitize’ gem with some code like below.

Sanitize.clean(“//value goes here//”)

The above will check for the value of the parameters and escape the scripts, if any.

2)      Escaping on the output values

As a second step, it is good practice to escape all output of the application, especially when re-displaying user input, which hasn’t been input-filtered using escapeHTML() or it’s alias h() method to replace the HTML input characters &,”,<,> by their uninterpreted representations in HTML.

Ex:- <%=h @value_to_be_displayed %>

Links for References:

1)   http://guides.rubyonrails.org/security.html#cross-site-scripting-xss

Ruby on Rails – Sanitize()

Sanitize is one of the most important gem, which needs to be installed to perform the sanitizing of parameters. In Ruby on Rails, the hackers can make use of passing the scripts like <script>alert(“hacking”);</script> in the parameter of any URL to hack the application. To get rid of this situation, we must do the following :-

gem install sanitize

gem install nokogiri (dependent gem of sanitize)

libxml2 package (dependent of nokogiri) – http://nokogiri.org/tutorials/installing_nokogiri.html

Now, add the following lines in your application controller to sanitize the parameters and automatically escaping the scripts to make your applications safer:-

  before_filter :input_filter

    def input_filter
        params.each do |key,value|
     # if it’s a hash, we need to check each value inside it…
      if value.is_a?(Hash)
       value.each do |hash_key,hash_value|
           params[key][hash_key] = Sanitize.clean(hash_value)
       end
       params[key].symbolize_keys!
      elsif value.is_a?(String) || value.is_a?(Integer)
       params[key] = Sanitize.clean(value)
      end
    end
    params.symbolize_keys!
  end

Ruby on Rails Security – CSRF

Analysis:-

This attack method works by including malicious code or a link in a page that accesses a web application that user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands.

In rails, session can be stored either as a cookie or as a server-side session hash. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is, that it will also send the cookie, if the request comes from a site with a different domain

Solution and Fix:-

The solution to this is including a security token in the requests which will be checked on the server side. This will be done by adding the line ‘protect_from_forgery’ in the application controller. This will automatically include a security token, calculated from the current session and the server-side secret, in all the forms and Ajax requests generated by Rails. The secret is not needed if we use cookie as session storage. If the security token doesn’t match what was expected, the session will be reset.

Once the forgery protection is enabled, the form now will have a hidden ID field. The protect_from_forgery method adds a before_filter called verify_authenticity_token to all actions. It will compare this ID field against an ID stored in the session variable. If they differ, the action will not be executed.

 

Example hidden field in the form with the authenticity token:

<input name=”authenticity_token” type=”hidden” value=”rNZrqiOxWlQw1/3PqKa5+3L1teWbZwLr6ljhLxkXWCc=” />

 

Links for References:-

1)      http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf

2)      http://ruby.about.com/od/security/a/forgeryprotect.htm

Note: XSS vulnerabilities bypass all CSRF protections. XSS gives the attacker access to all elements on a page, so he can read the CSRF security token from a form or directly submit the form.