How to properly handle chrome extension updates from content scripts

Once Chrome extension update happens, the “orphaned” content script is cut off from the extension completely. The only way it can still communicate is through shared DOM. If you’re talking about really sensitive data, this is not secure from the page. More on that later.

First off, you can delay an update. In your background script, add a handler for the chrome.runtime.onUpdateAvailable event. As long as the listener is there, you have a chance to do cleanup.

// Background script
chrome.runtime.onUpdateAvailable.addListener(function(details) {
  // Do your work, call the callback when done
  syncRemainingData(function() {
    chrome.runtime.reload();
  });
});

Second, suppose the worst happens and you are cut off. You can still communicate using DOM events:

// Content script
// Get ready for data
window.addEventListener("SendRemainingData", function(evt) {
  processData(evt.detail);
}, false);

// Request data
var event = new CustomEvent("RequestRemainingData");
window.dispatchEvent(event);

// Be ready to send data if asked later
window.addEventListener("RequestRemainingData", function(evt) {
  var event = new CustomEvent("SendRemainingData", {detail: data});
  window.dispatchEvent(event);
}, false);

However, this communication channel is potentially eavesdropped on by the host page. And, as said previously, that eavesdropping is not something you can bypass.

Yet, you can have some out-of-band pre-shared data. Suppose that you generate a random key on first install and keep it in chrome.storage – this is not accessible by web pages by any means. Of course, once orphaned you can’t read it, but you can at the moment of injection.

var PSK;
chrome.storage.local.get("preSharedKey", function(data) {
  PSK = data.preSharedKey;

  // ...

  window.addEventListener("SendRemainingData", function(evt) {
    processData(decrypt(evt.detail, PSK));
  }, false);

  // ...

  window.addEventListener("RequestRemainingData", function(evt) {
    var event = new CustomEvent("SendRemainingData", {detail: encrypt(data, PSK)});
    window.dispatchEvent(event);
  }, false);
});

This is of course proof-of-concept code. I doubt that you will need more than an onUpdateAvailable listener.

Leave a Comment