Content Security Policy Level 3

W3C First Public Working Draft,

This version:
http://www.w3.org/TR/2015/WD-CSP-3-20150119/
Latest version:
http://www.w3.org/TR/CSP3/
Editor's Draft:
https://w3c.github.io/webappsec-csp/
Version History:
https://github.com/w3c/webappsec-csp/commits/master/index.src.html
Feedback:
public-webappsec@w3.org with subject line “[CSP] … message topic …” (archives)
Editor:
(Google Inc.)
Participate:
File an issue (open issues)

Abstract

This document defines a mechanism by which web developers can control the resources which a particular page can fetch or execute, as well as a number of security-relevant policy decisions.

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Application Security Working Group as a Working Draft. This document is intended to become a W3C Recommendation.

The (archived) public mailing list public-webappsec@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “CSP” in the subject, preferably like this: “[CSP] …summary of comment…

This document is a First Public Working Draft.

Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by the Web Application Security Working Group.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

Table of Contents

1. Introduction

This section is not normative.

This document defines Content Security Policy (CSP), a tool which developers can use to lock down their applications in various ways, mitigating the risk of content injection vulnerabilities such as cross-site scripting, and reducing the privilege with which their applications execute.

CSP is not intended as a first line of defense against content injection vulnerabilities. Instead, CSP is best used as defense-in-depth. It reduces the harm that a malicious injection can cause, but it is not a replacement for careful input validation and output encoding.

This document is an iteration on Content Security Policy Level 2, with the goal of more clearly explaining the interactions between CSP, HTML, and Fetch on the one hand, and providing clear hooks for modular extensibility on the other. Ideally, this will form a stable core upon which we can build new functionality.

1.1. Examples

1.1.1. Control Execution

MegaCorp Inc’s developers want to protect themselves against cross-site scripting attacks. They can mitigate the risk of script injection by ensuring that their trusted CDN is the only origin from which script can load and execute. Moreover, they wish to ensure that no plugins can execute in their pages' contexts. The following policy has that effect:
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'

1.2. Goals

Content Security Policy aims to do to a few related things:

  1. Mitigate the risk of content-injection attacks by giving developers fairly granular control over

    • The resources which can be requested (and subsequently embedded or executed) on behalf of a specific Document or Worker

    • The execution of inline script

    • Dynamic code execution (via eval() and similar constructs)

    • The application of inline style

  2. Mitigate the risk of attacks which require a resource to be embedded in a malicious context (the "Pixel Perfect" attack described in [TIMING], for example) by giving developers granular control over the origins which can embed a given resource.

  3. Provide a policy framework which allows developers to reduce the privilege of their applications.

  4. Provide a reporting mechanism which allows developers to detect flaws being exploited in the wild.

1.3. Changes from Level 2

This document describes an evolution of the Content Security Policy Level 2 specification [CSP2]. The following is a high-level overview of the changes:

  1. The specification has been rewritten from the ground up in terms of the [FETCH] specification, which should make it simpler to integrate CSP’s requirements and restrictions with other specifications (and with Service Workers in particular).

  2. The frame-src directive, which was deprecated in CSP Level 2, has been removed.

  3. Insecure schemes in source expressions now match their secure variants. That is, http: is equivalent to http: https:, and http://a.com to http://a.com https://a.com.

    Likewise, 'self' now matches https and wss variants of the page’s origin, even on pages whose scheme is http.

  4. Violation reports generated from inline script or style will now report "inline" as the blocked resource. Likewise, blocked eval() execution will report "eval" as the blocked resource.

  5. Directives with effects on a Document or Worker itself (as opposed to the resources such a context can load) have moved out into a separate [CSP-DOCUMENT] module. This includes base-uri, form-action, frame-ancestors, plugin-types, sandbox.

  6. The manifest-src directive has been added.

  7. The report-uri directive is deprecated in favor of the new report-to directive, which relies on [OOB-REPORTING] as infrastructure.

1.4. Open Questions

  1. Do we really want to remove frame-src? Though the threat model of workers and frames is similar, they have distinct capabilities. Perhaps it makes sense for folks to allow workers while disallowing frames, or vice-versa?

  2. Can we enable sandbox inside meta? It’s not clear what threat we’re preventing by dropping support for it (and Chrome and Safari support it today).

  3. Reporting:

    1. Do we still need to strip values? I think we’ve removed much of the risk by using the original URL of a blocked resource; there shouldn’t be anything in the report JSON that script can’t gather on its own by walking the DOM.

2. Framework

2.1. Policies

A policy defines a set of allowed and restricted behaviors, and may be applied to a Window or WorkerGlobalScope as described in §4.2.2 Initialize a global object’s CSP list.

Each policy has an associated directive set, which is a set of directives that define the policy’s implications when applied.

Each policy has an associated disposition, which is either "enforce" or "report".

A serialized CSP is an ASCII string, consisting of a semicolon-delimited series of serialized directives, adhering to the following ABNF grammar [RFC5234]:

serialized-policy = serialized-directive *( OWS ";" [ OWS serialized-directive ] )
                    ; OWS is defined in section 3.2.3 of RFC 7230

2.1.1. Parse a serialized CSP as disposition

Given a serialized CSP (serialized CSP), and a disposition (disposition), this algorithm will return a policy object. If the string cannot be parsed, the resulting policy’s directive set will be empty.

  1. Let policy be a new policy with an empty directive set, and a disposition of disposition.

  2. For each token returned by strictly splitting serialized CSP on the U+003B SEMICOLON character (;):

    1. Strip leading and trailing whitespace from token.

    2. If token is an empty string, skip the remaining substeps and continue to the next item.

    3. Let directive name be the result of collecting a sequence of characters from token which are not space characters.

    4. If policy’s directive set contains a directive whose name is directive name, skip the remaining substeps and continue to the next item.

      The user agent SHOULD notify developers that a directive was ignored. A console warning might be appropriate, for example.

    5. Let directive value be the result of splitting token on spaces.

    6. Let directive be a new directive whose name is directive name, and value is directive value.

    7. Add directive to policy’s directive set.

  3. Return policy.

2.1.2. Parse a serialized CSP list as disposition

Given a string (list) and a disposition (disposition) which contains a comma-delimited series of serialized CSP strings, the following algorithm will return a list of policies:

  1. Let policies be an empty list.

  2. For each token returned by splitting list on commas:

    1. Let policy be the result of executing §2.1.1 Parse a serialized CSP as disposition on token with disposition.

    2. If policy’s directive set is empty, skip the remaining substeps, and continue to the next item.

    3. Add policy to policies.

  3. Return policies.

2.2. Directives

Policies contain a set of directives, each of which controls a specific behavior. The directives defined in this document are described in detail in §6 Content Security Policy Directives.

Each directive is a name / value pair. The name is a non-empty string, and the value is a set of non-empty strings. The value set MAY be empty.

A serialized directive is an ASCII string, consisting of one or more whitespace-delimited tokens, and adhering to the following ABNF [RFC5234]:

serialized-directive = directive-name [ RWS directive-value ]
directive-name       = 1*( ALPHA / DIGIT / "-" )
directive-value      = *( %x09 / %x20-%x2B / %x2D-%x3A / %x3C-%7E )
                       ; Directive values may contain whitespace and VCHAR characters,
                       ; excluding ";" and ","

