This document defines a policy language used to declare a set of content restrictions for a web resource, and a mechanism for transmitting the policy from a server to a client where the policy is enforced.

This document describes a proposal that has been discussed by the broader community for about two years. There are experimental implementations in Firefox and Chrome, using the header names X-Content-Security-Policy and X-WebKit-CSP respectively. Internet Explorer 10 Platform Preview also contains a partial implementation, using the header name X-Content-Security-Policy.

In addition to the documents in the W3C Web Application Security working group, the work on this document is also informed by the work of the IETF websec working group, particularly that working group's requirements document: draft-hodges-websec-framework-reqs.

Introduction

This document defines Content Security Policy, a mechanism web applications can use to mitigate a broad class of content injection vulnerabilities, such as cross-site scripting (XSS). Content Security Policy is a declarative policy that lets the authors (or server administrators) of a web application inform the client about the sources from which the application expects to load resources.

To mitigate XSS attacks, for example, a web application can declare that it only expects to load script from specific, trusted sources. This declaration allows the client to detect and block malicious scripts injected into the application by an attacker.

Content Security Policy (CSP) is not intended as a first line of defense against content injection vulnerabilities. Instead, CSP is best used as defense-in-depth, to reduce the harm caused by content injection attacks.

There is often a non-trivial amount of work required to apply CSP to an existing web application. To reap the greatest benefit, authors will need to move all inline script and style out-of-line, for example into external scripts, because the user agent cannot determine whether an inline script was injected by an attacker.

To take advantage of CSP, a web application opts into using CSP by supplying a Content-Security-Policy HTTP header. Such policies apply to the current resource representation only. To supply a policy for an entire site, the server needs to supply a policy with each resource representation.

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("MUST", "SHOULD", "MAY", etc) used in introducing the algorithm.

A conformant user agent MUST implement all the requirements listed in this specification that are applicable to user-agents.

A conformant server MUST implement all the requirements listed in this specification that are applicable to servers.

Key Concepts and Terminology

This section defines several terms used throughout the document.

The term security policy, or simply policy, for the purposes of this specification refers to either:

  1. a set of security preferences for restrictions within which the content can operate, or
  2. a fragment of text that codifies these preferences.

The security policies defined by this document are applied by a user agent on a per-resource representation basis. Specifically, when a user agent receives a policy along with the representation of a given resource, that policy applies to that resource representation only. This document often refers to that resource representation as the protected resource.

A server transmits its security policy for a particular protected resource as a collection of directives, such as default-src 'self', each of which declares a specific set of restrictions for that resource as instantiated by the user agent. More details are provided in the directives section.

A directive consists of a directive name, which indicates the privileges controlled by the directive, and a directive value, which specifies the restrictions the policy imposes on those privileges.

The term origin is defined in the Origin specification. [[!RFC6454]]

The term globally unique identifier is defined in section 4 of the Origin specification. [[!RFC6454]]

The term URI is defined in the URI specification. [[!URI]]

The term resource representation is defined in the HTTP 1.1 specification. [[!HTTP11]]

The <script>, <object>, <embed>, <img>, <video>, <audio>, <source>, <track>, <link>, <applet>, <frame> and <iframe> elements are defined in the HTML5 specification. [[!HTML5]]

A plugin is defined in the HTML5 specification. [[!HTML5]]

The @font-face Cascading Style Sheets (CSS) rule is defined in the CSS Fonts Module Level 3 specification. [[!CSS3FONT]]

The XMLHttpRequest object is defined in the XMLHttpRequest specification. [[!XMLHTTPREQUEST]]

The WebSocket object is defined in the WebSocket specification. [[!WEBSOCKETS]]

The EventSource object is defined in the EventSource specification. [[!EVENTSOURCE]]

The Augmented Backus-Naur Form (ABNF) notation used in this document is specified in RFC 5234. [[!ABNF]]

This document also uses the ABNF extension "#rule" as defined in HTTP 1.1. [[!HTTP11]]

The following core rules are included by reference, as defined in [ABNF Appendix B.1]: ALPHA (letters), DIGIT (decimal 0-9), WSP (white space) and VCHAR (printing characters).

Framework

This section defines the general framework for content security policies, including the delivery mechanisms and general syntax for policies. The next section contains the details of the specific directives introduced in this specification.

Policy Delivery

The server delivers the policy to the user agent via an HTTP response header.

Content-Security-Policy Header Field

The Content-Security-Policy header field is the preferred mechanism for delivering a CSP policy.

"Content-Security-Policy:" 1#policy

A server MAY send more than one HTTP header field named Content-Security-Policy with a given resource representation.

A server MAY send different Content-Security-Policy header field values with different representations of the same resource or with different resources.

Upon receiving an HTTP response containing at least one Content-Security-Policy header field, the user agent MUST enforce each of the policies contained in each such header field.

Content-Security-Policy-Report-Only Header Field

The Content-Security-Policy-Report-Only header field lets servers experiment with policies by monitoring (rather than enforcing) a policy.

"Content-Security-Policy-Report-Only:" 1#policy

For example, a server operators might wish to develop their security policy iteratively. The operators can deploy a report-only policy based on their best estimate of how their site behaves. If their site violates this policy, instead of breaking the site, the user agent will send violation reports to a URI specified in the policy. Once a site has confidence that the policy is appropriate, they start enforcing the policy using the Content-Security-Policy header field.

A server MAY send more than one HTTP header field named Content-Security-Policy-Report-Only with a given resource representation.

A server MAY send different Content-Security-Policy-Report-Only header field values with different representations of the same resource or with different resources.

Upon receiving an HTTP response containing at least one Content-Security-Policy-Report-Only header field, the user agent MUST monitor each of the policies contained in each such header field.

