Warning: This site documents the original and out-of-date Mozilla proposal for Content Security Policy.

The current and official Content Security Policy specification is undergoing standardization at the W3C Web Application Security Working Group and the latest revision of the specification can be found here:

CSP Specification

Version: 0.1 | 0.2 | 1.0 | 2.0 (cur)

Content Security Policy provides granular controls enabling website administrators to restrict the locations from which different types of web content can load. This document first describes the restrictions which are enabled globally when Content Security Policy is used. Next, details are provided regarding the types of policies administrators can declare and a description of how valid content sources are defined. Following that are some example policy sets to ilustrate various Content Security Policy use cases.

Browser vendors and websites who wish to implement Content Security Policy should refer to the specification document for detailed information regarding CSP syntax and behavior.

Also, it seems appropriate to acknowledge RSnake and Gerv who originated this idea. Jeremiah Grossman has also been extremely helpful in advancing it.

Content Restrictions

The main goal of Content Security Policy is to prevent malicious code from being injected into a website and executed within the context of that site. Hence, a recurring theme in CSP is to prevent the creation of JavaScript code from potentially tainted strings.

The following restrictions will apply whenever any CSP directives are declared for a document:

  1. No inline JavaScript will execute
    • Restricted:
      • The contents of internal <script> nodes
      • javascript: URIs, e.g. <a href="javascript:bad_stuff()">
      • Event-handling attributes, e.g. <a onclick="bad_stuff()">
    • Allowed:
      • Script in files loaded from white-listed sources
    • Justification:
      • XSS attacks are possible because the browser has no way to differentiate between content the server intended to send and content injected by an attacker. Content Security Policy forces the separation of code from content and requires authors to be explicit about the code they intend to execute
      • Common vectors for injecting script into web pages have been restricted in CSP. With CSP enabled, the bar for a successful XSS attack is raised substantially, requiring an attacker to:
        1. inject a <script> tag into the target document
        2. point this tag at a script file on a white-listed host
        3. control the contents of the white-listed script file
      • Note: websites are still able to peform event-handling in the following ways:
        1. setting the on<event> properties of an element, e.g. element.onclick = myFunc;
        2. using addEventListener, e.g. element.addEventListener("click", myFunc, false);
        Both methods need to be used from within valid white-listed script files.
    • Vulnerability types mitigated:
      1. Reflected XSS Example
        Example: Search engine using improper input validation echoes unfiltered query string into results page
        <h1>Bad Search</h1>
        <p>Your search for "<script>bad_stuff();</script>" returned 0 results.</p>
      2. Stored XSS Example
        Example: Social news site allowing metacharacters to be stored in usernames and displaying them unfiltered
        <h1>Bad News Portal</h1>
        <p>Today's stories:</p>
        <ol>
            <li><b>Something big happened!</b> - Posted by <script>bad_stuff();</script></li>
        </ol>
      3. javascript: link injection Example
      4. HTML attribute injection Example
        Example: Website with alternate stylesheets gets CSS properties from unfiltered query string, e.g.
        http://example.site/index.html?view=print+onload="bad_stuff()
        <html>
        <body class="print" onload="bad_stuff()">
  2. Code will not be created from strings
    • Restricted:
      • eval()
      • setTimeout called with a String argument, e.g. setTimeout("evil string...", 1000)
      • setInterval called with a String argument, e.g. setInterval("evil string...", 1000)
      • new Function constructor, e.g. var f = new Function("evil string...")
      • javascript: URIs, e.g. <a href="javascript:bad_stuff()">
    • Allowed:
    • Justification:
      • eval and related functions make trivial the task of generating code from strings, which commonly come from untrusted sources, are loaded via insecure protocols, and can become tainted with attacker controlled data.
      • Once tainted data has been introduced to a JavaScript program, it is extremely difficult to control its propogation and calls to eval and similar are likely to incorporate tainted strings containing malicious code.
      • Note: the common AJAX pattern in which a site makes a XMLHttpRequest to fetch JSON data is still enabled under CSP using a JSON parser or inside a browser that has native JSON support.
    • Vulnerability types mitigated:
      1. AJAX request tampering Example
        Example: Website makes AJAX request to a JSON feed using attacker-controlled data and calls eval on the response, e.g.
        http://example.site/index.html?"});bad_stuff()//
        Requesting page:
        var ajaxUrl = "http://example.site/get_data.cgi?ref="+location.href;
        ajaxResponse = makeAjaxRequest( ajaxUrl );
        myData = eval( "(" + ajaxResponse + ")" );
        AJAX Response:
        {
          referer: "http://example.site/index.html?"});bad_stuff()//",
          data: 42
        }
      2. Improper use of dynamic properties Example
        Example: Website uses eval to make references to dynamic JS object properties using attacker-controlled values
        Unsanitized input value used to determine property name
        var myName = document.getElementsByTagName("input")[0].value;
        eval( "myObj.prop_" + myName + " = 42" );
        Attacker sends malicious code to the eval call through the input control
        The resulting code is executed
        eval( "myObj.prop_; bad_stuff() // = 42" );
  3. No data: URIs unless opted-in to via explicit policy
    • Restricted:
      • data: URIs as a source for inline content
    • Allowed:
      • data: URIs as a source for inline content when explicitly opted-in to, e.g.
        X-Content-Security-Policy: allow 'self'; img-src data:
    • Justification:
      • The data: URI scheme is designed to allow the loading of arbitrary textual or binary data into a document, including HTML, JavaScript, images, media files, etc.
      • data: URIs are a potential vector for HTML and JavaScript injection which can be used by an attacker for XSS or website defacement.
      • The increase in attack surface created by data: URIs, and additional input sanitization required by sites wishing to use them justifies the opt-in requirement for this feature in CSP.
    • Vulnerability types mitigated:
      1. data: URL script injection Example
        Example: Wiki allowing editors to specify arbitrary hyperlinks in articles, including data: URLs
        <h1>Article</h1>
        <p>The original source for this article can be found <a href="data:text/html,<script>bad_stuff()</script>">here</a>.
  4. XBL bindings must come from chrome: or resource: URIs
    • Restricted:
    • Allowed:
      • XBL bindings loaded via the chrome: or resource: protocols
    • Justification:
      • XBL is used to define the properties and behaviors of elements in HTML, XUL, and SVG documents from external files and as such is a vector for script injection.
      • Requiring that XBL bindings be loaded from either the chrome: or resource: protocol ensures that the bindings are part of a package already installed on a user's system. This prevents script from arbitrary locations on the Web from being included in a document via CSS.
      • Note: this restriction still enables user stylesheets to use XBL, custom browser add-on bindings to be referenced by web content, and chrome UI features to be implemented in XBL, e.g. <video> controls.
    • Vulnerability types mitigated:
      1. Stylesheet script injection Example
        Example: Social networking site allowing users to customize their profile by specifying an external stylesheet
        User links to external stylesheet <link rel="stylesheet" type="text/css" href="http://evil.site/style.css" />
        <div id="profile">
        Stylesheet contains XBL binding
        #profile {
          -moz-binding: url("bindings.xml#evil");
        }
        XBL binding contains malicious code
        <?xml version="1.0"?>
        <bindings xmlns="http://www.mozilla.org/xbl"
                  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
          <binding id="evil">
            <implementation>
              <constructor>
                bad_stuff();
              </constructor>
            </implementation>
          </binding>
        </bindings>
      2. Style attribute injection Example
        Example: Website fails to escape quotes or other metacharacters in an input control, allowing an attacker to inject a style attribute, e.g.
        http://example.site/form.cgi?name=foo" style="-moz-binding: url('http://evil.site/bindings.xml#evil')
        CSS with -moz-binding property is injected into the document <input type="text" name="name" value="foo" style="-moz-binding: url('http://evil.site/bindings.xml#evil')" />
        XBL binding contains malicious code
        <?xml version="1.0"?>
        <bindings xmlns="http://www.mozilla.org/xbl"
                  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
          <binding id="evil">
            <implementation>
              <constructor>
                bad_stuff();
              </constructor>
            </implementation>
          </binding>
        </bindings>
  5. Optional directives, policy-uri and report-uri, must refer to the same host as the protected document. Additionally, policy-uri documents must be served with the MIME type text/x-content-security-policy to be valid
    • Restricted:
      • policy-uri directives which refer to a URI on a different host as the protected document, e.g.
        policy-uri http://other.tld/csp-policy.cgi
      • poliy-uri responses served with Content-Type other than text/x-content-security-policy, e.g.
        Content-Type: text/html, or
        Content-type: image/jpeg
      • report-uri directives which refer to a URI on a different host as the protected document, e.g.
        report-uri http://other.tld/csp-report.cgi
    • Allowed:
      • policy-uri directives which refer to a URI on the same host as the protected document, e.g.
        policy-uri http://same.site/csp-policy.cgi.
        The policy document must also be served with the response header,
        Content-Type: text/x-content-security-policy
      • report-uri directives which refer to a URI on the same host as the protected document, e.g.
        policy-uri http://same.site/csp-report.cgi
    • Justification:
      • A site which has not opted-in to using CSP should not be forced into using CSP by an attacker who can inject a policy-uri directive via a CSP header. Restricting the policy-uri to the same host as the protected document, and requiring it to be served as text/x-content-security-policy ensures the site has positively opted-in to CSP.
      • The report sent to the report-uri contains potentially sensitive information, including cookie values and query string parameters. This information is intended only for the protected site for debugging purposes or similar. An attacker should not be allowed to steal the report information by injecting a report-uri, along with an arbitrary policy to be violated.

