Obsolete since Gecko 15.0 (Firefox 15.0 / Thunderbird 15.0 / SeaMonkey 2.12)
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
Note: As of Gecko 15.0, Content Security Policy no longer has any default restrictions. Please see the W3C Content Security Policy specification for more details.
By default, when CSP is in effect, a certain set of restrictions is put in place. Web servers can adjust these restrictions to suit the needs of the web sites or applications they're running by using policy directives to change individual policy areas. If you don't customize a specific policy area, the configuration described below is used.
Inline JavaScript
By default, no inline JavaScript code executes. Only scripts loaded from files located on white-listed servers are executed.
Restricted scripts
Internal <script> nodes
No code embedded using <script>
elements is executed. For example, the following code is ignored:
<script type="text/javascript"> /* some evil code here */ </script>
However, scripts loaded from a white-listed source using the <script>
element is still allowed:
<script src="foo.js" type="text/javascript"></script>
javascript: URIs
javascript:
URIs are ignored:
<a href="javascript:do_something_evil()">Click this for awesome fun stuff!</a>
Event-handling attributes specified in HTML
Additionally, specifying JavaScript code to execute on event handling HTML attributes is disabled by CSP's default settings:
<a onclick="another_evil_script()">Click this for awesome fun stuff!</a>
To handle events, you can set the event handler attributes of elements, or call element.addEventListener()
, from script that has been loaded from a white-listed site:
element.onclick = someFunction; element.addEventListener("click", someFunction, false);
Justification
Cross-site scripting (XSS) attacks are possible because the browser can't tell the difference between content the server intended to send and content injected by an attacker. By default, CSP forces scripts to be kept entirely separate from content, requiring authors to be specific about what code they want to load and execute. This makes it much more difficult for attackers to inject scripts into sites.
With CSP enabled, injecting an attack into a site is much more difficult; the attacker is required to:
- Inject a
<script>
element into the target document. - Point the new script element at a script file on a white-listed host.
- Be able to modify the contents of the script file on the white-listed host.
Attack types mitigated
These default restrictions on inline JavaScript help to mitigate the following types of attacks:
- Reflected XSS.
- Stored XSS.
javascript:
link injection.- HTML attribute injection.
Code in strings
By default, CSP disables all features that allow code in strings to be executed.
eval()
The JavaScript function eval()
is disabled by default.
setTimeout() and setInterval()
Calls to window.setTimeout()
and window.setInterval()
specifying a string as the code to be executed at the specified time are ignored:
window.setInterval("omg_evil_code()", 10000);
You can, however, use these functions specifying a function name to execute at the appropriate time:
window.setInterval(myFunc, 10000);
Function constructor
Attempts to use the Function()
constructor to create functions from code in a text string are disallowed by default:
var f = new Function("/* evil code */");
Instead, you should create your function using the function
operator or the function
statement:
function f(...) { /* function operator */ /* my safe, happy function code here */ }
var f = function() { /* function statement */ /* my safe, happy function code here */ }
Justification
All of the code constructs disallowed by this restriction can be used to generate code from strings, which can easily come from untrusted sources, loaded using insecure protocols, and are therefore easily tainted by attackers. Once string data has been contaminated by an attacker, preventing the strings from being used to execute malicious code is very difficult.
XMLHttpRequest
to fetch JSON data from a server is still enabled when CSP is in effect when using a JSON parser or a browser with native JSON support.Attack types mitigated
These default restrictions on creating code help to mitigate the following types of attacks:
- AJAX request tampering
- Improper use of dynamic properties
data: URIs
By default, all data: URIs are disallowed unless they are explicitly opted-in using the X-Content-Security-Policy
header:
X-Content-Security-Policy: allow 'self'; img-src 'self' data:
data:
token in the above policy is effectively a hostless scheme, so any data: URI
is permitted as a content source for images.Justification
Because data: URIs can be used to load any type of data (including JavaScript or HTML), it's an obvious potential vector for attacks such as this example:
<a href="data:text/html,<script>omg_evil_script()</script>">Open my fun game</a>
XBL bindings
By default, XBL bindings must come from either chrome:
or resource:
URIs. Attempts to load XBL bindings using any other URL scheme will fail.
Justification
XBL is used to define the properties and behaviors of elements in HTML, XUL, and SVG documents from external files; as such XBL files are a potential injection attack vector. By requiring that XBL bindings be loaded using only chrome:
or resource:
URIs ensures that the bindings are loaded from a package that's already installed on the user's system. This prevents script from arbitrary locations from being included in a document using CSS.
Example
An attacker can use a style sheet (or an inline style attribute) to inject script through an XBL binding.
First, the CSS is injected:
<link rel="stylesheet" type="text/css" href="https://evil.site/style.css" />
<div id="profile">
or
<input type="text" name="name" value="foo" style="-moz-binding: url('https://evil.site/bindings.xml#evil')" />
The CSS establishes an XBL binding:
#profile { -moz-binding: url("bindings.xml#evil"); }
And the XBL includes JavaScript code that does unspeakable things to the user's computer:
<?xml version="1.0"?> <bindings xmlns="https://www.mozilla.org/xbl" xmlns:xul="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <binding id="evil"> <implementation> <constructor> bad_stuff(); </constructor> </implementation> </binding> </bindings>
Optional CSP directives must refer to the same host
The optional CSP policy directives policy-uri
and report-uri
must refer to the same host as the protected document. In addition, policy-uri
documents must be served with the MIME type text/x-content-security-policy
to be valid.
Justification
This requirement prevents an attacker from using CSP to attack sites that have not opted-in to using CSP. Such an attack could be executed by injecting a policy-uri
directive using a CSP HTTP header. By restricting the policy-uri
directive to the originating host and requiring the text/x-content-security-policy
MIME type, the browser can ensure that the site has intentionally opted-in to using CSP.
As for the report-uri
, the report it sends contains potentially confidential information such as cookie values and query string parameters. This information is only intended for the use of the site administrator for debugging; restricting the destination for these reports to the protected server prevents that information from being hijacked by an attacker.
See also
- Introducing Content Security Policy
- Using Content Security Policy
- CSP policy directives
- Using CSP violation reports