Chrome Extension Content Security Policy & Manifest Version 2

Starting around Chrome/Chromium 18 extensions are moving to manifest version two and this starts enforcing a content security policy. Many extension developers will need to update their manifest and re-write some code.

Here's what we had to do for the Twilio Client Extension.

Update the Manifest

The Manifest needs to change how the content is loaded.

{
  "manifest_version": 2,
  "content_security_policy": "media-src 'self' https://*.static.twilio.com; object-src 'self' https://*.static.twilio.com; script-src 'self' https://*.static.twilio.com;",
  "background": {
      "page":"background.html"
  },

The previous setting for background_page is gone.

Content Security Policy

This was the more confusing part of this update for me as I'd only had passing exposure to CSP before. Read the W3C docs, it shows where the names like *-src come from.

What our CSP shows is that we load media from self and from all HTTPS hosts inside of the static.twilio.com domain, including static.twilio.com itself. This was necessary otherwise the JS console will throw errors like:

Refused to load script from 'https://static.twilio.com/libs/twiliojs/1.0-392a7f1/twilio.js' because of Content-Security-Policy.

Removing In-Line JavaScript

This part is pretty easy, and you know you should have built your code this way in the first place but, like many, used the in-line methods for "convenience" :)

This means all the stuff that was built like this needs to be removed.


<script type="text/javascript">
var bgp = chrome.extension.getBackgroundPage();
bgp.doCoolness();

$('#some_field').on('click',some_routine());
</script>

Should be re-constructed to load from a source.

<script type="text/javascript" src="j/ext.js"></script>

Of course, now your scripts need to wait till DOM ready, so some things must be wrapped inside of ye-ould event listener.

// 100s of lines of JS here

// Last
document.addEventListener("DOMContentLoaded", function () {
  my_ext.init();
  my_ext.be_cool({duration:'forever'});
});

HTH