; RWS is defined in section 3.2.3 of RFC7230. ALPHA, DIGIT, and
; VCHAR are defined in Appendix B.1 of RFC 5234.

Directives have five associated algorithms:

  1. A pre-request check, which takes a request and a policy as an argument, and is executed during §4.1.3 Should request be blocked by Content Security Policy?. This algorithm returns "Allowed" unless otherwise specified.

  2. A post-request check, which takes a request, a response, and a policy as arguments, and is executed during §4.1.4 Should response to request be blocked by Content Security Policy?. This algorithm returns "Allowed" unless otherwise specified.

  3. A response check, which takes a request, a response, and a policy as arguments, and is executed during §4.1.4 Should response to request be blocked by Content Security Policy?. This algorithm returns "Allowed" unless otherwise specified.

  4. An inline check, which takes an Element and a type string as arguments, and is executed during §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy?. This algorithm returns "Allowed" unless otherwise specified.

  5. An initialization, which takes a Document or global object, a response, and a policy as arguments. This algorithm is executed during §4.2.1 Initialize a Document's CSP list, and has no effect unless otherwise specified.

2.2.1. Source Lists

Many directives' values consist of source lists: sets of tokens which identify content that can be fetched and potentially embedded or executed. These tokens represent one of the following types of source expression:

  1. Keywords such as 'none' and 'self' (which match nothing and the current URL’s origin, respectively)

  2. Serialized URLs such as https://example.com/path/to/file.js (which matches a specific file) or https://example.com/ (which matches everything on that origin)

  3. Schemes such as https: (which matches any resource having the specified scheme)

  4. Hosts such as example.com (which matches any resource on the host, regardless of scheme) or *.example.com (which matches any resource on the host or any of its subdomains (and any of its subdomains' subdomains, and so on))

  5. Nonces such as 'nonce-qwertyu12345' (which can match specific elements on a page)

  6. Digests such as 'sha256-abcd...' (which can match specific elements on a page)

A serialized source list is an ASCII string, consisting of a space-delimited series of source expressions, adhering to the following ABNF grammar [RFC5234]:

serialized-source-list = ( source-expression *( RWS source-expression ) ) / "'none'"
source-expression      = scheme-source / host-source / keyword-source
                         / nonce-source / hash-source

; Schemes:
scheme-source = scheme ":"
                ; scheme is defined in section 3.1 of RFC 3986.

; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ port-part ] [ path-part ]
scheme-part = scheme
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char )
host-char   = ALPHA / DIGIT / "-"
port-part   = ":" ( 1*DIGIT / "*" )
path-part   = path
              ; path is defined in section 3.3 of RFC 3986.
   
; Keywords:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'" 

; Nonces: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" ) 

; Digests: 'sha256-[digest goes here]'
hash-source    = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"

The host-char production intentionally contains only ASCII characters; internationalized domain names cannot be entered directly as part of a serialized CSP, but instead MUST be Punycode-encoded [RFC3492]. For example, the domain üüüüüü.de MUST be represented as xn--tdaaaaaa.de.

Note: Though IP address do match the grammar above, only 127.0.0.1 will actually match a URL when used in a source expression (see §6.1.11.2 Does url match source list? for details). The security properties of IP addresses are suspect, and authors ought to prefer hostnames whenever possible.

A URL matches a source list if the algorithm in §6.1.11.2 Does url match source list? returns Matches.

2.3. Violations

A violation represents an action or resource which goes against the policies associated with a global object.

Each violation has a global object, which is the global object whose policy has been violated.

Each violation has a url which is its global object’s URL.

Each violation has a status which is a non-negative integer representing the HTTP status code of the resource for which the global object was instantiated.

Each violation has a resource, which is either null, "inline", "eval", or a URL. It represents the resource which violated the policy.

Each violation has a referrer, which is either null, or a URL. It represents the referrer of the resource whose policy was violated.

Each violation has a policy, which is the policy that has been violated.

Each violation has an effective directive which is a non-empty string representing the directive whose enforcement caused the violation.

Each violation has a source file, which is either null or a URL.

Each violation has a line number, which is a non-negative integer.

Each violation has a column number, which is a non-negative integer.

2.3.1. Create a violation object for global, policy, and directive

Given a global object (global), a policy (policy), and a string (directive), the following algorithm creates a new violation object, and populates it with an initial set of data:

  1. Let violation be a new violation whose global object is global, policy is policy, effective directive is directive, and resource is null.

  2. If the user agent is currently executing script, and can extract a source file’s URL, line number, and column number from the global, set violation’s source file, line number, and column number accordingly.

    Is this kind of thing specified anywhere? I didn’t see anything that looked useful in [ES2015].

  3. If global is a Window object, set violation’s referrer to global’s document's referrer.

  4. Set violation’s status to the HTTP status code for the resource associated with violation’s global object.

    How, exactly, do we get the status code? We don’t actually store it anywhere.

  5. Return violation.

2.3.2. Create a violation object for request, policy, and directive

Given a request (request), a policy (policy), and a string (directive), the following algorithm creates a new violation object, and populates it with an initial set of data:

  1. Let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on request’s client’s global object, policy, and directive.

  2. Set violation’s resource to request’s url.

    Note: We use request’s url, and not its current url, as the latter might contain information about redirect targets to which the page MUST NOT be given access.

  3. Return violation.

3. Policy Delivery

A server MAY declare a policy for a particular resource representation via an HTTP response header field whose value is a serialized CSP. This mechanism is defined in detail in §3.1 The Content-Security-Policy HTTP Response Header Field and §3.2 The Content-Security-Policy-Report-Only HTTP Response Header Field, and the integration with Fetch and HTML is described in §4.1 Integration with Fetch and §4.2 Integration with HTML.

A policy may also be declared inline in an HTML document via a meta element’s http-equiv attribute, as described in §3.3 The <meta> element.

3.1. The Content-Security-Policy HTTP Response Header Field

The Content-Security-Policy HTTP response header field is the preferred mechanism for delivering a policy from a server to a client. The header’s value is represented by the following ABNF [RFC5234]:

Content-Security-Policy = 1#serialized-policy
Content-Security-Policy: script-src 'self';
                         report-to csp-reporting-endpoint

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

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

When the user agent receives a Content-Security-Policy header field, it MUST parse and enforce each serialized CSP it contains as described in §4.1 Integration with Fetch, §4.2 Integration with HTML.

3.2. The Content-Security-Policy-Report-Only HTTP Response Header Field

The Content-Security-Policy-Report-Only HTTP response header field allows web developers to experiment with policies by monitoring (but not enforcing) their effects. The header’s value is represented by the following ABNF [RFC5234]:

Content-Security-Policy-Report-Only = 1#serialized-policy

This header field allows developers to piece together their security policy in an iterative fashion, deploying a report-only policy based on their best estimate of how their site behaves, watching for violation reports, and then moving to an enforced policy once they’ve gained confidence in that behavior.

Content-Security-Policy-Report-Only: script-src 'self';
                                     report-to csp-reporting-endpoint

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

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

