Generating Content-Security-Policies, the easy way.

c0nrad 10/9/2014

Content-Security-Policy (CSP) is a relatively new HTTP header for eliminating potential XSS vulnerabilities from your website. This article will give a brief intro to CSP, and then shows some newer tools related to CSP, and how to use them to generate a policy for a website.

How It Works

Content Security Policy is a white list that specifies where assets are allowed to be loaded from and executed. This includes scripts that come from the same website. If the website tries to load or execute an asset that isn't on the white list, an asset being javascript, css, websockets, images, etc, the asset will be blocked.

Here's an example policy:

Content-Security-Policy: default-src 'self'; script-src www.google.com; img-src https:; style-src 'unsafe-inline'; report-uri https://caspr.io/endpoint/abc123

This is an example policy you might see on a simple website. Lets break it down by resource:

default-src 'self'; By default, the website will accept all assets that come from the same domain. So for this website, c0nrad.io/js/bootstrap.js would be an acceptable asset to execute, since it's from the same domain.

script-src www.google.com; The website will also accept all javascript assets that belong to www.google. So www.google.com/jquery.js would be a valid asset.

img-src https:; Any image loaded over https (from any domain) is allowed.

style-src 'unsafe-inline'; Normally inline scripts are not allowed (js/css). This allows inline CSS to be executed (for example anything in between <style> tags).

report-uri https://caspr.io/endpoint/abc123 If a violation occurs on the page, send a violation report to this URL (via HTTP post).

Before Caspr, this took a little work

Unless the asset is listed in the policy, it will not be loaded. And for some reason, customers don't like it when only half of your website shows up. So it's important to make sure that the policy accurately reflects what assets the website is using.

But if your website has any size to it, it may be difficult to correctly build that policy without missing something.

By using two new tools (Caspr and Enforcer), we won't have to write a single line of code while we're generating and testing our new policy.

Overview

The steps:

To install CSP we're going to use a pretty basic approach. You can specify a report-uri on your CSP header, so that whenever there's a violation of the policy, your browser sends an HTTP post request to that endpoint. By specifying a very restrictive policy, we can collect a bunch of reports and see exactly what we need to include in our final policy.

Step 1: The Tools

Using these tools, we can test/build/validate a CSP policy without touching a line of code.

Caspr

Deploy Caspr

The first tool is called Caspr. You can check it out at caspr.io or view the source at Github .

Caspr is three things:

  • A endpoint for collecting CSP reports
  • A frontend for viewing and aggregating the reports and building policies
  • An API for downloading and viewing these CSP reports

Enforcer

Install Enforcer

The tool we're going to use to test different policies is a chrome extension called Enforcer.

Enforcer grabs your web requests and inserts a Content-Security-Policy header into each of the pages. This makes testing much faster and easier (and you can test CSP on websites you don't own).

Step 2: Setup a Project on Caspr

Next create a project on caspr. Copy the report-uri for the new project.

Step 3: Generate Reports

Next load the Enforcer chrome extension. Set the policy and report uri to the newly created caspr project, and visit every unique webpage on the website.

What we're trying to do is get a good mapping of all the assets used on the website.

Step 4: Build a policy

Go back to caspr project and look at some reports. The analyze page gives a quick overview of the different types of reports the website has.

Then go to the Builder page, this is where we'll start building the policy. Click all the assets you want to be allowed on the page. Once you're satisfied, copy that new policy and try it out on Enforcer.

Step 4: Remove Inline Scripts

If you have any inline scripts (javascript/css), you're going to have to move them into their own file. (Or generate hashes/nonces)

This step is important because we will be denying all inline scripts from executing (and hence stopping XSS attacks).

Step 5: Install the Policy

This really depends on what backend you're using. I'm thinking of putting a github page together with the different ways of installing CSP on each framework. Message me if you're interested? (c0nrad@c0nrad.io).

Step 6: Enjoy!

:)

Questions or comments? c0nrad@c0nrad.io Or comment at Hacker News