HTML meta Element (Experimental)

The server MAY supply a CSP policy in an HTML meta element with an http-equiv attribute that is a case insensitive match for either Content-Security-Policy or Content-Security-Policy-Report-Only.

Add the following entries to the pragma directives for the meta element:

Content security policy (http-equiv="content-security-policy")
  1. If the user agent is already enforcing a CSP policy for the document, abort these steps.
  2. If the meta element lacks a content attribute, abort these steps.
  3. Enforce the CSP policy contained in the content attribute of the meta element.
Content security policy, report only (http-equiv="content-security-policy-report-only")
  1. If the user agent is already monitoring a CSP policy for the document, abort these steps.
  2. If the meta element lacks a content attribute, abort these steps.
  3. Monitor the CSP policy contained in the content attribute of the meta element.

As a consequence of these requirements, a policy supplied in an HTTP header field takes precedence over policies supplied in meta elements. Similarly, the above requirements entail that the first meta element containing a policy takes precedence over policies supplied in subsequent meta elements.

TODO: Turn the bullets below into actual spec text.

  • In order to work, the meta element needs to be in document's head. This requirement makes it harder for folks to inject CSP policies into vulnerable documents.
  • Ignore the report-uri directive in CSP policies obtained from meta elements. This requirement mitigates one attack that might result from an injected policy. It also provides a carrot for supplying the policy in an HTTP header, which is better for security.
  • Add some guidance that sites should put the meta element as early as possible in their document to reduce the risk of an attacker injecting another policy in front.
  • Ignore policies from meta elements that get inserted after the document's readyState reaches "interactive". This requirement further mitigates the risk of the meta element being injected. (Is this requirement still useful in light of the above mitigations?)

Enforcing multiple policies.

The above sections note that when multiple policies are present, each must be enforced or reported, according to its type. An example will help clarify how that ought to work in practice. The behavior of an XMLHttpRequest might seem unclear given a site that, for whatever reason, delivered the following HTTP headers:

Content-Security-Policy: default-src 'self' http://example.com http://example.net;
                         connect-src 'none';
Content-Security-Policy: connect-src http://example.com/;
                         script-src http://example.com/
          

Is a connection to example.com allowed or not? The short answer is that the connection is not allowed. Enforcing both policies means that a potential connection would have to pass through both unscathed. Even though the second policy would allow this connection, the first policy contains connect-src 'none', so its enforcement blocks the connection. The impact is that adding additional policies to the list of policies to enforce can only further restrict the capabilities of the protected resource.

To demonstrate that further, consider a script tag on this page. The first policy would lock scripts down to 'self', http://example.com and http://example.net via the default-src directive. The second, however, would only allow script from http://example.com/. Script will only load if it meets both policy's criteria: in this case, the only origin that can match is http://example.com, as both policies allow it.

Syntax and Algorithms

Policies

A CSP policy consists of a U+003B SEMICOLON (;) delimited list of directives:

policy            = [ directive *( ";" [ directive ] ) ]

Each directive consists of a directive-name and (optionally) a directive-value:

directive         = *WSP [ directive-name [ WSP directive-value ] ]
directive-name    = 1*( ALPHA / DIGIT / "-" )
directive-value   = *( WSP / <VCHAR except ";" and ","> )
Parsing

To parse a CSP policy policy, the user agent MUST use an algorithm equivalent to the following:

  1. Let the set of directives be the empty set.
  2. For each non-empty token returned by strictly splitting the string policy on the character U+003B SEMICOLON (;):
    1. Skip whitespace.
    2. Collect a sequence of characters that are not space characters. The collected characters are the directive name.
    3. If there are characters remaining in token, skip ahead exactly one character (which must be a space character).
    4. The remaining characters in token (if any) are the directive value.
    5. If the set of directives already contains a directive with name directive name, ignore this instance of the directive and continue to the next token.
    6. Add a directive to the set of directives with name directive name and value directive value.
  3. Return the set of directives.

Source List

Many CSP directives use a value consisting of a source list.

Each source expression in the source list represents a location from which content of the specified type can be retrieved. For example, the source expression 'self' represents the set of URIs which are in the same origin as the protected resource and the source expression 'unsafe-inline' represents content supplied inline in the resource itself.

source-list       = *WSP [ source-expression *( 1*WSP source-expression ) *WSP ]
                  / *WSP "'none'" *WSP
source-expression = scheme-source / host-source / keyword-source
scheme-source     = scheme ":"
host-source       = [ scheme "://" ] host [ port ] [ path ]
keyword-source    = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
scheme            = <scheme production from RFC 3986, section 3.1>
host              = "*" / [ "*." ] 1*host-char *( "." 1*host-char )
host-char         = ALPHA / DIGIT / "-"
path              = <path production from RFC 3986, section 3.3>
port              = ":" ( 1*DIGIT / "*" )
Parsing

To parse a source list source list, the user agent MUST use an algorithm equivalent to the following:

  1. If source list (with leading and trailing whitespace stripped) is a case insensitive match for the string 'none' (including the quotation marks), return the empty set.
  2. Let the set of source expressions be the empty set.
  3. For each token returned by splitting source list on spaces, if the token matches the grammar for source-expression, add the token to the set of source expressions.
  4. Return the set of source expressions.

Note that characters like U+003B SEMICOLON (;) and U+002C COMMA (,) cannot appear in source expressions directly: if you'd like to include these characters in a source expression, they must be percent encoded as %3B and %2C respectively.

Matching

