A couple of days ago I had another look at Content Security Policy, a technology that allows a site to tell a browser resources are allowed to be loaded to protect against XSS and some other types of web application vulnerabilities. CSP was originally devised by the Firefoxians, but is in the process of being standardized by the W3C with support in Firefox, Chrome, Safari and even the upcoming Internet Explorer 10.
Great!
The functionality offered by CSP (blocking requests that are not allowed) is pretty close to what WP DoNotTrack tries to do, so I decided I’d try to integrate CSP in my plugin, based on the following assumptions:
- CSP-mode will only work for WP DoNotTrack if it is configured to use a whitelist
- As most WordPress+plugins installations are bound to have pages with at least inline JavaScript and/or style, I have to add “unsafe-inline” to allow those to continue to work (which indeed limits the level of protection against XSS-attacks)
- Given that a lot (most?) WordPress installations implement WP Super Cache of W3 Total Cache, it will -at least in a first stage- only kick in if WP DoNotTrack is configured to filter unconditionally
- Ideally the JavaScript-based component of WP DoNotTrack would “see” that CSP was activated and would not perform those nifty JavaScript AOP trickery
The “proof of concept”-quality code I ended up adding to wp-donottrack.php was pretty simple:
function wp_donottrack_csp() { global $listmode; if ($listmode==="1") { $whitelist=wp_donottrack_getWhiteList(true); $csp="default-src 'self' 'unsafe-inline'"; if (is_array($whitelist)) { foreach ($whitelist as $white) { $csp.=" *.".$white; } } header("X-Content-Security-Policy: " . $csp); //FF & MSIE10 header("Content-Security-Policy: ". $csp); //new standard header("X-WebKit-CSP: " . $csp); //chrome & safari } } add_action('init', 'wp_donottrack_csp', 10, 0);
Wait?
With this code on my testblog I started playing around in a couple of browsers. Based on that experience I found the following limitations:
- IE10 is not in production yet and there seems to be no information on the Microsoft sites available about what will be supported either. If anyone who’s reading this has IE10 preview installed, I would be very interested to know how my testblog looks like.
- Firefox does not support “unsafe-inline” yet, so any X-Content-Security-Policay header effectively blocks inline JavaScript and CSS, which I can’t do in my plugin
- The JavaScript API is part of the CSP 1.1 and seems not to have been implemented by browsers yet
So in this particular context (and specifically the absolute need for “unsafe-inline”), I’ve decided to hold off implementing CSP (I might implement iFrame sandboxing as support for that is coming with IE10 and will probably also land in Firefox 17). But if you have full control over a particular website or -application (meaning you can remove all inline JavaScript and CSS and all instances of evals in insourced JavaScript) and you want to harden your installation to stop cross-site scripting, you really should start thinking about implementing CSP (as Twitter seems to have done already)!