Copyright © 2010-2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
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 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/.
Although a FPWD, this document describes a proposal that has been
discussed by the broader community for approximately a year. 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
This document was published by the Web Application Security Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webappsec@w3.org (subscribe, archives). All feedback is welcome.
Publication as a 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 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 section is non-normative.
This document defines Content Security Policy, a mechanism web applications can use to mitigate the 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 restrict from where the application can load resources.
To mitigate XSS, for example, a web application can restrict itself to loading scripts only from known, trusted URIs, making it difficult for an attacker who can inject content into the web application to inject malicious script.
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 needs to opt into using
CSP by supplying a Content-Security-Policy HTTP header or an appropriate
HTML meta
element. Such policies apply the current document
only. To supply a policy for an entire site, the server need to supply a
policy along with each resource representation.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].
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 is one that implements all the requirements listed in this specification that are applicable to user-agents.
A conformant server is one that implements all the requirements listed in this specification that are applicable to servers.
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:
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. That resource representation is often referred to in this document as the protected document.
A server transmits its security policy for a particular resource as
a collection of directives, such as default-src
'self'
, each of which controls a specific set of privileges for
a document rendered by a 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.
Fetching resources requires resolving and parsing URLs. The algorithms for resolving a URL and parsing a URL are defined in the HTML5 standard [HTML5].
The term origin is defined in the Origin specification. [ORIGIN]
The term URI is defined in the URI specification. [URI]
The <script>
, <object>
, <embed>
,
<img>
, <video>
, <audio>
,
<link>
, <frame>
and <iframe>
elements are defined in the HTML5 standard. [HTML5].
The <applet>
element is defined in the HTML 4.01 standard. [HTML401].
The @font-face
CSS rule is defined in the CSS Fonts Module Level 3 standard.
[CSS3FONT]
The XMLHttpRequest
object is defined in the XMLHttpRequest
standard. [XMLHTTPREQUEST]
The WebSocket
object is defined in the WebSocket
standard. [WEBSOCKET].
The EventSource
object is defined in the EventSource
standard. [EVENTSOURCE].
The Augmented Backus-Naur Form (ABNF) notation used in this document is specified in RFC 5234. [ABNF]
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).
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.
The policy can be delivered from the server to the client via an HTTP response header
or an HTML meta
element.
Of the two delivery mechanisms, servers should use the HTTP
response header mechanism whenever possible because, when using the
meta
element mechanism, there is a period of time between
when the user agent begins to process the document and when the user
agent encounters the meta
element when the document is
not protected by the policy.
Content-Security-Policy
Header FieldThe Content-Security-Policy
header field is the
preferred mechanism for delivering a CSP policy.
A server may supply one or more CSP policies in HTTP response
header fields named Content-Security-Policy
along with
the protected document.
Upon receiving an HTTP response containing at least one
Content-Security-Policy
header field, the user agent
must enforce the combination
of all the policies contained in these header fields.
Content-Security-Policy-Report-Only
Header FieldThe Content-Security-Policy-Report-Only
header field
lets server experiment with CSP by monitoring (rather than
enforcing) a policy. This feature lets server operators develop
their security policy iteratively. They 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 can promote the report-only policy to normal blocking mode.
A server may supply one or more CSP policies in HTTP response
header fields named Content-Security-Policy-Report-Only
along with the protected document.
If a server supplies at least one
Content-Security-Policy-Report-Only
header field in an
HTTP response, the server must not supply any
Content-Security-Policy
header fields.
Upon receiving an HTTP response containing at least one
Content-Security-Policy-Report-Only
header field, the
user agent must monitor the
combination of all the policies contained in these header
fields.
meta
ElementThe 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:
http-equiv="content-security-policy"
)meta
element lacks a
content
attribute, abort these steps.content
attribute of the meta
element.http-equiv="content-security-policy-report-only"
)meta
element lacks a
content
attribute, abort these steps.content
attribute of the meta
element.A CSP policy consists of a U+003B SEMICOLON
(;
) delimited list of directives:
policy = directive-list directive-list = [ 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 ";"> )
To parse a CSP policy policy, the user agent must use an algorithm equivalent to the following:
;
):
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
document and the source expression 'unsafe-inline'
represents content supplied inline in the document 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 ] ) keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'" scheme = <scheme> production from RFC 3986 host = "*" / [ "*." ] 1*host-char *( "." 1*host-char ) host-char = ALPHA / DIGIT / "-" port = ":" ( 1*DIGIT / "*" )
To parse a source list source list, the user agent must use an algorithm equivalent to the following:
'none'
(including the quotation
marks), return the empty set.source-expression
, add the token to the
set of source expressions.To check whether a URI matches a source expression, the user agent must use an algorithm equivalent to the following:
*
), then return does match.scheme-source
, then the URI matches the source
expression of the URI's scheme is a case-insensitive match for the
source expression's scheme
.host-source
:
scheme
that is
not a case insensitive match for scheme, then
return does not match.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
host, then return does not match.host
, then return does
not match.port
and port is not the default port
for scheme, then return does not
match.port
that (a) does not contain an U+002A ASTERISK
character (*
) and (b) does not represent
the same number as port, then return does not
match.'self'
(including the quotation marks),
then return the URI matches the source expression if the URI has
the same scheme, host, and port as the document's URI.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'
.
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 prevent the protected document 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 document because the attacker will be unable to usurp the document'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, where the specific requirements for monitoring each directive are defined separately for each directive (See Directives, below).
Generally speaking, monitoring a directive does not prevent the protected document from undertaking any actions. Instead, any actions that would have been prevented by the directive are instead reported to the developer of the web application. Monitoring a CSP policy is most useful for testing whether enforcing the policy will break the web application.
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.
To enforce the combination of one or more policies, the user agent must enforce each policy. For example, if an action is prevented by at least one of the policies, then the action will be prevented by the combination of the policies.
To monitor the combination of one or more policies, the user agent must monitor each each policy.
This section describes the content security policy directives introduced in this specification.
In order to protect against Cross-site Scripting (XSS), authors should include
script-src
and object-src
directives, ordefault-src
directive, which covers both
scripts and plug-ins.In either case, authors should not include
'unsafe-inline'
in their CSP policies if they wish to
protect themselves against XSS.
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 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.
script-src
The script-src
directive restricts which scripts the
protected document can execute. The directive also controls other
resources, such as XSLT stylesheets, 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
If the policy contains an explicit script-src
, let the
allowed script sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed script sources be the
default sources
If 'unsafe-inline'
is not in allowed script
sources:
script
element or from an inline event handler),
instead the user agent must not execute script.javascript
URI, instead the user agent must not execute
the script. (Note: The user agent should execute script contained in
"bookmarklets" even when enforcing this restriction.)If 'unsafe-eval'
is not in allowed script
sources:
eval
and function eval
must throw a
security exception.Function
must throw a security exception.setTimeout
function must return
zero without creating a timer.setInterval
function must return
zero without creating a timer.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:
src
attribute of a script
element or when
processing the Worker
or SharedWorker
constructors.<?xml-stylesheet?>
processing directive in an XML
document, the href
attributes on
<xsl:include>
element, or the href
attributes on <xsl:import>
element.object-src
The object-src
directive restricts from where the
protected document 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
If the policy contains an explicit object-src
, let the
allowed object sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed object sources be 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:
data
attribute of an object
element, the
src
attribute of an embed
elements, or the
code
or archive
attributes of an
applet
element.Whenever the user agent would load a plug-in without an associated
URI (e.g., because the object
element lacked a
data
attribute), if the protected document's URI does not
match the allowed object
sources, the user agent must not load the plug-in.
style-src
The style-src
directive restricts which styles the
user applies to the protected document. 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
If the policy contains an explicit style-src
, let the
allowed style sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed style sources be the
default sources
If 'unsafe-inline'
is not in allowed style
sources:
style
element, instead the user agent must
ignore the style.style
attribute, instead the user agent
must
ignore the style.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 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:
href
attribute of a link
element with a
rel
attribute containing the token
stylesheet
or when processing the @import
directive in a stylesheet.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 document 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
If the policy contains an explicit img-src
, let the
allowed image sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed image sources be 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:
src
attribute of an img
elements,
the url()
or image()
values on any CSS
property that is capable of loading an image [CSS3-Images], or
the href
attribute of a link
element with
an image-related rel
attribute, such as
icon
.Should the user agent fire the error event when one of these loads fails?
media-src
The media-src
directive restricts from where the
protected document 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
If the policy contains an explicit media-src
, let the
allowed media sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed media sources be 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:
src
attribute of a video
or audio
elements.frame-src
The frame-src
directive restricts from where the
protected document 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
If the policy contains an explicit frame-src
, let the
allowed frame sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed frame sources be 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:
src
attribute of an iframe
or
frame
element.How does this work for the object
element? We don't know whether the request is going to lead to a
plug-in or a frame until we get the response back and can look at the
MIME type.
font-src
The font-src
directive restricts from where the
protected document 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
If the policy contains an explicit font-src
, let the
allowed font sources be the result of parsing the directive's value as a source
list. Otherwise, let the allowed font sources be 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:
@font-face
CSS rule. TODO: Citation needed.connect-src
The connect-src
directive restricts which URIs the
protected document can load using DOM APIs. 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
If the policy contains an explicit connect-src
, let
the allowed connection targets be the result of parsing the directive's value as a source
list. Otherwise, let the allowed connection targets be
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:
open()
method of an XMLHttpRequest
object.WebSocket
constructor.EventSource
constructor.sandbox
A future version of this document might include a
sandbox
directive for controlling the HTML5 sandbox
flags.
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>
Let the set of report URIs be the value of the
report-uri
directive, each resolved relative to the
protected document's URI.
To send a violation report, the user agent must use an algorithm equivalent to the following:
We might need to change some of these keys because they can leak sensitive information.
Examples of public suffixes include .com
,
.net
and .co.uk
. Examples of
"public suffix +1 DNS label" include
example.com
, example.net
and
example.co.uk
. Therefore a protected document whose
host is www.example.com
could have a
report-uri
hosted on
reports.example.com
but not
reports.example.net
.
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.)policy-uri
The policy-uri
directive specifies a URI from which
the user agent can retrieve the actual policy. The syntax for the name
and value of the directive are described by the following ABNF
grammar:
directive-name = "policy-uri" directive-value = <URI-reference from RFC 3986>
The policy-uri
directive might be
removed from this document.
Authors must not specify policies that contain both a
policy-uri
directive and another directive.
If the user agent would enforce a policy containing both the
policy-uri
directive and another directive, instead the
user agent must enforce the policy default-src
'none'
.
When processing the policy-uri
directive, the user
agent must run an algorithm equivalent to the following:
policy-uri
directive
relative to the URI of the protected document.default-src 'none'
.
GET
.200
or if the request encountered an HTTP redirect, abort these steps
and enforce the policy default-src 'none'
.Content-Type
header
field or if the Content-Type
header field is not a case
insensitive match for text/x-content-security-policy
,
abort these steps and enforce the policy default-src
'none'
.policy-uri
directive, abort these steps and enforce the
policy default-src 'none'
.This section is non-normative.
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, plug-in 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: A site operations group wishes to globally deny all third-party scripts in the site, and a particular project team wishes to also disallow third-party media in their section of the site. Site operations sends the first header while the project team sends the second header, and the user-agent takes the combination of the two headers to form the complete interpreted policy:
Content-Security-Policy: default-src *; script-src 'self' Content-Security-Policy: default-src *; script-src 'self'; media-src 'self'
Example 4: 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:
This section is non-normative.
This section contains an example violation report the user agent might sent to a server when the protected document violations a sample policy.
In the following example, a document from
http://example.org/page.html
was rendered with the
following CSP policy:
default-src 'self'; report-uri http://example.org/csp-report.cgi
The document loaded an image from
http://evil.example.com/image.png
, violating the
policy.
{ "csp-report": { "request": "GET http://example.org/page.html HTTP/1.1", "request-headers": "Host: example.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b12pre) Gecko/20110222 Firefox/4.0b12pre Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip, deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Proxy-Connection: keep-alive Cache-Control: max-age=0", "blocked-uri": "http://evil.example.com/image.png", "violated-directive": "default-src http://example.org" } }
In the above sample report the violated-directive
field was sent in the way it was interpreted by the user-agent. The
directive was made explicit by replacing the keyword
'self'
with the explicit host name of the protected
resource. This is recommended behavior for user-agents as it reduces
ambiguity, making policy violations easier to trace by server
admins.
Should we add this as a requirement when preparing reports?
No informative references.