Default CSP restrictions

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:

  1. Inject a <script> element into the target document.
  2. Point the new script element at a script file on a white-listed host.
  3. 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.

Note: The common AJAX design pattern of using 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:
Note: The 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="http://evil.site/style.css" />
<div id="profile">

or

<input type="text" name="name" value="foo" style="-moz-binding: url('http://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="http://www.mozilla.org/xbl"
          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <binding id="evil">
    <implementation>
      <constructor>
        bad_stuff();
      </constructor>
    </implementation>
  </binding>
</bindings>

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

 

Document Tags and Contributors

Contributors to this page: Sheppy, chrisortega, jswisher, Marsf, kscarfone, abarth, bsterne
Last updated by: Sheppy,