Content security policy

Content Security Policy can significantly reduce the risk and impact of cross-site scripting attacks in modern browsers.

Joe Medley
Joe Medley
Mike West

Browser Support

  • Chrome: 25.
  • Edge: 14.
  • Firefox: 23.
  • Safari: 7.

Source

The web's security model is based on a same-origin policy. For example, code from https://mybank.com must have access to only https://mybank.com's data, and https://evil.example.com must never be allowed access. Each origin is, in theory, kept isolated from the rest of the web, giving developers a safe sandbox to build in. In practice, however, attackers have found several ways to subvert the system.

Cross-site scripting (XSS) attacks, for example, bypass the same-origin policy by tricking a site into delivering malicious code along with the intended content. This is a huge problem, as browsers trust all of the code that shows up on a page as being legitimately part of that page's security origin. The XSS Cheat Sheet is an old but representative cross-section of the methods an attacker might use to violate this trust by injecting malicious code. If an attacker successfully injects any code at all, they've compromised the user session and gained access to private information.

This page outlines Content Security Policy (CSP) as a strategy for reducing the risk and impact of XSS attacks in modern browsers.

Components of CSP

To implement an effective CSP, take the following steps:

  • Use allowlists to tell the client what's allowed and what isn't.
  • Learn what directives are available.
  • Learn the keywords they take.
  • Restrict the use of inline code and eval().
  • Report policy violations to your server before enforcing them.

Source allowlists

XSS attacks exploit the browser's inability to distinguish between script that's part of your application and script that's been maliciously injected by a third party. For example, the Google +1 button at the bottom of this page loads and executes code from https://apis.google.com/js/plusone.js in the context of this page's origin. We trust that code, but we can't expect the browser to figure out on its own that code from apis.google.com is safe to run, while code from apis.evil.example.com probably isn't. The browser happily downloads and executes any code a page requests, regardless of source.

CSP's Content-Security-Policy HTTP header lets you create an allowlist of sources of trusted content, and tells the browser to execute or render only resources from those sources. Even if an attacker can find a hole to inject a script through, the script won't match the allowlist, and therefore won't be executed.

We trust apis.google.com to deliver valid code, and we trust ourselves to do the same. Here's an example policy that allows scripts to execute only when they come from one of those two sources:

Content-Security-Policy: script-src 'self' https://apis.google.com

script-src is a directive that controls a set of script-related privileges for a page. This header 'self' as one valid source of script, and https://apis.google.com as another. The browser can now download and execute JavaScript from apis.google.com over HTTPS, as well as from the current page's origin, but not from any other origin. If an attacker injects code into your site, the browser throws an error and doesn't run the injected script.