When the user agent receives a Content-Security-Policy-Report-Only header field, it MUST parse and monitor each serialized CSP it contains as described in §4.1 Integration with Fetch and §4.2 Integration with HTML.

Note: The Content-Security-Policy-Report-Only header is not supported inside a meta element.

3.3. The <meta> element

A Document may deliver a policy via one or more HTML meta elements whose http-equiv attributes are an ASCII case-insensitive match for the string "Content-Security-Policy". For example:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

Implementation details can be found in HTML’s Content-Security-Policy http-equiv processing instructions [HTML].

Note: The Content-Security-Policy-Report-Only header is not supported inside a meta element. Neither are the report-uri, frame-ancestors, and sandbox directives.

Why sandbox? Can we loosen that?

Authors are strongly encouraged to place meta elements as early in the document as possible, because policies in meta elements are not applied to content which precedes them. In particular, note that resources fetched or prefetched using the Link HTTP response header field, and resources fetched or prefetched using link and script elements which precede a meta-delivered policy will not be blocked.

Note: A policy specified via a meta element will be enforced along with any other policies active for the protected resource, regardless of where they’re specified. The general impact of enforcing multiple policies is described in §8.1 The effect of multiple policies.

Note: Modifications to the content attribute of a meta element after the element has been parsed will be ignored.

4. Integrations

This section is non-normative.

This document defines a set of algorithms which are used in other specifications in order to implement the functionality. These integrations are outlined here for clarity, but those external documents are the normative references which ought to be consulted for detailed information.

4.1. Integration with Fetch

A number of directives control resource loading in one way or another. This specification provides algorithms which allow Fetch to make decisions about whether or not a particular request should be blocked or allowed, and about whether a particular response should be replaced with a network error.

  1. §4.1.3 Should request be blocked by Content Security Policy? is called as part of step #4 of its Main Fetch algorithm.

  2. §4.1.4 Should response to request be blocked by Content Security Policy? is called as part of step #12 of its Main Fetch algorithm.