Policy Directives

There are a total of ten policy areas that web site administrators can define via Content Security Policy. Meaningful policy sets can be created, however, by defining just a few of these policy areas. With the exception of the allow section, each policy area is optional and can be defined independently from the other areas. If Content Security Policy is specified by a web site, the allow section is required. It is treated as a catch-all for types of content whose policy may or may not be defined. If an allow section is not specified, then the policy is invalid and an error is raised. Additional policies can be defined for specific types of content as described below.

Content Security Policy is defined on a per-resource basis and can vary according to the sensitivity of a particular resource. Some example policy sets are provided below.

  1. allow
    • allow is the catch-all section that defines the security policy for all types of content which are not called out in any of the more specific directives
    • It is required to be defined for any resource which utilizes Content Security Policy
  2. options
    • Options for modifying the core restrictions of CSP
    • inline-script enables inline script and javascript: URIs
    • eval-script enables the parsing of strings into code via eval() and similar functions
  3. img-src
    • Indicates which sources are valid for images and favicons
    • Images from non-white-listed sources will not be requested or loaded
  4. media-src
    • Indicates which sources are valid for <audio> and <video>
    • <audio> and <video> from non-white-listed sources will not be requested or loaded
  5. script-src
    • Indicates valid sources of JavaScript
    • Script from non-white-listed sources will not be requested or executed
  6. object-src
    • Indicates valid sources for <object>, <embed>, and <applet> elements
    • Objects from non-white-listed sources will not be requested or loaded
  7. frame-src
    • Indicates which sources are valid for <frame> and <iframe> elements
    • "Which documents may be embedded within my site?"
    • Frame content from non-white-listed sources will not be requested or loaded
  8. font-src
    • Indicates which sources are valid for @font-face loads
    • Downloadable fonts from non-white-listed sources will not be requested or loaded
  9. xhr-src
    • Indicates which sources are valid for XMLHttpRequest connections
    • XMLHttpRequests may not be opened to non-white-listed sources
  10. frame-ancestors
    • Indicates which sources are valid for <frame> and <iframe> elements
    • "Which sites may embed content from my site?"
    • All sites within the frame chain must be in the frame-ancestors list in order for the load to be permitted.
      • If SiteA embeds SiteB which embeds SiteC, then both SiteA and SiteB must be approved by SiteC before SiteC will be loaded in SiteB's <frame> or <iframe>.
    • Note that this directive addresses the clickjacking threat, but not CSRF
      • Using frame-ancestors, it is possible to prevent a resource from being framed within a malicious webpage. The browser will stop loading the protected document as soon as its frame-ancestors policy is received and a policy violation is determined.
      • However, this directive does not prevent the request for the document from being sent to the framed document's server, as policy directives are received by the browser in the server's response. To mitigate Cross-Site Request Forgery, the Origin header provides a more robust mechanism.
  11. style-src
    • Indicates valid sources for stylesheets
      • This includes externally linked stylesheets, as well as inline <style> elements and style attributes of HTML elements within the protected document
    • Stylesheets from non-white-listed sources will not be requested or loaded
  12. report-uri
    • Instructs the browser where to send a report when Content Security Policy is violated
    • The report will be a JSON document sent via POST to the specified URI containing the following:
      • request - HTTP request line which led to the policy violation (method, resource path, HTTP version)
      • request-headers - HTTP headers sent which led to the policy violation
      • blocked-uri - URI of the resource that was blocked from loading
      • violated-directive - The policy section that was violated (e.g., "script-src *.mozilla.org")
      • original-policy - The original policy as served in the X-Content-Security-Policy header
    • Sample report:
      {
        "csp-report":
          {
            "request": "GET http://index.html HTTP/1.1",
            "request-headers": "Host: example.com                                                        
                                User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.3a5pre)
                                Gecko/20100601 Minefield/3.7a5pre
                                Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
                                Accept-Language: en-us,en;q=0.5                                          
                                Accept-Encoding: gzip,deflate                                            
                                Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7                           
                                Keep-Alive: 115                                                          
                                Connection: keep-alive",
            "blocked-uri": "http://evil.com/some_image.png",
            "violated-directive": "img-src 'self'",
            "original-policy": "allow 'none'; img-src *, allow 'self'; img-src 'self'"
          }
      }
      
  13. policy-uri
    • Indicates the location of a file containing the security policies for the resource
    • The policy-uri must point to the same host that the protected document resides on, and the file must be served with
      Content-Type: text/x-content-security-policy
    • If a valid policy-uri is specified, any policy defined in the HTTP header will be ignored
    • A Content Security Policy set including policy-uri is only valid if policy-uri is the only directive present. Otherwise, an exception is raised and CSP is disabled.

