Product SiteDocumentation Site

3.2.3. Content Security Policy (CSP)

Content Security policy is a comprehensive web security mechanism that allows web applications to declaratively list all sources of trusted content. Originally developed at Mozilla and later adopted by Webkit, Content Security Policy is now a W3C Candidate Recommendation.
One of the persistent problems in web application security is the lack of distinction between content loaded from trusted sources and potentially malicious content injected or referenced in the web page. Content Security Policy takes a comprehensive approach: a new HTTP header is introduced to allow server to send a whitelist of trusted sources to the client. Conformant user agents follow the policy declared in the header and block content from untrusted sources.
Several headers are related to Content Security Policy:
  • X-Content-Security-Policy: experimental header originally introduced by Mozilla
  • X-WebKit-CSP: experimental header used in WebKit based browsers
  • Content-Security-Policy: a standard header proposed by W3C, that shall be used as replacement for the two abovementioned experimenal headers. However, older versions of browsers may support only experimental versions of this header, so web application developers that seek the best coverage may want to use all three headers together.
Value of the header consists of several directives separated by semicolon, each of them followed by list of sources separated by spaces. Following simple policy declares http://example.com as a trusted sources of scripts and disables all other sources:
Content-Security-Policy: default-src 'none'; script-src http://example.com
Since CSP uses whitelist approach, loading scripts from any other domain would not be permitted. Suppose webpage contains following:
<script src="http://malicious.com"></script>
In Firefox this would generate following warning:
[13:16:03.713] CSP WARN:  Directive script-src http://example.com:80 violated by http://malicious.com/
This approach works in case of content with known origin, but this does not solve problem with inlined scripts such as
<script>exploit()</script>
CSP addresses this problem by completely banning execution of any scripts or CSS inlined with <script> or JavaScript URI and similar restrictions apply on eval() like mechanisms. This is necessary from security standpoint, however, it also means that web application developers who want to adopt CSP need to make sure their application does not make use of banned functions. To mitigate this CSP includes reporting capability via report-uri directive, reporting only mode via Content-Security-Policy-Report-Only header and ability to disable protection with 'unsafe-inline' and 'unsafe-eval' sources (see below).

3.2.3.1. Directives and source lists

CSP defines several directives that define restricted content types:
  • script-src restricts which scripts the protected resource can execute.
  • object-src restricts from where the protected resource can load plugins.
  • style-src restricts which styles the user applies to the protected resource.
  • img-src restricts from where the protected resource can load images.
  • media-src restricts from where the protected resource can load video and audio.
  • frame-src restricts from where the protected resource can embed frames.
  • font-src restricts from where the protected resource can load fonts.
  • connect-src restricts which URIs the protected resource can load using script interfaces (like XMLHttpRequest).
and additional directives that control behaviour of CSP:
  • default-src sets a default source list for all directives except sandbox. If not set, directives that are omitted permit all sources by default.
  • sandbox is an optional directive that specifies an HTML sandbox policy that the user agent applies to the protected resource.
  • report-uri specifies a URI to which the user agent sends reports about policy violation.
Source list syntax is fairly flexible: source can be specified from scheme only (https:) and hostname (example.com) to a fully qualified URI (https://example.com:443). Wildcards are also permitted instead of scheme, port or as prefix of domain name to denote arbitrary subdomain (*.example.com). Additionally, there are four keywords allowed in the source list:
  • 'none' matches nothing.
  • 'self' matches current origin.
  • 'unsafe-inline' allows inline JavaScript and CSS and can be used with script-src and style-src directives.
  • 'unsafe-eval' allows eval-list mechanisms that convert text to executable script and can be used with script-src directive.
Content-Security-Policy: default-src 'none'; script-src https://cdn.example.com 'self' 'unsafe-inline'; connect-src https://api.example.com; 

3.2.3.2. Reporting policy violations

Developers who are tuning CSP for their web applications or adopting CSP can use reporting capabilities of CSP. By including report-uri directive server can instruct client's user agent to send POST with JSON-formatted violation report to a specified URI.
Content-Security-Policy: ...; report-uri /csp_report_parser;
Reports sent back to server about CSP violation looks like this:
{
"csp-report": {
  "document-uri": "http://example.org/page.html",
  "referrer": "http://evil.example.com/haxor.html",
  "blocked-uri": "http://evil.example.com/image.png",
  "violated-directive": "default-src 'self'",
  "original-policy": "default-src 'self'; report-uri http://example.org/csp-report.cgi"
}
}
When deploying CSP it may be useful to test the policy in the wild before enforcing it. It is possible to achieve this by sending Content-Security-Policy-Report-Only header instead - this will indicate that the user agent must monitor any policy violations, but not enforce them. Combined with report-uri this gives developers tools to seamlessly deploy new CSP policy.
Content-Security-Policy-Report-Only: ...; report-uri /csp_report_parser;

3.2.3.3. References