March 14, 2018

Content Security Policy with Ruby on Rails

The best solution to protect your Rails app from Cross-site Scripting (XSS) attacks is to deploy a Content Security Policy (CSP). A CSP is delivered via a special HTTP header that instructs the browser to only execute or render resources from a white list. Here is an example of a CSP Header:

Content-Security-Policy: default-src 'self'; script-src 'self' www.google-analytics.com

This CSP header would instruct a web browser to allow the loading of resources only from the page’s origin and JavaScript files additionally from www.google-analytics.com. A more detailed description of what CSP is and how it works can be found over at https://content-security-policy.com

The simplest way to add a Content Security Policy to a Rails App

Adding a content security policy header can be as easy as including an after_action on your base controller that will add the new header. Here is an example:

class ApplicationController < ActionController::Base
  after_action :set_csp_header

  def set_csp_header
      response.set_header("Content-Security-Policy", "default-src 'self'; script-src 'self' https://www.google-analytics.com;")
  end
end

This would allow you to respond with a CSP header, as long as the controller that is called has ApplicationController as its base.

There is a gem for that

Instead of manually adding a way for your app to return a Content Security Policy header, you can also include one of the many gems that does it for you. The most popular one is the Secure Headers gem. It comes with a standard configured content security policy and other pre-configured security headers.

Content-Security-Policy: default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline' Strict-Transport-Security: max-age=631138519 X-Content-Type-Options: nosniff X-Download-Options: noopen X-Frame-Options: sameorigin X-Permitted-Cross-Domain-Policies: none X-Xss-Protection: 1; mode=block

Everything is of course adjustable and the gem is well maintained.

Managing a Content Security Policy can be a lot of manual work

One of the issues with CSP is that you are deploying a whitelist approach that you have to maintain going forward. This means that everytime you add or remove a third party dependency from your rails app you should be updating your content security policy.

You will also want to include a reporting endpoint that you can include in your CSP to catch violation reports. Monitoring policy violations at scale can be difficult. The Content-Security-Policy Spec includes a way to declare a violation reporting endpoint. Building such an endpoint isn’t trivial. The report-uri setting is used to let the browser know where to sent violation reports.

Content-Security-Policy: default-src 'self'; report-uri https://log.templarbit.com/csp-reports/06edfbca

How Templarbit can help deliver a frictionless CSP setup

At Templarbit we are building a developer-oriented security platform, helping small and large companies protect their software from malicious activity. One of our features is the first intelligent XSS defense delivered via CSP Headers. We provide you with the fastest way to deploy and manage a Content Security Policy for your ruby on rails application. Managing updates to your Content Security Policy will become a frictionless experience and happens in real time without pushing any code changes. Powering things behind the scenes are a combination of our proprietary data and machine learning models that allow Templarbit to automatically make a decision on policy changes without relying on human input. We deliver this into your rails app via the Templarbit gem.

If you want to get started with Content-Security-Policy today, you can sign up for a free trial here.