What is a Content Security Policy?

A Content Security Policy (CSP) is an important aspect of securing websites and web applications. CSP is a resource security specification (W3C recommendation) for web browsers. It is configured by sending directives in an HTTP header. Enforcing the directives is the responsibility of web browsers. After years of battling XSS and various injection attacks in websites, the CSP specification was created to provide websites a way of controlling what resources can be loaded within the site’s pages. By restricting the loading and execution of resources to a trusted whitelist, a website’s security can be substantially improved.

How does CSP work?

CSP is typically configured in the HTTP headers sent by the web server, although it can also be specified in a meta tag in the document head. At its simplest, a site-wide CSP policy can be delivered with every page, but individual pages can have different policies for more fine-grained control. When the web browser receives the policy it applies it to all resources loaded in the page – JavaScript, CSS, images, audio, video, iframes, etc. If an attempt is made to load a resource that is not whitelisted by the policy then the browser will block loading the resource.

A common attack approach is to find existing application code that allows execution of arbitrary script provided by the user, possibly in an input field or in the URL query string. Once such a vulnerability has been identified a compact script is supplied that then loads a more complicated script by making a remote request. With a sufficiently strict CSP configuration, the remote request would be blocked by the browser since the remote URL is not a trusted source for script execution. It is still important to avoid deploying application code that executes user-supplied script!

CSP resource configuration options

The basic CSP directive is default-src. This specifies the default source whitelist for all resources. Any resource type that is unspecified will fully inherit from default-src. However, if a resource type has any values specified then that resource type does not inherit at all from default-src. Some of the more specific resource types:

  • script-src: for JavaScript
  • image-src: for <img> elements
  • style-src: for CSS
  • font-src: for fonts
  • media-src: for <audio> and <video> elements
  • frame-src: for <iframe> elements

Specifying source values

There are some keywords for source values:

  • none: block all sources (generally only useful if you want to completely block a specific resource type)
  • self: allow same-origin requests
  • unsafe-inline: allow inline scripts or styles (avoid if possible)
  • unsafe-eval: allow the use of the JavaScript eval function (avoid if possible)

Values can also be specified by host or scheme. Hostnames can be schemeless and include wildcards (*).  For example:

default-src: 'self'; script-src: 'self' *.cdn.com; font-src: 'self' https://fonts.gstatic.com

The default-src value restricts resources to the same origin. The script-src value additionally allows <script> elements to specify sources from any subdomain of cdn.com (http or https). The font-src value allows the same origin and fonts.gstatic.com (https only, http will be blocked).

How to configure CSP

For a small website a strict policy of default-src: 'self' can be added as the first meta tag in the document head and each page tested. The web browser will log CSP violations in the console and rules can be added as needed to resolve violations. Once a working policy has been built it can be deployed, ideally using the Content-Security-Policy header instead of the meta tag.

Larger and more complicated websites may require a more complicated security policy, possibly even with page-specific policies. CSP provides a report-only configuration by using the Content-Security-Policy-Report-Only header. With this header, violations will not be enforced, but they will be logged to the browser console, and if a reporting URI has been provided then a request with a JSON body will be sent to the reporting URI. If you don’t want to create your own server to receive reports there are reporting services like Report URI and URIports. Report URI even includes a wizard reporting URI that will help you build up your policy by starting with a strict policy and monitoring logged violations to build up your whitelist.

Not all violation reports are useful

When CSP is enabled for a website violations are reported the same regardless of whether the violations were caused by your site content or external manipulation like attempted attacks or, more commonly, browser extensions. Fortunately, logging services include filtering options. Dropbox shared their experience analyzing CSP logs and provided some good advice on filtering.

Building secure web applications

In the past, numerous front-end frameworks and toolkits took advantage of JavaScript’s extensive flexibility to provide novel functionality. Unfortunately, some of those features proved to be the most easily exploitable by attackers as well. As the JavaScript language has matured and front-end frameworks have improved it is much easier to build applications with strict security policies. SitePen has extensive experience building secure enterprise web applications with a variety of frameworks. Dojo Framework was designed from the ground up with modern browser technology and security best practices. The older Dojo Toolkit recently received a significant update enabling its use with a strict CSP configuration. 

If you’re maintaining a legacy application or need advice as you approach a brand new project, schedule a technical strategy session with our team of experts to guide you in the right direction, the first time, on your path to building secure web applications. 

Further reading