To check whether a URI matches a source expression, the user agent MUST use an algorithm equivalent to the following:

  1. Normalize the URI according to RFC 3986, section 6.
  2. If the source expression a consists of a single U+002A ASTERISK character (*), then return does match.
  3. If the source expression matches the grammar for scheme-source:
    1. If the URI's scheme is a case-insensitive match for the source expression's scheme, return does match.
    2. Otherwise, return does not match.
  4. If the source expression matches the grammar for host-source:
    1. If the URI does not contain a host, then return does not match.
    2. Let uri-scheme, uri-host, and uri-port be the scheme, host, and port of the URI, respectively. If the URI does not have a port, then let uri-port be the default port for uri-scheme. Let uri-path be the path of the URI after decoding percent-encoded characters. If the URI does not have a path, then let uri-path be the U+002F SOLIDUS character (/).
    3. If the source expression has a scheme that is not a case insensitive match for uri-scheme, then return does not match.
    4. If the source expression does not have a scheme, return does not match if
      1. the scheme of the protected resource's URI is a case insensitive match for HTTP, and uri-scheme is not a case insensitive match for either HTTP or HTTPS
      2. the scheme of the protected resource's URI is not a case insensitive match for HTTP, and uri-scheme is not a case insensitive match for the scheme of the protected resource's URI.
    5. If the first character of the source expression's host is an U+002A ASTERISK character (*) and the remaining characters, including the leading U+002E FULL STOP character (.), are not a case insensitive match for the rightmost characters of uri-host, then return does not match.
    6. If uri-host is not a case insensitive match for the source expression's host, then return does not match.
    7. If the source expression does not contain a port and uri-port is not the default port for uri-scheme, then return does not match.
    8. If the source expression does contain a port, then return does not match if
      1. port does not contain an U+002A ASTERISK character (*), and
      2. port does not represent the same number as uri-port.
    9. If the source expression contains a non-empty path, then:
      1. Let decoded-path be the result of decoding path's percent-encoded characters.
      2. If the final character of decoded-path is the U+002F SOLIDUS character (/), and decoded-path is not a prefix of uri-path, then return does not match.
      3. If the final character of decoded-path is not the the U+002F SOLIDUS character (/), and decoded-path is not an exact match for uri-path then return does not match.
    10. Otherwise, return does match.
  5. If the source expression is a case insensitive match for 'self' (including the quotation marks), then:
    1. Return does match if the URI has the same scheme, host, and port as the protected resource's URI (using the default port for the appropriate scheme if either or both URIs are missing ports).
    2. Return does match if the URI's origin has the same scheme, host, and port as the protected resource's URI (using the default port for the appropriate scheme if the URI is missing a port). This includes URIs with the blob scheme, for instance.
  6. Otherwise, return does not match.

A URI matches a source list, if, and only if, the URI matches at least one source expression in the set of source expressions obtained by parsing the source list. Notice that no URIs match an empty set of source expressions, such as the set obtained by parsing the source list 'none'.

Path Matching

The rules for matching source expressions that contain paths are simpler than they look: paths that end with the '/' character match all files in a directory and its subdirectories. Paths that do not end with the '/' character match only one specific file. A few examples should make this clear:

  1. The source expression example.com has no path, and therefore matches any file served from that host.
  2. The source expression example.com/scripts/ matches any file in the scripts directory of example.com, and any of its subdirectories. For example, both https://example.com/scripts/file.js and https://example.com/scripts/js/file.js would match.
  3. The source expression example.com/scripts/file.js matches only the file named file.js in the scripts directory of example.com.
  4. Likewise, the source expression example.com/js matches only the file named js. In particular, note that it would not match files inside a directory named js. Files like example.com/js/file.js would be matched only if the source expression ended with a trailing "/", as in example.com/js/.

Note that query strings have no impact on matching: the source expression example.com/file?key=value matches all of https://example.com/file, https://example.com/file?key=value, https://example.com/file?key=notvalue, and https://example.com/file?notkey=notvalue.

Media Type List

The experimental plugin-types directive uses a value consisting of a media type list.

Each media type in the media type list represents a specific type of resource that can be retrieved and used to instantiate a plugin in the protected resource.

media-type-list   = media-type *( 1*WSP media-type )
media-type        = <type from RFC 2045> "/" <subtype from RFC 2045>
Parsing

To parse a media type list media type list, the user agent MUST use an algorithm equivalent to the following:

  1. Let the set of media types be the empty set.
  2. For each token returned by splitting media type list on spaces, if the token matches the grammar for media-type, add the token to the set of media types. Otherwise ignore the token.
  3. Return the set of media types.
Matching

A media type matches a media type list if, and only if, the media type is a case-insensitive match for at least one token in the set of media types obtained by parsing the media type list.

Processing Model

To enforce a CSP policy, the user agent MUST parse the policy and enforce each of the directives contained in the policy, where the specific requirements for enforcing each directive are defined separately for each directive (See Directives, below).

Generally speaking, enforcing a directive prevents the protected resource from performing certain actions, such as loading scripts from URIs other than those indicated in a source list. These restrictions make it more difficult for an attacker to abuse an injection vulnerability in the resource because the attacker will be unable to usurp the resource's privileges that have been restricted in this way.

Enforcing a CSP policy SHOULD NOT interfere with the operation of user-supplied scripts such as third-party user-agent add-ons and JavaScript bookmarklets.

To monitor a CSP policy, the user agent MUST parse the policy and monitor each of the directives contained in the policy.

Monitoring a directive does not prevent the protected resource from undertaking any actions. Instead, any actions that would have been prevented by the directives are instead reported to the developer of the web application. Monitoring a CSP policy is useful for testing whether enforcing the policy will cause the web application to malfunction.

A server MAY cause user agents to monitor one policy while enforcing another policy by returning both Content-Security-Policy and Content-Security-Policy-Report-Only header fields. For example, if a server operator is using one policy but wishes to experiment with a stricter policy, the server operator can monitor the stricter policy while enforcing the original policy. Once the server operator is satisfied that the stricter policy does not break the web application, the server operator can start enforcing the stricter policy.

