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:
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:
- 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()">
- The contents of internal
- 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:
- inject a
<script>tag into the target document - point this tag at a script file on a white-listed host
- control the contents of the white-listed script file
- inject a
- Note: websites are still able to peform event-handling in the following ways:
- setting the on<event> properties of an element, e.g.
element.onclick = myFunc; - using
addEventListener, e.g.element.addEventListener("click", myFunc, false);
- setting the on<event> properties of an element, e.g.
- Vulnerability types mitigated:
- 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> - 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> javascript:link injection ExampleExample: Blog allowing commenters to specify an arbitrary link to their own website, including javascript:URLs<h1>Blog Comments</h1>
<small>Posted by: <a href="javascript:bad_stuff()">h4x0r</a> on 19 Mar 2009</small>
<p>If you like my comment, please visit my site.</p>- 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()">
- Reflected XSS Example
- Restricted:
- Code will not be created from strings
- Restricted:
eval()setTimeoutcalled with a String argument, e.g.setTimeout("evil string...", 1000)setIntervalcalled with a String argument, e.g.setInterval("evil string...", 1000)new Functionconstructor, e.g.var f = new Function("evil string...")javascript:URIs, e.g.<a href="javascript:bad_stuff()">
- Allowed:
- Functions declared using the function operator, e.g.
function f() { some_code }, orvar f = function() { some_code } setTimeoutcalled with a Function argument, e.g.setTimeout(myFunc, 1000)setIntervalcalled with a Function argument, e.g.setInterval(myFunc, 1000)
- Functions declared using the function operator, e.g.
- Justification:
evaland 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
evaland similar are likely to incorporate tainted strings containing malicious code. - Note: the common AJAX pattern in which a site makes a
XMLHttpRequestto fetch JSON data is still enabled under CSP using a JSON parser or inside a browser that has native JSON support.
- Vulnerability types mitigated:
- AJAX request tampering Example
Example: Website makes AJAX request to a JSON feed using attacker-controlled data and calls evalon 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 } - Improper use of dynamic properties Example
Example: Website uses evalto make references to dynamic JS object properties using attacker-controlled valuesUnsanitized 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 evalcall through the input controlThe resulting code is executed eval( "myObj.prop_; bad_stuff() // = 42" );
- AJAX request tampering Example
- Restricted:
- 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.
- The
- Vulnerability types mitigated:
data:URL script injection ExampleExample: 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>.
- Restricted:
- XBL bindings must come from
chrome:orresource:URIs- Restricted:
- XBL bindings loaded via any protocol other than
chrome:orresource:
- XBL bindings loaded via any protocol other than
- Allowed:
- XBL bindings loaded via the
chrome:orresource:protocols
- XBL bindings loaded via the
- 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:orresource: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:
- 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> - 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-bindingproperty 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>
- Stylesheet script injection Example
- Restricted:
- Optional directives,
policy-uriandreport-uri, must refer to the same host as the protected document. Additionally,policy-uridocuments must be served with the MIME typetext/x-content-security-policyto be valid- Restricted:
policy-uridirectives which refer to a URI on a different host as the protected document, e.g.policy-uri http://other.tld/csp-policy.cgipoliy-uriresponses served with Content-Type other thantext/x-content-security-policy, e.g.Content-Type: text/html, orContent-type: image/jpegreport-uridirectives 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-uridirectives 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-policyreport-uridirectives 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-uridirective via a CSP header. Restricting thepolicy-urito the same host as the protected document, and requiring it to be served astext/x-content-security-policyensures the site has positively opted-in to CSP. - The report sent to the
report-uricontains 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 areport-uri, along with an arbitrary policy to be violated.
- A site which has not opted-in to using CSP should not be forced into using CSP by an attacker who can inject a
- Restricted:
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.
- allow
allowis 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
- options
- Options for modifying the core restrictions of CSP
inline-scriptenables inline script andjavascript:URIseval-scriptenables the parsing of strings into code viaeval()and similar functions
- img-src
- Indicates which sources are valid for images and favicons
- Images from non-white-listed sources will not be requested or loaded
- 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
- script-src
- Indicates valid sources of JavaScript
- Script from non-white-listed sources will not be requested or executed
- object-src
- Indicates valid sources for <object>, <embed>, and <applet> elements
- Objects from non-white-listed sources will not be requested or loaded
- 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
- font-src
- Indicates which sources are valid for
@font-faceloads - Downloadable fonts from non-white-listed sources will not be requested or loaded
- Indicates which sources are valid for
- xhr-src
- Indicates which sources are valid for
XMLHttpRequestconnections XMLHttpRequests may not be opened to non-white-listed sources
- Indicates which sources are valid for
- 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-ancestorslist 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 itsframe-ancestorspolicy 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 headerprovides a more robust mechanism.
- Using
- style-src
- Indicates valid sources for stylesheets
- This includes externally linked stylesheets, as well as inline
<style>elements andstyleattributes of HTML elements within the protected document
- This includes externally linked stylesheets, as well as inline
- Stylesheets from non-white-listed sources will not be requested or loaded
- Indicates valid sources for stylesheets
- 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 violationblocked-uri- URI of the resource that was blocked from loadingviolated-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'" } }
- policy-uri
- Indicates the location of a file containing the security policies for the resource
- The
policy-urimust point to the same host that the protected document resides on, and the file must be served withContent-Type: text/x-content-security-policy - If a valid
policy-uriis specified, any policy defined in the HTTP header will be ignored - A Content Security Policy set including
policy-uriis only valid ifpolicy-uriis 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:
- 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
- (Optional) Scheme, e.g.
- Keyword
- Represents a special class of Content Sources
'self'- refers to the host the protected document is served from, including the same scheme and port (note: single quotes required)'none'- refers to the empty set (no hosts are valid, note: single quotes required)
- Represents a special class of Content Sources
- Data
data:- permitsdata: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
- Site wants all content to come from its own domain:
X-Content-Security-Policy: allow 'self'
- 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
- 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
