Content Security Policy is a way for site owners to define how content in their web site or web application is meant to behave, and have this enforced by the web browser.
Content Security Policy is not a magical solution to every security issue, but it addresses one aspect in particular. The primary goal of Content Security Policy is to mitigate Cross Site Scripting (XSS) by providing a way for site owners to specify which domains the browser should treat as valid sources of script. Therefore, the policy defines a whitelist of sources and the type of content those sources can contain. Compatible web browsers (user agents) or add-ons/extensions which support CSP will then only execute scripts from thee whitelisted domains. CSP can also be used to help mitigate clickjacking and packet sniffing attacks by specifying which domains can embed resources and specify which protocols (schemes) and porst can be used (e.g. serving a site over HTTPS on port 443 only). Non-supporting browsers will disregard the Content Security Policy (CSP) header and will default to the standard same-origin policy for web page content.
Episode 75 of the OWASP Podcast Series was an interview with Brandon Sterne (Mozilla), chief author of CSP. He highlighted that when a site declares and enables a CSP, even if only a small proportion of users are using a CSP compatible browser, both the site owners and other users will benefit. This is because the site owner can receive notifications whenever the policy is broken, using a real-time violation reporting mechanism, and this would alert the owner to there being some sort of script being injected or the existence of some other type of content that wasn't explicitly whitelisted. This allows the site owner to investigate and adjust the policy or mitigate/fix as appropriate. He used the analogy of a "canary in a coal mine" which gives advance warning of a coming crisis.
If you have read the specification and are considering implementing CSP for an existing web site or application, ensure your development environments has all the up-to-date code including JavaScript libraries. The first thing to understand is whether existing code and included libraries violate the base restrictions. These are independednt of content originating from other domains, and need to be addressed before any consideration is made of third-party content.
Base restrictions
The base restrictions, regardless of your own policies, are all good practice:
- no inline scripts
- no script code created from strings
- no data from URLs (unless allowed by policy)
- no XBL bindings except for those loaded by the "chrome:" or "resource:" protocols
Usually the first of these is probably the most common problem to have unless development practices have excluded inline scripts from working practices. It is far too easy for inline scripts to creep into page templates, if only for simple event handling such as "click", "rollover" and "rollout". When reviewing replacement code for these types of event, do consider whether the functionality can be replaced with non-script alternatives (e.g. CSS rollovers, HTML5) before developing new JavaScript code. At the same time, take the opportunity to review accessibility requirements at the same time—WCAG 2.0 has plenty to say about events.
Replacing inline JavaScript events with separate files with a content-type of application/javascript or application/json, often involves having to build in more adjustments to make the code compatible with the range of web browsers in use currently. This is more awkward and not necessarily straightforward.
The base restrictions can be weakened using the "options" directive but the risk of doing this, and the reduction in benefit to the site owner, need to be balanced with the effort in moving/changing/removing code. In the longer term, try not to modify the default behavior.
Bespoke and third-party JavaScript libraries, frameworks and widgets used within the site or application also need to be reviewed. This can be where the process becomes more difficult; if third party code doesn't meet the baseline restrictions, you have to consider whether to patch it, or replace it with something else, or remove the associated functionality, or weaken the baseline restriction as described above.
The "out of the box" experiences with some common libraries are shown below. These results are for a tight "allow 'self'; frame-ancestors 'none';" policy where the code library is included in a web page—but not making any calls to the functions. "-" indicates no violation of base restrictions occurred when the library was loaded.
| Name |
Version |
Comments |
| Dojo |
1.5.0 |
Violated base restriction: Code will not be created from strings
|
| jQuery |
1.4.3 |
Violated base restriction: Inline Scripts will not execute
|
| MochiKit |
1.4.2 |
Violated base restriction: Code will not be created from strings
|
| MooTools |
1.3 |
-
|
| Prototype |
1.6.1 |
-
|
| Script.aculo.us |
1.8.3 |
- (also requires Prototype above)
|
| YUI |
3.2.0 |
-
|
Rico was unavailable to download at the time of the tests. These quick checks didn't exercise use of the libraries—you will need to test relevant code in your own context yourselves. Of course, it could be argued that medium-high risk web sites and applications shouldn't be using third party code, but using these established libraries saves effort, and may reduce faults in custom JavaScript code.
Policy
Before creating the policy itself, you need to understand all the content included in the site and from which sources (scheme, host, or port) they are drawn from. It would be nice to believe this is already documented, but even if it is, check it is up-to-date. Extra code might include a widget, inline advertising or tracking code. These can usually be identified by an examination of the site source code and/or the results of spidering (traversing) the web site or application.
The policy can be defined in its entirely within the X-Content-Security-Policy HTTP header, or the header can reference a URL (policy-uri) with the same origin (scheme, host, or port) of a file containing the security policy. If you use the file method, make sure this is included in any application entry point permissions.
Security violation report
The security violation report is used to alert site owners of content that does not comply with the CSP. Ensure that all requests sent to the URL specified are logged securely. You may want the option to issue alerts to administrators and/or build this into existing integrated security event management systems. If an application has been thoroughly tested, violation reports should be treated with due attention. However, the site may also receive direct requests for the URL itself (by web crawlers, or people probing the site) and the report content could be forged. So, do add an exclusion for the URL to your robots.txt file, and treat the content with suspicion.
The mandatory "allow" directive defines the security policy for all types of content, but this can be tailored for particular content types (images, audio, video, scripts, style sheets, fonts, frames, XMLHttpRequests and object, embed & applet elements) using other directives. begin with assuming that all content only comes from the same source (allow:'self') and check what contravenes this. Before allowing an additional source for particular content types, consider whether the content can be included locally, or replaced in some way. For example can the font files referenced in CSS files be stored on the site instead of referencing another site? This reduces also inter-site dependencies.
File caching may mean that you receive violation reports some time after you have corrected your code to match the policy.
Note that by the inclusion of an "X-Content-Security-Policy-Report-Only" HTTP header, you can operate in Report-Only mode, suppressing enforcement of the policy in the browser, but continuing to receive the violation reports.
Concluding thoughts
CSP will be a great benefit for site owners and (some) users alike.
You may get some push back when it is realised there is some effort to implement CSP correctly, so be wary of online services being taken off the primary corporate site to make it easier to use CSP, especially when the services are moved to possibly less-secure third-party providers hosted elsewhere. That doesn't actually reduce the organisation's risk, nor that of the users.
For additional background on CSP, read the paper by Jeff Hodges and Andy Steingruebl of
PayPal The Need for a Coherent Web Security Policy Framework, the references in the paper, and some discussions during the idea's development. See also the additional information including a link to download a beta version of Firefox 4 which supports CSP, a demo and a link to a plugin for WordPress.
Some other blog posts relating to Content Security Policy within the last week or so are:
CSP is not an excuse not to do proper input validation and output encoding, but it does assist identification of problems if they occur, and will help to protect some users who are using a CSP-compliant browser or extension/add-on. That may not be a huge number of people at the moment, but there are efforts to make this more mainstream. For example CSP is listed as deliverables of the new W3C Web App Security Working Group. Keep your eyes and ears open, but do begin to consider the issue in new projects and larger changes to existing web sites and applications.