If the user agent monitors or enforces a CSP policy that does not contain any directives, the user agent SHOULD report a warning message in the developer console.

If the user agent monitors or enforces a CSP policy that contains an unrecognized directive, the user agent SHOULD report a warning message in the developer console indicating the name of the unrecognized directive.

Whenever a user agent runs a worker: [[!WEBWORKERS]]

If a policy violation occurs while enforcing or monitoring a policy, the user agent MUST fire a violation event at the protected resource's Document.

Script Interfaces (Experimental)

SecurityPolicyViolationEvent Events

readonly attribute DOMString documentURI
Refer to the document-uri property of violation reports for a description of this property.
readonly attribute DOMString referrer
Refer to the referrer property of violation reports for a description of this property.
readonly attribute DOMString blockedURI
Refer to the blocked-uri property of violation reports for a description of this property.
readonly attribute DOMString violatedDirective
Refer to the violated-directive property of violation reports for a description of this property.
readonly attribute DOMString effectiveDirective
Refer to the effective-directive property of violation reports for a description of this property.
readonly attribute DOMString originalPolicy
Refer to the original-policy property of violation reports for a description of this property.
readonly attribute DOMString sourceFile
Refer to the source-file property of violation reports for a description of this property.
readonly attribute long lineNumber
Refer to the line-number property of violation reports for a description of this property.
DOMString documentURI
Refer to the document-uri property of violation reports for a description of this property.
DOMString referrer
Refer to the referrer property of violation reports for a description of this property.
DOMString blockedURI
Refer to the blocked-uri property of violation reports for a description of this property.
DOMString violatedDirective
Refer to the violated-directive property of violation reports for a description of this property.
DOMString effectiveDirective
Refer to the effective-directive property of violation reports for a description of this property.
DOMString originalPolicy
Refer to the original-policy property of violation reports for a description of this property.
DOMString sourceFile
Refer to the source-file property of violation reports for a description of this property.
long lineNumber
Refer to the line-number property of violation reports for a description of this property.
Firing events using the SecurityPolicyViolationEvent interface

To fire a violation event means to queue a task to fire an event named securitypolicyviolation using the SecurityPolicyViolationEvent interface with the following initializations:

  • documentURI MUST be initialized to the address of the protected resource.
  • referrer MUST be initialized to the referrer of the protected resource, or the empty string if the protected resource has no referrer.
  • blockedURI MUST be initialized to the URI of the resource that was prevented from loading, or the empty string if the resource has no URI.
  • violatedDirective MUST be initialized to the policy directive that was violated. This will contain the default-src directive in the case of policy violations caused by falling back to the default sources when enforcing a directive.
  • effectiveDirective MUST be initialized to the name of the policy directive that was violated. This will contain the directive whose enforcement triggered the violation, even if that directive does not explicitly appear in the policy, but is implicitly activated via the default-src directive.
  • originalPolicy MUST be initialized to the policy as received by the user-agent.
  • sourceFile MUST be intialized to the address of the resource where the violation occurred. This might be the same as documentURI, or might point to an external script, stylesheet, etc.
  • lineNumber MUST be initialized to the line number in sourceFile where the violation occurred, or to 0 if no line number can be determined.

If the origin of resource that was prevented from loading is not the same as the origin of the protected resource, then replace the blockedURI property's value with the ASCII serialization of the blocked resource's origin.

If the origin of resource that was prevented from loading is a globally unique identifier (for example, data: or blob:), then replace the blockedURI property's value with the ASCII serialization of the blocked resource's scheme.

The task source for the queued task is the DOM manipulation task source.

Document

readonly attribute SecurityPolicy securityPolicy
The security policy for this document.
attribute EventHandler onsecuritypolicyviolation
Event handler for securitypolicyviolation events.

SecurityPolicy

Let the active CSP policies be the set of CSP policies the user agent is currently enforcing for the associated document.