A policy is generally enforced upon a global object, but the user agent needs to parse any policy delivered via an HTTP response header field before any global object is created in order to handle directives that require knowledge of a response’s details. To that end:

  1. A response has an associated CSP list which contains any policy objects delivered in the response’s header list.

  2. §4.1.1 Set response’s CSP list is called in the HTTP fetch and HTTP-network fetch algorithms.

    Note: These two calls should ensure that a response’s CSP list is set, regardless of how the response is created. If we hit the network (via HTTP-network fetch, then we parse the policy before we handle the Set-Cookie header. If we get a response from a Service Worker (via HTTP fetch, we’ll process its CSP list before handing the response back to our caller.

4.1.1. Set response’s CSP list

Given a response (response), this algorithm evaluates its header list for serialized CSP values, and populates its CSP list accordingly:

  1. Set response’s CSP list to the empty list.

  2. Let policies be the result of executing §2.1.2 Parse a serialized CSP list as disposition on the result of parsing Content-Security-Policy in response’s header list, with a disposition of "enforce".

  3. Append to policies the result of executing §2.1.2 Parse a serialized CSP list as disposition on the result of parsing Content-Security-Policy-Report-Only in response’s header list, with a disposition of "report".

  4. For each policy in policies:

    1. Insert policy into response’s CSP list.

4.1.2. Report Content Security Policy violations for request

Given a request (request), this algorithm reports violations based on client’s "report only" policies.

  1. Let CSP list be request’s client’s global object’s CSP list.

  2. For each policy in CSP list:

    1. If policy’s disposition is "enforce", then skip to the next policy.

    2. Let violates be the result of executing §6.1.11.1 Does request violate policy? on request and policy.

    3. If violates is not "Does Not Violate", then execute §5.3 Report a violation on the result of executing §2.3.2 Create a violation object for request, policy, and directive on request, policy, and violates.

4.1.3. Should request be blocked by Content Security Policy?

Given a request (request), this algorithm returns Blocked or Allowed and reports violations based on request’s client’s Content Security Policy.

  1. Let CSP list be request’s client’s global object’s CSP list.

  2. Let result be "Allowed".

  3. For each policy in CSP list:

    1. If policy’s disposition is "report", then skip to the next policy.

    2. Let violates be the result of executing §6.1.11.1 Does request violate policy? on request and policy.

    3. If violates is not "Does Not Violate", then:

      1. Execute §5.3 Report a violation on the result of executing §2.3.2 Create a violation object for request, policy, and directive on request, policy, and violates.

      2. Set result to "Blocked".

  4. Return result.

4.1.4. Should response to request be blocked by Content Security Policy?

Given a response (response) and a request (request), this algorithm returns Blocked or Allowed, and reports violations based on request’s client’s Content Security Policy.

  1. Let CSP list be request’s client’s global object’s CSP list.

  2. Let result be "Allowed".

  3. For each policy in CSP list:

    1. For each directive in policy:

      1. If the result of executing directive’s post-request check is "Blocked", then:

        1. Execute §5.3 Report a violation on the result of executing §2.3.2 Create a violation object for request, policy, and directive on request, policy, and directive.

        2. If policy’s disposition is "enforce", then set result to "Blocked".

    Note: This portion of the check verifies that the page can load the response. That is, that a Service Worker hasn’t substituted a file which would violated the page’s CSP.

  4. For each policy in response’s CSP list:

    1. For each directive in policy:

      1. If the result of executing directive’s response check on request, response, and policy is "Blocked", then:

        1. Execute §5.3 Report a violation on the result of executing §2.3.2 Create a violation object for request, policy, and directive on request, policy, and directive.

        2. If policy’s disposition is "enforce", then set result to "Blocked".

    Note: This portion of the check allows policies delivered with the response to determine whether the response is allowed to be delivered.

  5. Return result.

4.2. Integration with HTML

  1. The Document and WorkerGlobalScope objects have a CSP list, which holds all the policy objects which are active for a given context. This list is empty unless otherwise specified, and is populated via the §4.2.2 Initialize a global object’s CSP list algorithm.

  2. A policy is enforced or monitored for an global object by inserting it into the global object’s CSP list.

  3. §4.2.2 Initialize a global object’s CSP list is called during the initialising a new Document object and run a worker algorithms in order to bind a set of policy objects associated with a response to a newly created global object.

    The algorithm is named "creating a new Document object" in W3C’s HTML, and isn’t well-integrated with Fetch.

    Need to monkey-patch these in: something like "Set the Window object’s CSP list to the CSP list of the resource used to generate the document.

  4. §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? is called during the prepare a script and update a style block algorithms in order to determine whether or not an inline script or style block is allowed to execute/render.

    The update a style block algorithm does not exist in W3C’s HTML.

    The nonce attribute for script and style were added to WHATWG’s HTML in whatwg/html@882803c. They have not yet been added to W3C’s HTML.

    The §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? hooks were added to WHATWG’s HTML in whatwg/html@ee3486e. They aren’t yet in W3C’s HTML.

  5. §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? is called during handling of inline event handlers (like onclick) and inline style attributes in order to determine whether or not they ought to be allowed to execute/render.

    This hook is in-flight for WHATWG’s HTML. <https://github.com/WHATWG/html/issues/384>

  6. Policies are enforced during processing of the meta element’s http-equiv.

    This processing was added to WHATWG’s HTML in whatwg/html@5064a62. It has not yet been added to W3C’s HTML.

  7. A Document's embedding document is the Document through which the Document's browsing context is nested.

4.2.1. Initialize a Document's CSP list

Given a Document (document), and a response (response), the user agent performs the following steps in order to initialize document’s CSP list:

  1. If response’s url’s scheme is a local scheme:

    1. Let documents be an empty list.

    2. If document has an embedding document (embedding), then add embedding to documents.

    3. If document has an opener browsing context, then add its active document to documents.

    4. For each doc in documents:

      1. For each policy in doc’s CSP list:

        1. Insert an alias to policy in document’s CSP list.

    Note: local scheme includes about:, and this algorithm will therefore alias the embedding document’s policies for an iframe srcdoc Document.

    Note: We do all this to ensure that a page cannot bypass its policy by embedding a frame or popping up a new window containing content it controls (blob: resources, or document.write()).

  2. For each policy in response’s CSP list, insert policy into document’s CSP list.

  3. For each policy in document’s CSP list:

    1. For each directive in policy:

      1. Execute directive’s initialization algorithm on document and response.

4.2.2. Initialize a global object’s CSP list

Given a global object (global), and a response (response), the user agent performs the following steps in order to initialize global’s CSP list:

  1. If response’s url’s scheme is a local scheme:

    1. Let documents be an empty list.

    2. Add each of global’s documents to documents.

    3. For each document in documents:

      1. For each policy in document’s global object’s CSP list:

        1. Insert an alias to policy in global’s CSP list.

    Note: local scheme includes about:, and this algorithm will therefore alias the embedding document’s policies for an iframe srcdoc Document.

  2. For each policy in response’s CSP list, insert policy into global’s CSP list.

4.2.3. Should element’s inline type behavior be blocked by Content Security Policy?

Given an Element (element), and a string (type) this algorithm returns "Allowed" if the element is allowed to have inline definition of a particular type of behavior (script execution, style application, event handlers, etc.), and "Blocked" otherwise:

  1. Let result be "Allowed".

  2. For each policy in element’s Document's global object’s CSP list:

    1. For each directive in policy:

      1. If directive’s inline check returns "Allowed" when executed upon element and type, skip to the next directive.

      2. Otherwise, let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on the incumbent settings object, policy, and "style-src" if type is "style" or "style-attribute", or "script-src" otherwise.

      3. Set violation’s resource to "inline".

      4. Execute §5.3 Report a violation on violation.

      5. If policy’s disposition is "enforce", then set result to "Blocked".

  3. Return result.

5. Reporting

When one or more of a policy’s directives is violated, a violation report may be generated and sent out to a reporting endpoint associated with the policy.

5.1. Violation DOM Events

[Constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict)]
interface SecurityPolicyViolationEvent : Event {
    readonly    attribute DOMString documentURI;
    readonly    attribute DOMString referrer;
    readonly    attribute DOMString blockedURI;
    readonly    attribute DOMString violatedDirective;
    readonly    attribute DOMString effectiveDirective;
    readonly    attribute DOMString originalPolicy;
    readonly    attribute DOMString sourceFile;
    readonly    attribute DOMString statusCode;
    readonly    attribute long      lineNumber;
    readonly    attribute long      columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    DOMString documentURI;
    DOMString referrer;
    DOMString blockedURI;
    DOMString violatedDirective;
    DOMString effectiveDirective;
    DOMString originalPolicy;
    DOMString sourceFile;
    long      lineNumber;
    long      columnNumber;
};

5.2. Obtain the deprecated serialization of violation

Given a violation (violation), this algorithm returns a JSON text string representation of the violation, suitable for submission to a reporting endpoint associated with the deprecated report-uri directive.

  1. Let object be a new JavaScript object with properties initialized as follows:

    "document-uri"

    The result of executing the URL serializer on violation’s url, with the exclude fragment flag set.

    "referrer"

    The result of executing the URL serializer on violation’s referrer, with the exclude fragment flag set.

    "blocked-uri"

    The result of executing the URL serializer on violation’s resource, with the exclude fragment flag set.

    "effective-directive"

    violation’s effective directive

    "violated-directive"

    violation’s effective directive

    "original-policy"

    The serialization of violation’s policy

    "status-code"

    violation’s status

  2. If violation’s source file is not null:

    1. Set object’s "source-file" property to the result of executing the URL serializer on violation’s source file, with the exclude fragment flag set.

    2. Set object’s "line-number" property to violation’s line number.

    3. Set object’s "column-number" property to violation’s column number.

  3. Return the result of executing JSON.stringify() on object.

5.3. Report a violation

Given a violation (violation), this algorithm reports it to the endpoint specified in violation’s policy, and fires a SecurityPolicyViolationEvent at violation’s global object.

  1. Fire a trusted event with the name securitypolicyviolation that uses the SecurityPolicyViolationEvent interface, with its attributes initialized as follows:

    documentURI

    violation’s url

    referrer

    violation’s referrer

    blockedURI

    violation’s resource

    effectiveDirective

    violation’s effective directive

    violatedDirective

    violation’s effective directive

    originalPolicy

    violation’s policy

    sourceFile

    violation’s source file

    statusCode

    violation’s status

    lineNumber

    violation’s line number

    columnNumber

    violation’s column number

    Note: Both effectiveDirective and violatedDirective are the same value. This is intentional to maintain backwards compatibility.

  2. If violation’s policy’s directive set contains a directive named "report-uri" (directive):

    1. If violation’s policy’s directive set contains a directive named "report-to", skip the remaining substeps.

    2. Let endpoint be the result of executing the URL parser on directive’s value.

    3. If endpoint is not a valid URL, skip the remaining substeps.

    4. Let request be a new request, initialized as follows:

      method

      "POST"

      url

      violation’s url

      origin

      violation’s global object’s origin

      window

      "no-window"

      client

      violation’s global object’s relevant settings object

      destination

      ""

      initiator

      ""

      type

      ""

      cache mode

      "no-cache"

      credentials mode

      "same-origin"

      header list

      A header list containing a single header whose name is "Content-Type", and value is "application/csp-report"

      body

      The result of executing §5.2 Obtain the deprecated serialization of violation on violation

      redirect mode

      "error"

    5. Fetch request. The result will be ignored.

    Note: All of this should be considered deprecated. It sends a single request per violation, which simply isn’t scalable. As soon as this behavior can be removed from user agents, it will be.

    Note: report-uri only takes effect if report-to is not present. That' is, the latter overrides the former, allowing for backwards compatibility with browsers that don’t support the new mechanism.

  3. If violation’s policy’s directive set contains a directive named "report-to" (directive):

    1. Let group be directive’s value.

    2. Let settings object be violation’s global object’s relevant settings object.

    3. Execute [OOB-REPORTING]'s Queue data as type for endpoint group on settings algorithm with the following arguments:

      data

      violation

      type

      "CSP"

      endpoint group

      group

      settings

      settings object

6. Content Security Policy Directives

This specification defines a number of types of directives which allow developers to control certain aspects of their sites' behavior. This document defines directives which govern resource fetching (in §6.1 Fetch Directives) and directives which govern reporting (in §6.2 Reporting Directives). These form the core of Content Security Policy; other directives are defined in a modular fashion in ancillary documents (see §6.3 Directives Defined in Other Documents for examples).

To mitigate the risk of cross-site scripting attacks, web developers SHOULD include directives that regulate sources of script and plugins. They can do so by including:

In either case, developers 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.

6.1. Fetch Directives

Fetch directives control the locations from which certain resource types may be loaded. For instance, script-src allows developers to whitelist trusted sources of script to execute on a page, while font-src controls the sources of web fonts.

6.1.1. child-src

The child-src directive governs the creation of nested browsing contexts (e.g. iframe and frame navigations) and Worker execution contexts. The syntax for the directive’s name and value is described by the following ABNF:

directive-name  = "child-src"
directive-value = serialized-source-list

This directive controls requests which will populate a frame or a worker. More formally, requests falling into one of the following categories:

Given a page with the following Content Security Policy:
Content-Security-Policy: child-src https://example.com/

Fetches for the following code will all return network errors, as the URLs provided do not match child-src's source list:

<iframe src="https://not-example.com"></iframe>
<script>
  var blockedWorker = new Worker("data:application/javascript,...");
</script>
6.1.1.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request):