Content Sources

Content Sources are the fundamental basis for how Content Security Policies are defined. A policy set combines Policy Directives with a list of Content Sources to define the locations from which different types of content may be loaded. A valid Content Source takes one of two forms:

  1. Host Expression
    • Describes an Internet host
    • Consists of:
      • (Optional) Scheme, e.g. http://, ftp://
      • Hostname, including an optional leading wildcard, e.g. *.mozilla.org
        • The wildcard character must be used in the most specific (left most) part of the hostname and may match any number of subdomain labels.
      • (Optional) Port number, which is separated from the hostname with a colon, e.g. mozilla.com:443
  2. Keyword
    • Represents a special class of Content Sources
      1. 'self' - refers to the host the protected document is served from, including the same scheme and port (note: single quotes required)
      2. 'none' - refers to the empty set (no hosts are valid, note: single quotes required)
  3. Data
    • data: - permits data: URIs to be valid content sources, e.g. img-src data:

Further detailed information on Content Sources can be found within the Formal Policy Syntax section of the specification document.

Example Use Cases

  1. Site wants all content to come from its own domain:
    • X-Content-Security-Policy: allow 'self'
  2. Auction site wants to allow images from anywhere, plugin content from a list of trusted media providers, and scripts only from its server hosting sanitized JavaScript:
    • X-Content-Security-Policy: allow 'self'; img-src *; object-src media1.com media2.com; script-src userscripts.example.com
  3. Online payments site wants to ensure that all of the content in its pages is loaded over SSL to prevent attackers from eavesdropping on requests for insecure content
    • X-Content-Security-Policy: allow https://payments.example.com