readonly attribute bool allowsEval
A boolean representing the logical and of whether the source expression 'unsafe-eval' is present in the allowed script sources of each of the active CSP policies.
readonly attribute bool allowsInlineScript
A boolean representing the logical and of whether the source expression 'unsafe-inline' is present in the allowed script sources of each of the active CSP policies.
readonly attribute bool allowsInlineStyle
A boolean representing the logical and of whether the source expression 'unsafe-inline' is present in the allowed style sources of each of the active CSP policies.
readonly attribute bool isActive
A boolean which is true if the set of active CSP policies is non-empty, and false otherwise.
readonly attribute DOMString[] reportURIs
An array consisting of the union of the set of report URIs for all the active CSP policies.
bool allowsConnectionTo(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed connection targets of each of the active CSP policies.
bool allowsFontFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed font sources of each of the active CSP policies.
bool allowsFormAction(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed form actions of each of the active CSP policies.
bool allowsFrameFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed frame sources of each of the active CSP policies.
bool allowsImageFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed image sources of each of the active CSP policies.
bool allowsMediaFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed media sources of each of the active CSP policies.
bool allowsObjectFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed object sources of each of the active CSP policies.
bool allowsPluginType(DOMString type)
Returns the logical and of whether the provided type matches the allowed plugin types of each of the active CSP policies.
bool allowsScriptFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed script sources of each of the active CSP policies.
bool allowsStyleFrom(DOMString uri)
Returns the logical and of whether the provided uri matches the allowed style sources of each of the active CSP policies.

Usage

The script interface described here serves as a feature detection API that developers can use in order to make intelligent decisions about code that executes on a page based on the page's active policy. This is especially important for developers of libraries or frameworks which are meant to be used on a variety of sites in unknown contexts.

A few use-cases follow for illustration:

  • Does the user agent support CSP?

    var isCSPSupported = !!document.SecurityPolicy;
  • Is a policy active on the current page? If not, perhaps one should be injected via the (experimental) meta element.

    var isCSPActive = document.SecurityPolicy.isActive();
  • Can I use new Function(); or eval()? Some libraries use these dangerous methods for performance optimizations. If they are unavailable, the library could gracefully fall back to a less performant (but safer) mechanism.

    var isEvalAvailable = document.SecurityPolicy.allowsEval();
  • Can I use library X, hosted on a third-party server? Analytics packages are a good example of such third-party packages that a developer might want to include if they're allowed. For a library that's hosted on https://cdn.example.com/ and that includes images from https://img.example.com/, the following would allow a developer to determine its availability.

    var isLibraryAvailable = (document.SecurityPolicy.allowsScriptFrom('https://cdn.example.com/path/to/library.js')
                              && document.SecurityPolicy.allowsImageFrom('https://img.example.com/path/to/img.png'));

Note that this interface only provides insight into the origins allowed by the page's Content Security Policy. That, of course, is not the only restriction that might be in place. Just because CSP allows you to make XMLHttpReqests to https://bank.example.com/ doesn't mean that the request will go through cleanly.

Directives

This section describes the content security policy directives introduced in this specification.

In order to protect against Cross-Site Scripting (XSS), web application authors SHOULD include

In either case, authors SHOULD NOT include either 'unsafe-inline' or data: as valid sources in their policies. Both enable XSS attacks by allowing code to be included directly in the document itself; they are best avoided completely.

default-src

The default-src directive sets a default source list for a number of directives. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "default-src"
directive-value   = source-list

Let the default sources be the result of parsing the default-src directive's value as a source list.

To enforce the default-src directive, the user agent MUST enforce the following directives:

If not specified explicitly in the policy, the directives listed above will use the default sources.

Usage

default-src, as the name implies, serves as a default source list which the other source list-style directives will use as a fallback if they're not otherwise explicitly set. That is, consider the following policy declaration:

Content-Security-Policy: default-src 'self'

Under this policy, fonts, frames, images, media, objects, scripts, and styles will all only load from the same origin as the protected resource, and connections will only be made to the same origin. Adding a more specific declaration to the policy would completely override the default source list for that resource type.

Content-Security-Policy: default-src 'self'; script-src example.com

Under this new policy, fonts, frames, and etc. continue to be load from the same origin, but scripts will only load from example.com. There's no inheritance; the script-src directive sets the allowed sources of script, and the default list is not used for that resource type.

Given this behavior, one good way of building a policy for a site would be to begin with a default-src of 'none', and to build up a policy from there that contains only those resource types which are actually in use for the page you'd like to protect. If you don't use webfonts, for instance, there's no reason to specify a source list for font-src; specifying only those resource types a page uses ensures that the possible attack surface for that page remains as small as possible.

script-src

The script-src directive restricts which scripts the protected resource can execute. The directive also controls other resources, such as XSLT style sheets [[!XSLT]], which can cause the user agent to execute script. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "script-src"
directive-value   = source-list

The term allowed script sources refers to the result of parsing the script-src directive's value as a source list if the policy contains an explicit script-src, or otherwise to the default sources.

If 'unsafe-inline' is not in allowed script sources:

If 'unsafe-eval' is not in allowed script sources:

The term callable refers to an object whose interface has one or more callers as defined in the Web IDL specification [[!WEBIDL]].

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed script sources, the user agent MUST act as if it had received an empty HTTP 400 response:

object-src

The object-src directive restricts from where the protected resource can load plugins. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "object-src"
directive-value   = source-list

The term allowed object sources refers to the result of parsing the object-src directive's value as a source list if the policy contains an explicit object-src, or otherwise to the default sources.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed object sources, the user agent MUST act as if it had received an empty HTTP 400 response:

It is not required that the consumer of the element's data be a plugin in order for the object-src directive to be enforced. Data for any object, embed, or applet element MUST match the allowed object sources in order to be fetched. This is true even when the element data is semantically equivalent to content which would otherwise be restricted by one of the other directives, such as an object element with a text/html MIME type.

Whenever the user agent would load a plugin without an associated URI (e.g., because the object element lacked a data attribute), if the protected resource's URI does not match the allowed object sources, the user agent MUST NOT load the plugin.

style-src

The style-src directive restricts which styles the user applies to the protected resource. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "style-src"
directive-value   = source-list

The term allowed style sources refers to the result of parsing the style-src directive's value as a source list if the policy contains an explicit style-src, or otherwise to the default sources.

If 'unsafe-inline' is not in allowed style sources:

Note: These restrictions on inline do not prevent the user agent from applying style from an external stylesheet (e.g., found via <link rel="stylesheet">). The user agent is also not prevented from applying style from Cascading Style Sheets Object Model (CSSOM). [[!CSSOM]]

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed style sources, the user agent MUST act as if it had received an empty HTTP 400 response:

Note: The style-src directive does not restrict the use of XSLT. XSLT is restricted by the script-src directive because the security consequences of including an untrusted XSLT stylesheet are similar to those incurred by including an untrusted script.

img-src

The img-src directive restricts from where the protected resource can load images. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "img-src"
directive-value   = source-list

The term allowed image sources refers to the result of parsing the img-src directive's value as a source list if the policy contains an explicit img-src, or otherwise to the default sources.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed image sources, the user agent MUST act as if it had received an empty HTTP 400 response:

media-src

The media-src directive restricts from where the protected resource can load video and audio. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "media-src"
directive-value   = source-list

The term allowed media sources refers to the result of parsing the media-src directive's value as a source list if the policy contains an explicit media-src, or otherwise to the default sources.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed media sources, the user agent MUST act as if it had received an empty HTTP 400 response:

frame-src

The frame-src directive restricts from where the protected resource can embed frames. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "frame-src"
directive-value   = source-list

The term allowed frame sources refers to the result of parsing the frame-src directive's value as a source list if the policy contains an explicit frame-src, or otherwise to the default sources.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed frame sources, the user agent MUST act as if it had received an empty HTTP 400 response:

font-src

The font-src directive restricts from where the protected resource can load fonts. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "font-src"
directive-value   = source-list

The term allowed font sources refers to the result of parsing the font-src directive's value as a source list if the policy contains an explicit font-src, or otherwise to the default sources.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed font sources, the user agent MUST act as if it had received an empty HTTP 400 response:

connect-src

The connect-src directive restricts which URIs the protected resource can load using script interfaces. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "connect-src"
directive-value   = source-list

The term allowed connection targets refers to the result of parsing the connect-src directive's value as a source list if the policy contains an explicit connect-src, or otherwise to the default sources.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed connection targets, the user agent MUST act as if it had received an empty HTTP 400 response:

Usage

JavaScript offers a few mechanisms that directly connect to an external server to send or receive information. EventSource maintains an open HTTP connection to a server in order to receive push notifications, WebSockets open a bidirectional communication channel between your browser and a server, and XMLHttpRequest makes arbitrary HTTP requests on your behalf. These are powerful APIs that enable useful functionality, but also provide tempting avenues for data exfiltration.

The connect-src directive allows you to ensure that these sorts of connections are only opened to origins you trust. Sending a policy that defines a list of source expressions for this directive is straightforward. For example, to limit connections to only example.com, send the following header:

Content-Security-Policy: connect-src example.com

All of the following will fail with the preceeding directive in place:

  • new WebSocket("wss://evil.com/");
  • (new XMLHttpRequest()).open("GET", "https://evil.com/", true);
  • new EventSource("https://evil.com");

form-action (Experimental)

The form-action restricts which URIs can be used as the action of HTML form elements. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "form-action"
directive-value   = source-list

The term allowed form actions refers to the result of parsing the form-action directive's value as a source list.

Whenever the user agent fetches a URI (including when following redirects) in the course of one of the following activities, if the URI does not match the allowed form actions, the user agent MUST act as if it had received an empty HTTP 400 response:

Note that form-action does not fall back to the default source list when the directive is not defined. That is, a policy that defines default-src 'none' but not form-action will still allow form submissions to any target.

sandbox

The sandbox directive specifies an HTML sandbox policy that the user agent applies to the protected resource. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "sandbox"
directive-value   = token *( 1*WSP token )
token             = <token from RFC 2616>

When enforcing the sandbox directive, the user agent MUST parse the sandboxing directive using the directive-value as the input and protected resource's forced sandboxing flag set as the output. [[!HTML5]]

Usage

HTML5 defines a sandbox attribute for iframe elements, intended to allow web authors to reduce the risk of including potentially untrusted content by imposing restrictions on that content's abilities. When the attribute is set, the content is forced into a unique origin, prevented from submitting forms, running script, creating or navigating other browsing contexts, and prevented from running plugins. These restrictions can be loosened by setting certain flags as the attribute's value.

The sandbox directive allows any resource, framed or not, to ask for the same sorts of restrictions to be applied to itself.

For example, a message board or email system might provide downloads of arbitrary attachments provided by other users. Attacks that rely on tricking a client into rendering one of these attachments could be mitigated by requesting that resources only be rendered in a very restrictive sandbox. Sending the sandbox directive with an empty value establishes such an environment:

Content-Security-Policy: sandbox

More trusted resources might be allowed to run in an environment with fewer restrictions by adding allow-* flags to the directive's value. For example, you can allow a page that you trust to run script, while ensuring that it isn't treated as same-origin with the rest of your site. This can be accomplished by sending the sandbox directive with the allow-scripts flag:

Content-Security-Policy: sandbox allow-scripts

The set of flags available to the CSP directive should match those available to the iframe attribute. Currently, those include:

  • allow-forms
  • allow-same-origin
  • allow-scripts, and
  • allow-top-navigation

Note as well that, like the rest of Content Security Policy, the sandbox directive is meant as a defense-in-depth. Web authors would be well-served to use it in addition to standard sniffing-mitigation and privilege-reduction techniques.

script-nonce (Experimental)

The script-nonce directive restricts script execution by requiring the presence of the specified nonce on script elements. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "script-nonce"
directive-value   = nonce
nonce             = 1*( <VCHAR except ";" and ","> )

If the directive's value is empty, consists solely of whitespace, or contains invalid characters, let the script nonce be the empty string. Otherwise, let the script nonce be the directive's value, stripped of leading and trailing whitespace.

If the policy contains a script-nonce directive, the server MUST generate a fresh value for the script-nonce directive at random and independently each time it transmits a policy. This requirement ensures that the nonce value is difficult for an attacker to predict.

When enforcing the script-nonce directive:

Usage

The script-nonce directive is intended to allow developers to strictly specify exactly which script elements on a page were intentionally included for execution. This is particularly useful when 'unsafe-inline' is accepted as a valid script-src (though any site is better off avoiding inline script completely), but can also serve as a layer of protection against the execution of otherwise trusted resources in a context where they might be unexpected and potentially dangerous.

Usage is straightforward. For each request, the server generates a unique value at random, and includes it in the CSP header:

Content-Security-Policy: script-nonce random-value;

This same value is then applied as a nonce attribute to each script tag that ought to be executed.

<script src="/path/to/script.js" nonce="random-value"></script>
<script nonce="random-value">
  alert("I execute! Hooray!");
</script>
<script>
  alert("I don't execute. Boo!");
</script>

Note that the nonce's value is not a hash or signature that verifies the contents of the script resources. It's quite simply a random string that informs the user agent which scripts were intentionally included in the page.

script elements containing the proper nonce execute. script elements that don't, don't. Even if an attacker is able to inject markup into the protected resource, the attack will be blocked by the attacker's inability to guess the random value.

Interaction with the script-src directive

The script-nonce and script-src directives' restrictions on code execution are non-exclusive: script will not execute unless it satisfies both directives. For example, inline event handlers will not execute given the following policy:

Content-Security-Policy: script-src 'self' 'unsafe-inline';
                         script-nonce nonce_value;

The script-src directive allows 'unsafe-inline', but the event handler's execution is blocked by the presence of the script-nonce directive.

Similarly, script will not be executed given the following policy:

Content-Security-Policy: script-src https://cdn.example.com;
                         script-nonce nonce_value;

and the following script element:

<script nonce="nonce_value" src="https://not.example.com/script.js"></script>

The nonce value matches, but the source isn't included in the script-src directive's source list. If the script element was loading script from https://cdn.example.com/ instead, it would execute, as its execution would violate neither the script-nonce nor script-src directives.

Finally, and potentially surprisingly, script will not be executed given the following policy:

Content-Security-Policy: script-src https://cdn.example.com;
                         script-nonce nonce_value;

and the following script element:

<script src="https://cdn.example.com/script.js"></script>

The source matches the script-src directive's source list, but no nonce is present. Its execution would therefore violate the script-nonce directive's restrictions.

plugin-types (Experimental)

The plugin-types restricts the set of plugins that can be invoked by the protected resource by limiting the types of resources that can be embedded. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "plugin-types"
directive-value   = media-type-list

The term allowed plugin types refers to the result of parsing the plugin-types directive's value as a media type list

Whenever the user agent would instantiate a plugin to handle resource while enforcing the plugin-types directive, the user agent MUST instead act as though the plugin reported an error if any of the following conditions hold:

Note that in any of these cases, acting as though the plugin reported an error will cause the user agent to display the fallback content.

Usage

The plugin-types directive whitelists a certain set of MIME types that can be embedded in a protected resource. For example, a site might want to ensure that PDF content loads, but that no other plugins can be instantiated. The following directive would satisfy that requirement:

Content-Security-Policy: plugin-types application/pdf;

Resources embedded via an embed or object element delivered with an application/pdf content type would be rendered in the appropriate plugin; resources delivered with some other content type would be blocked. Multiple types can be specified, in any order. If the site decided to additionally allow Flash at some point in the future, it could do so with the following directive:

Content-Security-Policy: plugin-types application/pdf application/x-shockwave-flash;

Note that wildcards are not accepted in the plugin-types directive. Only the resource types explicitly listed in the directive will be allowed.

Predeclaration of expected media types

Enforcing the plugin-types directive requires that object and embed elements declare the expected media type of the resource they include via the type attribute. If an author expects to load a PDF, she could specify this as follows:

<object data="resource" type="application/pdf"></object>

If resource isn't actually a PDF file, it won't load. This prevents certain types of attacks that rely on serving content that unexpectedly invokes a plugin other than that which the author intended.

Note that resource will not load in this scenario even if its media type is otherwise whitelisted: resources will only load when their media type is whitelisted and matches the declared type in their containing element.

reflected-xss (Experimental)

The reflected-xss directive instructs a user agent to active or disactivate any heuristics used to filter or block reflected cross-site scripting attacks. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "reflected-xss"
directive-value   = "allow" / "block" / "filter"

A user agent with support for XSS protection MUST enforce this directive as follows:

Relationship to X-XSS-Protection

This directive is meant to subsume the functionality provided by the propriatary X-XSS-Protection HTTP header which is supported by a number of user agents. Roughly speaking:

  • reflected-xss allow is equivalent to X-XSS-Protection: 0
  • reflected-xss filter is equivalent to X-XSS-Protection: 1
  • reflected-xss block is equivalent to X-XSS-Protection: 1; mode=block

report-uri

The report-uri directive specifies a URI to which the user agent sends reports about policy violation. The syntax for the name and value of the directive are described by the following ABNF grammar:

directive-name    = "report-uri"
directive-value   = uri-reference *( 1*WSP uri-reference )
uri-reference     = <URI-reference from RFC 3986>

The set of report URIs is the value of the report-uri directive, each resolved relative to the protected resource's URI.

To send a violation report, the user agent MUST use an algorithm equivalent to the following:

  1. Prepare a JSON object violation-object with the following keys and values: [[!RFC4627]]
    csp-report

    A JSON object containing the following keys and values:

    document-uri
    The address of the protected resource, with any <fragment> component removed.
    referrer
    The referrer attribute of the protected resource, or the empty string if the protected resource has no referrer.
    blocked-uri
    URI of the resource that was prevented from loading due to the policy violation, with any <fragment> component removed, or the empty string if the resource has no URI (inline script and inline style, for example).
    violated-directive
    The policy directive that was violated. This will contain the default-src directive in the case of policy violations caused by falling back to the default sources when enforcing a directive.
    effective-directive
    The name of the policy directive that was violated. This will contain the directive whose enforcement triggered the violation, even if that directive does not explicitly appear in the policy, but is implicitly activated via the default-src directive.
    original-policy
    The original policy as received by the user-agent.

    If the violation occurred as a result of script execution, and a specific line can be identified as the source, the following keys and values MAY be added:

    source-file
    The address of the resource where the violation occurred (an external script file, for instance), with any <fragment> component removed.
    line-number
    The line number in source-file on which the violation occurred.
  2. If the origin of the blocked-uri is not the same as the origin of the protected resource, then replace the blocked-uri with the ASCII serialization of the blocked-uri's origin.
  3. If the origin of the blocked-uri is a globally unique identifier (for example, data: or blob:), then replace the blocked-uri with the ASCII serialization of the blocked-uri's scheme.
  4. Let the violation report be the JSON stringification of the violation-object.
  5. For each report URI in the set of report URIs:
    1. Fetch the report URI from origin of the protected resource, with the synchronous flag not set, using HTTP method POST, with a Content-Type header field of application/json with an entity body consisting of the violation report. The user agent MUST NOT follow redirects when fetching this resource. (Note: The user agent ignores the fetched resource.)

Examples

Sample Policy Definitions

This section provides some sample use cases and accompanying security policies.

Example 1: A server wishes to load resources only form its own origin:

Content-Security-Policy: default-src 'self'

Example 2: An auction site wishes to load images from any URI, plugin content from a list of trusted media providers (including a content distribution network), and scripts only from a server under its control hosting sanitized ECMAScript:

Content-Security-Policy: default-src 'self'; img-src *;
                         object-src media1.example.com media2.example.com *.cdn.example.com;
                         script-src trustedscripts.example.com

Example 3: Online banking site wishes to ensure that all of the content in its pages is loaded over TLS to prevent attackers from eavesdropping on insecure content requests:

Content-Security-Policy: default-src https: 'unsafe-inline' 'unsafe-eval'

This policy allows inline content (such as inline script elements), use of eval, and loading resources over https. Note: This policy does not provide any protection from cross-site scripting vulnerabilities.

Example 4: A website that relies on inline script elements wishes to ensure that script is only executed from its own origin, and those elements it intentionally inserted inline:

Content-Security-Policy: script-src 'self' 'unsafe-inline';
                         script-nonce: nonce_value;

The inline script elements would then only execute if they contained a matching nonce attribute:

<script nonce="nonce_value">...</script>

Sample Violation Report

This section contains an example violation report the user agent might sent to a server when the protected resource violations a sample policy.

In the following example, the user agent rendered a representation of the resource http://example.org/page.html with the following CSP policy:

default-src 'self'; report-uri http://example.org/csp-report.cgi

The protected resource loaded an image from http://evil.example.com/image.png, violating the policy.

{
  "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'",
    "effective-directive": "img-src",
    "original-policy": "default-src 'self'; report-uri http://example.org/csp-report.cgi"
  }
}

Security Considerations

Cascading Style Sheet (CSS) Parsing

The style-src directive restricts the locations from which the protected resource can load styles. However, if the user agent uses a lax CSS parsing algorithm, an attacker might be able to trick the user agent into accepting malicious "style sheets" hosted by an otherwise trustworthy origin.

These attacks are similar to the CSS cross-origin data leakage attack described by Chris Evans in 2009. User agents SHOULD defend against both attacks using the same mechanism: stricter CSS parsing rules for style sheets with improper MIME types.

Violation Reports

The violation reporting mechanism in this document has been designed to mitigate the risk that a malicious web site could use violation reports to probe the behavior of other servers. For example, consider a malicious web site that white lists https://example.com as a source of images. If the malicious site attempts to load https://example.com/login as an image, and the example.com server redirects to an identity provider (e.g., idenityprovider.example.net), CSP will block the request. If violation reports contained the full blocked URI, the violation report might contain sensitive information contained in the redirected URI, such as session identifiers or purported identities. For this reason, the user agent includes only the origin of the blocked URI.

Implementation Considerations

The Content-Security-Policy header is an end-to-end header. It is processed and enforced at the client and, therefore, SHOULD NOT be modified or removed by proxies or other intermediaries not in the same administrative domain as the resource.

The originating administrative domain for a resource might wish to apply a Content-Security-Policy header outside of the immediate context of an application. For example, a large organization might have many resources and applications managed by different individuals or teams but all subject to a uniform organizational standard. In such situations, a Content-Security-Policy header might be added or combined with an existing one at a network-edge security gateway device or web application firewall. To enforce multiple policies, the administrator SHOULD combine the policy into a single header. An administrator might wish to use different combination algorithms depending on his or her intended semantics.

One sensible policy combination algorithm is to start by allowing a default set of sources and then letting individual upstream resource owners expand the set of allowed sources by including additional origins. In this approach, the resultant policy is the union of all allowed origins in the input policies.

Another sensible policy combination algorithm is to intersect the given policies. This approach enforces that content comes from a certain whitelist of origins, for example, preventing developers from including third-party scripts or content in violation of organizational standards and practices. In this approach, the combination algorithm forms the combined policy by removing disallowed hosts from the policies supplied by upstream resource owners.

Interactions between the default-src and other directives SHOULD be given special consideration when combining policies. If none of the policies contains a default-src directive, adding new src directives results in a more restrictive policy. However, if one or more of the input policies contain a default-src directive, adding new src directives might result in a less restrictive policy, for example, if the more specific directive contains a more permissive set of allowed origins.

Using a more restrictive policy than the input policy authored by the resource owner might prevent the resource from rendering or operating as intended.

IANA Considerations

The permanent message header field registry (see [RFC3864]) should be updated with the following registrations:

Content-Security-Policy

Header field name: Content-Security-Policy

Applicable protocol: http

Status: standard

Author/Change controller: W3C

Specification document: this specification (See Content-Security-Policy Header Field)

Content-Security-Policy-Report-Only

Header field name: Content-Security-Policy-Report-Only

Applicable protocol: http

Status: standard

Author/Change controller: W3C

Specification document: this specification (See Content-Security-Policy-Report-Only Header Field)