TODO.

This directive’s post-request check is as follows:

TODO.

6.1.2. connect-src

The connect-src directive restricts the URLs which can be loaded using script interfaces. The syntax for the directive’s name and value is described by the following ABNF:

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

This directive controls requests which transmit or receive data from other origins. This includes APIs like fetch(), [XHR], [EVENTSOURCE], [BEACON], and a's ping. This directive also controls WebSocket [WEBSOCKETS] connections, though those aren’t technically part of Fetch.

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 and similar 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 https://example.com, send the following header:

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

Fetches for the following code will all return network errors, as the URLs provided do not match connect-src's source list:

<a ping="https://not-example.com">...
<script>
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://not-example.com/');
  xhr.send();

  var ws = new WebSocket("https://not-example.com/");
        
  var es = new EventSource("https://not-example.com/");

  navigator.sendBeacon("https://not-example.com/", { ... });
</script>
6.1.2.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s initiator is "fetch", or its type is "" and destination is "subresource":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s initiator is "fetch", or its type is "" and destination is "subresource":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

6.1.3. default-src

The default-src directive serves as a fallback for the other fetch directives. The syntax for the directive’s name and value is described by the following ABNF:

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

If a default-src directive is present in a policy, its value will be used as the policy’s default source list. That is, given default-src 'none'; script-src 'self', script requests will use 'self' as the source list to match against. Other requests will use 'none'. This is spelled out in more detail in the §4.1.3 Should request be blocked by Content Security Policy? and §4.1.4 Should response to request be blocked by Content Security Policy? algorithms.

The following header:
Content-Security-Policy: default-src 'self'

will have the same behavior as the following header:

Content-Security-Policy: child-src 'self';
                         connect-src 'self';
                         font-src 'self';
                         img-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src 'self';
                         style-src 'self'

That is, when default-src is set, every fetch directive that isn’t explicitly set will fall back to the value default-src specifies.

There is no inheritance. If a script-src directive is explicitly specified, for example, then the value of default-src has no influence on script requests. That is, the following header:
Content-Security-Policy: default-src 'self'; script-src https://example.com

will have the same behavior as the following header:

Content-Security-Policy: child-src 'self';
                         connect-src 'self';
                         font-src 'self';
                         img-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src https://example.com;
                         style-src 'self'

Given this behavior, one good way to build a policy for a site would be to begin with a default-src of 'none', and to build up a policy from there which allowed only those resource types which are necessary for the particular page the policy will apply to.

6.1.3.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. Let name be the result of executing §6.1.11.4 Get the effective directive for request on request.

  2. If name is null, return "Allowed".

  3. If policy contains a directive whose name is name, return "Allowed".

  4. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  5. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. Let name be the result of executing §6.1.11.4 Get the effective directive for request on request.

  2. If name is null, return "Allowed".

  3. If policy contains a directive whose name is name, return "Allowed".

  4. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  5. Return "Allowed".

6.1.4. font-src

The font-src directive restricts the URLs from which font resources may be loaded. The syntax for the directive’s name and value is described by the following ABNF:

directive-name  = "font-src"
directive-value = serialized-source-list
Given a page with the following Content Security Policy:
Content-Security-Policy: font-src https://example.com/

Fetches for the following code will return a network errors, as the URL provided do not match font-src's source list:

<style>
  @font-face {
    font-family: "Example Font";
    src: url("https://not-example.com/font");
  }
  body {
    font-family: "Example Font";
  }
</style>
6.1.4.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is "font":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is "font":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

6.1.5. img-src

The img-src directive restricts the URLs from which image resources may be loaded. The syntax for the directive’s name and value is described by the following ABNF:

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

This directive controls requests which load images. More formally, this includes requests whose type is "image" [FETCH].

Given a page with the following Content Security Policy:
Content-Security-Policy: img-src https://example.com/

Fetches for the following code will return a network errors, as the URL provided do not match img-src's source list:

<img src="https://not-example.com/img">
6.1.5.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is "image":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is "image":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

6.1.6. manifest-src

The manifest-src directive restricts the URLs from which application manifests may be loaded [APPMANIFEST]. The syntax for the directive’s name and value is described by the following ABNF:

directive-name  = "manifest-src"
directive-value = serialized-source-list
Given a page with the following Content Security Policy:
Content-Security-Policy: manifest-src https://example.com/

Fetches for the following code will return a network errors, as the URL provided do not match manifest-src's source list:

<link rel="manifest" href="https://not-example.com/manifest">
6.1.6.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is "", and its initiator is "manifest":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is "", and its initiator is "manifest":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

6.1.7. media-src

The media-src directive restricts the URLs from which video, audio, and associated text track resources may be loaded. The syntax for the directive’s name and value is described by the following ABNF:

directive-name  = "media-src"
directive-value = serialized-source-list
Given a page with the following Content Security Policy:
Content-Security-Policy: media-src https://example.com/

Fetches for the following code will return a network errors, as the URL provided do not match media-src's source list:

<audio src="https://not-example.com/audio"></audio>
<video src="https://not-example.com/video">
    <track kind="subtitles" src="https://not-example.com/subtitles">
</video>
6.1.7.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is one of "audio", "video", or "track":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is one of "audio", "video", or "track":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

6.1.8. object-src

The object-src directive restricts the URLs from which plugin content may be loaded. The syntax for the directive’s name and value is described by the following ABNF:

directive-name  = "object-src"
directive-value = serialized-source-list
Given a page with the following Content Security Policy:
Content-Security-Policy: object-src https://example.com/

Fetches for the following code will return a network errors, as the URL provided do not match object-src's source list:

<embed src="https://not-example.com/flash"></embed>
<object data="https://not-example.com/flash"></object>
<applet archive="https://not-example.com/flash"></applet>