The Origin Header

The initial Content Security Policy proposal included a policy directive that could be used to mitigate CSRF vulnerabilities by governing which sites could initiate HTTP requests for a CSP-protected resource. This model was similar to the current Cross-Origin Resource Sharing mechanism being developed by W3C.

That particular directive has been removed from Content Security Policy. An alternative CSRF mitigation mechanism is provided by the Origin header.

Conclusions

Content Security Policy provides a way to greatly reduce or altogether eliminate a website's attack surface for Cross-Site Scripting. With proper Content Security Policy in place, a successful XSS attack will be orders of magnitude more difficult, requiring the attacker control the contents of white-listed script source files. No longer will XSS attacks which rely on echoing script into page contents be effective. Further, if a site knows it never wants to have JavaScript executing in its pages, it can simply globally disable JavaScript and not have to worry about script injection attacks against its users with supporting browsers.

While part of Content Security Policy, the Origin header provides a simple way for a website to mitigate Cross-Site Request Forgery against its sensitive resources. The Origin header provides the information a server needs to validate its requests while avoiding the privacy concerns which were chief among the criticisms of Referer.

As seen in every aspect of Computer Security, the protection of a system is best achieved through a variety of overlapping controls. Content Security Policy aims to be one part of a larger defense-in-depth application security strategy, or as our colleague Gerv likes to say, "belt-and-braces". Web administrators, while maintaining their normal security auditing and remediation process, will embrace the opportunity to mitigate broad classes of web app vulnerabilities, for those users with compliant browsers, by defining a few simple rules.

Overview | Details | Spec | Download | Demo | WordPress | Origin Header | Discussion