Implementing Content Security Policy in Apache

25th October, 2016 by

Along with SQL injection attacks, cross-site scripting (XSS) attacks are some of the more common to be used when attacking a website. Cross-site scripting attacks are a kind of hack where the attacker manages to inject a piece of code, normally in the form of Javascript, into a website where it is executed by another user.

Originally, this just covered the use of fooling a website into loading a javascript file from another website, but these days this can also include other content files or malicious fonts and images that may be executed by either the end user’s computer or on the server itself. The purpose of this form of attack is often to infect other users with malware, gain access to their account information or to gain deeper access to the system when run by an administrator account.

Content Security Policy

To help prevent cross-site scripting attacks, the idea of the Content Security Policy was devised. While the first version of CSP was only published in 2012, it has a history running back to 2004 with attempts to resolve this issue. CSP version 2 is the current version of the standard and is supported by both Chrome and Firefox, while Safari and edge only support version 1. It works when the web server sends a special header to the web browser identifying that the server implements a content security policy.  Ait then dictates from where the browser should load things like stylesheets, script files, images, and fonts. The web browser should then reference this information when loading the HTML code for the site and then fail to load any files that aren’t allowed by the policy.

While this won’t render all XSS style attacks impossible, it will (when implemented well) prevent all XSS attacks involving tricking the browser to load malicious files from external websites. Implementing CSP is as simple as placing a few files of configuration in your web server configuration. When running Apache you can place this code in the virtualhost configuration for your website or in a .htaccess file for the directory your website resides within. For anyone running a website on a dedicated server or VPS then the virtualhost configuration method is recommended whilst the .htaccess file method should only be needed if your website is on shared web hosting.

How To Implement CSP

At this point, I’m going to be assuming you know how to edit your virtualhost configuration or create a .htaccess file for this purpose. If not then we’ve previously provided guides explaining both that you could use for reference. So prepare your file and add the following directive:

Header set Content-Secure-Policy "default-src 'self';"

This is about the simplest set-up that you can have and informs the browser that the only content it should be allowing for your site is content that is loaded from your own domain. The Content-Secure-Policy header can be broken down to a number of directives starting with the directive type and then providing the sources for use with the directive. The default-src directive applies to all forms of content such as images, CSS, Javascript, AJAX requests, Frame contents, fonts, and media content. There are separate -src directives for each type of file such as script-src and img-src. A full list of the directive types and their potential source declarations are available at the Content Secure Policy site here:

Multiple Directives

Each directive can have numerous sources applied to them and you can use multiple directives in the policy separated by semicolons. This allows for both strict and comprehensive settings for the policy. So let’s imagine a more complex example of a blog that may link to images from across the internet, uses Javascript from it’s own domain, jquery from Google’s CDN and Google analytics and only uses it’s own CSS. This could be handled with a header similar to the below:

Header set Content-Secure-Policy "default-src 'none'; script-src 'self'; img-src *; style-src 'self';"

By including default-src ‘none’ in the directives the browser would block all external files that aren’t explicitly defined later in the Content-Secure-Policy header. The img-src directive uses an asterisk (*) as its source definition to illustrate that it should allow images to be allowed from any domain. Hopefully, the rest of it should be fairly straight forward.
Once you’ve created your Content-Secure-Policy header you can save your file, and if you’ve included the directive within your virtualhost declaration rather than in a .htaccess file, don’t forget to reload the Apache configuration for your changes to take effect.