If plugin content is loaded without an associated URL (perhaps an object element lacks a data attribute, but loads some default plugin based on the specified type), it MUST be blocked if object-src's value is 'none', but will otherwise be allowed.

Note: The object-src directive acts upon any request made on behalf of an object, embed, or applet element. This includes requests which would populate the nested browsing context generated by the former two (also including navigations). This is true even when the data is semantically equivalent to content which would otherwise be restricted by another directive, such as an object element with a text/html MIME type.

6.1.8.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is "", and its destination is "unknown":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is "", and its destination is "unknown":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

6.1.9. script-src

The script-src directive restricts the locations from which scripts may be executed. This includes not only URLs loaded directly into script elements, but also things like inline script blocks and XSLT stylesheets [XSLT] which can trigger script execution. The syntax for the directive’s name and value is described by the following ABNF:

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

The script-src directive governs four things:

  1. Script requests MUST pass through §4.1.3 Should request be blocked by Content Security Policy?.

  2. Script responses MUST pass through §4.1.4 Should response to request be blocked by Content Security Policy?.

  3. Inline script blocks MUST pass through §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy?. Their behavior will be blocked unless every policy allows inline script, either implicitly by not specifying a script-src (or default-src) directive, or explicitly, by whitelisting "unsafe-inline", a nonce-source or a hash-source that matches the inline block.

  4. The following JavaScript execution sinks are gated on the "unsafe-eval" source expression:

    Note: If a user agent implements non-standard sinks like setImmediate() or execScript(), they SHOULD also be gated on "unsafe-eval".

6.1.9.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is "script", and its destination is "subresource":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is "script", and its destination is "subresource":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s inline check algorithm is as follows:

Given an Element (element) and a string (type):

  1. If type is "script" or "script attribute":

    1. If the result of executing §6.1.12.1 Does element match source list? on element, this directive’s value, and type is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s initialization algorithm is as follows:

Do something interesting to the execution context in order to lock down eval(), et al. I don’t think ECMA gives us any hooks here, so let’s work with them to put something reasonable together.

6.1.10. style-src

The style-src directive restricts the locations from which style may be applied to a Document. The syntax for the directive’s name and value is described by the following ABNF:

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

The style-src directive governs several things:

  1. Style requests MUST pass through §4.1.3 Should request be blocked by Content Security Policy?. This includes:

    1. Stylesheet requests originating from a link element.

    2. Stylesheet requests originating from the @import rule.

    3. Stylesheet requests originating from a Link HTTP response header field [RFC5988].

  2. Responses to style requests MUST pass through §4.1.4 Should response to request be blocked by Content Security Policy?.

  3. Inline style blocks MUST pass through §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy?. The styles will be blocked unless every policy allows inline style, either implicitly by not specifying a script-src (or default-src) directive, or explicitly, by whitelisting "unsafe-inline", a nonce-source or a hash-source that matches the inline block.

  4. The following CSS algorithms are gated on the unsafe-eval source expression:

    1. insert a CSS rule

    2. parse a CSS rule,

    3. parse a CSS declaration block

    4. parse a group of selectors

    This would include, for example, all invocations of CSSOM’s various cssText setters and insertRule methods [CSSOM] [HTML5].

    This needs to be better explained.

6.1.10.1. Algorithms

This directive’s pre-request check is as follows:

Given a request (request) and a policy (policy):

  1. If request’s type is "style":

    1. If the result of executing §6.1.11.2 Does url match source list? on request’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s post-request check is as follows:

Given a request (request), a response (response), and a policy (policy):

  1. If request’s type is "style":

    1. If the result of executing §6.1.11.2 Does url match source list? on response’s url and this directive’s value is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s inline check algorithm is as follows:

Given an Element (element) and a string (type):

  1. If type is "style" or "style attribute":

    1. If the result of executing §6.1.12.1 Does element match source list? on element, this directive’s value, and type is "Does Not Match", return "Blocked".

  2. Return "Allowed".

This directive’s initialization algorithm is as follows:

Do something interesting to the execution context in order to lock down interesting CSSOM algorithms. I don’t think CSSOM gives us any hooks here, so let’s work with them to put something reasonable together.

6.1.11. URL Matching Algorithms

6.1.11.1. Does request violate policy?

Given a request (request) and a policy (policy), this algorithm returns the violated directive if the request violates the policy, and "Does Not Violate" otherwise.

  1. Let violates be "Does Not Violate".

  2. For each directive in policy:

    1. Let result be the result of executing directive’s pre-request check on request and policy.

    2. If result is "Blocked", then let violates be directive.

  3. Return violates.

6.1.11.2. Does url match source list?

Given a URL (url), and a source list (source list), this algorithm returns "Matches" if the URL matches one or more source expressions in source list, or "Does Not Match" otherwise:

  1. If source list is null, return "Matches".

  2. If source list contains a single item which is a case-sensitive match for the string "'none'", return "Does Not Match".

  3. For each expression in source list:

    1. If §6.1.11.3 Does url match expression in origin with redirect count? returns "Matches" when executed upon url and expression, return "Matches".

  4. Return "Does Not Match".

6.1.11.3. Does url match expression in origin with redirect count?

Given a URL (url), a source expression (expression), an origin (origin), and a number (redirect count), this algorithm returns "Matches" if url matches expression, and "Does Not Match" otherwise.

