this blog uses Content Security Policy

FYI: this post is an artifact of the Dark Ages when my blog was self-hosted WordPress. Let us not speak of that time.

Having recently given some talks about Content Security Policy (CSP), I decided just now to enable it on my own blog to prevent cross-site scripting.

This lil’ blog is hosted by the MIT Student Information Processing Board and runs on a fairly-uncustomized WordPress 4.x installation. Although I could have enabled CSP by modifying my .htaccess file, I chose to use HTML tags instead so that these instructions would work for people who don’t have shell access to their WordPress host. Unfortunately, CSP using hasn’t landed in Firefox yet (tracking bug) so I should probably do the .htaccess thing anyway.

It’s pretty easy to turn on CSP in WordPress from the dashboard:

  1. Go to <your_blog_path>/wp-admin/theme-editor.php. Note that this isn’t available for WordPress-hosted blogs (*
  2. Click on Header (header.php) in the sidebar to edit the header HTML.
  3. At the start of the HTML <head> element, add a CSP meta tag with your CSP policy. This blog uses <meta http-equiv="Content-Security-Policy" content="script-src 'self'"> which disallows all scripts except from its own origin (including inline scripts). As far as I can tell, this blocks a few inline scripts but doesn’t impede any functionality on a vanilla WordPress instance. You might want a more permissive policy if you use fancy widgets and plugins.
  4. [Bonus points] You can also show a friendly message to users who disable javascript by adding a <noscript> element to your header.noscript

A fun fact I discovered during this process is that embedding a SoundCloud iframe will include tracking scripts from Google Analytics and Unfortunately CSP on the embedding page (my blog) doesn’t extend to embedded contexts ( iframe), so those scripts will still run unless you’ve disabled JS.


That’s all. I might do more posts on WordPress hardening later or even write a WP plugin (*shudders at the thought of writing PHP*). More tips are welcome too.

UPDATE (8/24/15): CSP is temporarily disabled on this blog because Google Analytics uses an inline script. I’ll nonce-whitelist it later and turn CSP back on.