Note: origin is the origin of the resource relative to which the expression should be resolved. "'self'", for instance, will have distinct meaning depending on that bit of context.

  1. If expression is the string "*", and url’s scheme is not a local scheme, return "Matches".

  2. If expression matches the scheme-source or host-source grammar:

    1. If expression has a scheme-part that is not an ASCII case-insensitive match for url’s scheme, then return "Does Not Match" unless one of the following conditions is met:

      1. expression’s scheme-part is an ASCII case-insensitive match for "http" and url’s scheme is "https"

      2. expression’s scheme-part is an ASCII case-insensitive match for "ws" and url’s scheme is "wss"

    2. If expression matches the scheme-source grammar, return "Matches".

    Note: This logic effectively means that script-src http: is equivalent to script-src http: https:, and script-src http://example.com/ is equivalent to script-src http://example.com https://example.com. In short, we always allow a secure upgrade from an explicitly insecure expression.

  3. If expression matches the host-source grammar:

    1. If url’s host is null, return "Does Not Match".

    2. If expression does not have a scheme-part, then return "Does Not Match" unless one of the following conditions is met:

      1. origin’s scheme is url’s scheme

      2. origin’s scheme is "http", and url’s scheme one of "https", "ws", or "wss".

      3. origin’s scheme is "https", and url’s scheme is "wss".

      Note: As with scheme-part above, we allow schemeless host-source expressions to be upgraded from insecure schemes to secure schemes.

    3. If the first character of expression’s host-part is an U+002A ASTERISK character (*):

      1. Let remaining be the result of removing the leading "*" from expression.

      2. If remaining (including the leading U+002E FULL STOP character (.)) is not an ASCII case-insensitive match for the rightmost characters of url’s host, then return "Does Not Match".

    4. If the first character of expression’s host-part is not an U+002A ASTERISK character (*), and url’s host is not an ASCII case-insensitive match for expression’s host-part, return "Does Not Match".

    5. If expression’s host-part matches the IPv4address rule from [RFC3986], and is not "127.0.0.1"; or if expression’s host-part is an IPv6 address, return "Does Not Match".

      Note: A future version of this specification may allow literal IPv6 and IPv4 addresses, depending on usage and demand. Given the weak security properties of IP addresses in relation to named hosts, however, authors are encouraged to prefer the latter whenever possible.

    6. If expression does not contain a port-part, and url’s port is not the default port for url’s scheme, return "Does Not Match".

    7. If expression does contain a port-part:

      1. If expression’s port-part is not "*", and is not the same number as url’s port, return "Does Not Match".

    8. If expression contains a non-empty path-part, and redirect count is 0, then:

      1. Let exact match be false if the final character of expression’s path-part is the U+002F SOLIDUS character (/), and true otherwise.

      2. Let path list be the result of strictly splitting expression’s path-part on the U+002F SOLIDUS character (/).

      3. If path list has more items than url’s path, return "Does Not Match".

      4. If exact match is true, and path list does not have the same number of items as url’s path, return "Does Not Match".

      5. For each expression piece in path list:

        1. Let url piece be the next item in url’s path.

        2. Percent decode expression piece.

        3. Percent decode url piece.

        4. If expression piece is not an ASCII case-insensitive match for url piece, return "Does Not Match".

    9. Return "Matches".

  4. If expression is an ASCII case-insensitive match for "'self'", return "Matches" if one or more of the following conditions is met:

    1. origin is the same as url’s origin

    2. origin’s host is the same as url’s host, origin’s port and url’s {{URL/port} are either the same or the default ports for their respective schemes, and one or more of the following conditions is met:

      1. url’s scheme is "https" or "wss"

      2. origin’s scheme is "http"

    Note: Like the scheme-part logic above, the "'self'" matching algorithm allows upgrades to secure schemes when it is safe to do so. We limit these upgrades to endpoints running on the default port for a particular scheme or a port that matches the origin of the protected resource, as this seems sufficient to deal with upgrades that can be reasonably expected to succeed.

  5. Return "Does Not Match".

6.1.11.4. Get the effective directive for request

Each fetch directive controls a specific type of request. Given a request (request), the following algorithm returns either null or the name of the request’s effective directive:

  1. Switch on request’s type, and execute the associated steps:

    ""

    1. If the request’s initiator is "fetch", return connect-src.

    2. If the request’s initiator is "manifest", return manifest-src.

    3. If the request’s destination is "subresource", return connect-src.

    4. If the request’s destination is "unknown", return object-src.

    5. If the request’s destination is "document" and the request’s target browsing context is a nested browsing context, return child-src.

    "audio"

    "track"

    "video"

    1. Return media-src.

    "font"

    1. Return font-src.

    "image"

    1. Return image-src.

    "style"

    1. Return style-src.

    "script"

    1. Switch on request’s destination, and execute the associated steps:

      "subresource"

      1. Return script-src.

      "serviceworker"

      "sharedworker"

      "worker"

      1. Return child-src.

  2. Return null.

6.1.12. Element Matching Algorithms

6.1.12.1. Does element match source list?

Given an Element (element), a source list (list), and a string (type), this algorithm returns "Matches" or "Does Not Match".

  1. Let contains nonce or hash be false.

  2. For each expression in list:

    1. If expression matches the nonce-source or hash-source grammar, set contains nonce or hash to true.

  3. If contains nonce or hash is false, and list contains a source expression which is a case-sensitive match for the string "unsafe-inline", then return "Matches".

  4. If type is not "script attribute" or "style attribute":

    1. Let content be the script block’s source if element is a script element, or the value of element’s textContent IDL attribute for any other element.

    2. For each expression in list:

      1. If expression matches the nonce-source grammar, and element has a nonce attribute whose value is a case-sensitive match for expression’s base64-value part, return "Matches".

      2. If expression matches the hash-source grammar:

        1. Let algorithm be null.

        2. If expression’s hash-algorithm part is an ASCII case-insensitive match for "sha256", set algorithm to SHA-256.

        3. If expression’s hash-algorithm part is an ASCII case-insensitive match for "sha384", set algorithm to SHA-384.

        4. If expression’s hash-algorithm part is an ASCII case-insensitive match for "sha512", set algorithm to SHA-512.

        5. If algorithm is not null:

          1. Let actual be the result of base64 encoding the result of applying algorithm to content.

          2. If actual is a case-sensitive match for expression’s base64-value part, return "Matches".

  5. Return "Does Not Match".

6.2. Reporting Directives

Various algorithms in this document hook into the reporting process by constructing a violation object via §2.3.2 Create a violation object for request, policy, and directive or §2.3.1 Create a violation object for global, policy, and directive, and passing that object to §5.3 Report a violation to deliver the report.

6.2.1. report-uri

Note: The report-uri directive is deprecated. Please use the report-to directive instead. If the latter directive is present, this directive will be ignored. To ensure backwards compatibility, we suggest specifying both, like this:
Content-Security-Policy: ...; report-uri https://endpoint.com; report-to groupname

The report-uri directive defines a set of endpoints to which violation reports will be sent when particular behaviors are prevented.

directive-name  = "report-uri"
directive-value = uri-reference *( RWS uri-reference )

; The uri-reference grammar is defined in Section 4.1 of RFC 3986.

The directive has no effect in and of itself, but only gains meaning in combination with other directives.

6.2.2. report-to

The report-to directive defines a reporting group to which violation reports ought to be sent [OOB-REPORTING]. The directive’s behavior is defined in §5.3 Report a violation. The directive’s name and value are described by the following ABNF:

directive-name  = "report-to"
directive-value = token

6.3. Directives Defined in Other Documents

This document defines a core set of directives, and sets up a framework for modular extension by other specifications. At the time this document was produced, the following stable documents extend CSP:

Extensions to CSP MUST register themselves via the process outlined in draft-west-webappsec-csp-reg. In particular, note the criteria discussed in Section 3.2 of that document.

New directives SHOULD use the pre-request check, post-request check, response check, and initialization hooks in order to integrate themselves into Fetch and HTML.

7. Security Considerations

7.1. Nonce Reuse

Nonces override the other restrictions present in the directive in which they’re delivered. It is critical, then, that they remain unguessable, as bypassing a resource’s policy is otherwise trivial.

If a server delivers a nonce-source expression as part of a policy, the server MUST generate a unique value each time it transmits a policy. The generated value SHOULD be at least 128 bits long (before encoding), and SHOULD be generated via a cryptographically secure random number generator in order to ensure that the value is difficult for an attacker to predict.

Note: Using a nonce to whitelist inline script or style is less secure than not using a nonce, as nonces override the restrictions in the directive in which they are present. An attacker who can gain access to the nonce can execute whatever script they like, whenever they like. That said, nonces provide a substantial improvement over 'unsafe-inline' when layering a content security policy on top of old code. When considering 'unsafe-inline', authors are encouraged to consider nonces (or hashes) instead.

8. Authoring Considerations

8.1. The effect of multiple policies

This section is not normative.

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.

9. Implementation Considerations

9.1. Vendor-specific Extensions and Addons

Policy enforced on a resource SHOULD NOT interfere with the operation of user-agent features like addons, extensions, or bookmarklets. These kinds of features generally advance the user’s priority over page authors, as espoused in [HTML-DESIGN].

Moreover, applying CSP to these kinds of features produces a substantial amount of noise in violation reports, significantly reducing their value to developers.

Chrome, for example, excludes the chrome-extension: scheme from CSP checks, and does some work to ensure that extension-driven injections are allowed, regardless of a page’s policy.

10. IANA Considerations

The permanent message header field registry should be updated with the following registration: [RFC3864]

10.1. Content-Security-Policy

Header field name
Content-Security-Policy
Applicable protocol
http
Status
standard
Author/Change controller
W3C
Specification document
This specification (See §3.1 The Content-Security-Policy HTTP Response Header Field)

11. Acknowledgements

Lots of people are awesome.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words "for example" or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word "Note" and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

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.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[ES2015]
Allen Wirfs-Brock. ECMAScript® 2015 Language Specification. URL: http://www.ecma-international.org/ecma-262/6.0/index.html
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Ian Hickson. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[OOB-REPORTING]
Ilya Gregorik; Mike West. Out-of-band Reporting. URL: https://mikewest.github.io/error-reporting/
[SHA2]
FIPS PUB 180-4, Secure Hash Standard. URL: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr.. CSS Cascading and Inheritance Level 4. 8 September 2015. WD. URL: http://www.w3.org/TR/css-cascade-4/
[CSSOM]
Simon Pieters; Glenn Adams. CSS Object Model (CSSOM). 5 December 2013. WD. URL: http://www.w3.org/TR/cssom/
[DOM]
Anne van Kesteren; et al. W3C DOM4. 19 November 2015. REC. URL: http://www.w3.org/TR/dom/
[DOM-LS]
Document Object Model URL: https://dom.spec.whatwg.org/
[HTML5]
Ian Hickson; et al. HTML5. 28 October 2014. REC. URL: http://www.w3.org/TR/html5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC3492]
A. Costello. Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA). March 2003. Proposed Standard. URL: https://tools.ietf.org/html/rfc3492
[RFC3864]
G. Klyne; M. Nottingham; J. Mogul. Registration Procedures for Message Header Fields. September 2004. Best Current Practice. URL: https://tools.ietf.org/html/rfc3864
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
[RFC4648]
S. Josefsson. The Base16, Base32, and Base64 Data Encodings. October 2006. Proposed Standard. URL: https://tools.ietf.org/html/rfc4648
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. January 2008. Internet Standard. URL: https://tools.ietf.org/html/rfc5234
[RFC5988]
M. Nottingham. Web Linking. October 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
[RFC6454]
A. Barth. The Web Origin Concept. December 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6454
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7230
[RFC7231]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7231
[SERVICE-WORKERS]
Alex Russell; Jungkee Song; Jake Archibald. Service Workers. 25 June 2015. WD. URL: http://www.w3.org/TR/service-workers/
[URL]
Anne van Kesteren; Sam Ruby. URL. 9 December 2014. WD. URL: http://www.w3.org/TR/url-1/
[WORKERS]
Ian Hickson. Web Workers. 24 September 2015. WD. URL: http://www.w3.org/TR/workers/

Informative References

[CSP-DOCUMENT]
Mike West. Content Security Policy: Document Features. URL: https://w3c.github.io/webappsec-csp/document/
[CSP2]
Mike West; Adam Barth; Daniel Veditz. Content Security Policy Level 2. 21 July 2015. CR. URL: http://www.w3.org/TR/CSP2/
[HTML-DESIGN]
Anne Van Kesteren; Maciej Stachowiak. HTML Design Principles. URL: http://www.w3.org/TR/html-design-principles/
[MIX]
Mike West. Mixed Content. 8 October 2015. CR. URL: http://www.w3.org/TR/mixed-content/
[TIMING]
Paul Stone. Pixel Perfect Timing Attacks with HTML5. URL: http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/
[APPMANIFEST]
Marcos Caceres; et al. Web App Manifest. 15 December 2015. WD. URL: http://www.w3.org/TR/appmanifest/
[BEACON]
Ilya Grigorik; et al. Beacon. 9 December 2015. WD. URL: http://www.w3.org/TR/beacon/
[EVENTSOURCE]
Ian Hickson. Server-Sent Events. 3 February 2015. REC. URL: http://www.w3.org/TR/eventsource/
[UPGRADE-INSECURE-REQUESTS]
Mike West. Upgrade Insecure Requests. 8 October 2015. CR. URL: http://www.w3.org/TR/upgrade-insecure-requests/
[WEBSOCKETS]
Ian Hickson. The WebSocket API. 20 September 2012. CR. URL: http://www.w3.org/TR/websockets/
[XSLT]
James Clark. XSL Transformations (XSLT) Version 1.0. 16 November 1999. REC. URL: http://www.w3.org/TR/xslt

IDL Index

[Constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict)]
interface SecurityPolicyViolationEvent : Event {
    readonly    attribute DOMString documentURI;
    readonly    attribute DOMString referrer;
    readonly    attribute DOMString blockedURI;
    readonly    attribute DOMString violatedDirective;
    readonly    attribute DOMString effectiveDirective;
    readonly    attribute DOMString originalPolicy;
    readonly    attribute DOMString sourceFile;
    readonly    attribute DOMString statusCode;
    readonly    attribute long      lineNumber;
    readonly    attribute long      columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    DOMString documentURI;
    DOMString referrer;
    DOMString blockedURI;
    DOMString violatedDirective;
    DOMString effectiveDirective;
    DOMString originalPolicy;
    DOMString sourceFile;
    long      lineNumber;
    long      columnNumber;
};

Issues Index

Is this kind of thing specified anywhere? I didn’t see anything that looked useful in [ES2015].
How, exactly, do we get the status code? We don’t actually store it anywhere.
Why sandbox? Can we loosen that?
The algorithm is named "creating a new Document object" in W3C’s HTML, and isn’t well-integrated with Fetch.
Need to monkey-patch these in: something like "Set the Window object’s CSP list to the CSP list of the resource used to generate the document.
The update a style block algorithm does not exist in W3C’s HTML.
The nonce attribute for script and style were added to WHATWG’s HTML in whatwg/html@882803c. They have not yet been added to W3C’s HTML.
The §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? hooks were added to WHATWG’s HTML in whatwg/html@ee3486e. They aren’t yet in W3C’s HTML.
This hook is in-flight for WHATWG’s HTML. <https://github.com/WHATWG/html/issues/384>
This processing was added to WHATWG’s HTML in whatwg/html@5064a62. It has not yet been added to W3C’s HTML.
TODO.
TODO.
Do something interesting to the execution context in order to lock down eval(), et al. I don’t think ECMA gives us any hooks here, so let’s work with them to put something reasonable together.
This needs to be better explained.
Do something interesting to the execution context in order to lock down interesting CSSOM algorithms. I don’t think CSSOM gives us any hooks here, so let’s work with them to put something reasonable together.