Writing A Google Chrome Extension | Part 3: Securing the Extension

Writing A Google Chrome Extension | Part 3: Securing the Extension

Brajesh Sachan
Brajesh Sachan
Table of Contents
Table of Contents

Previously,

Part 1: Proof-of-Concept

Part 2: Making it Configurable

(Note: The source code for version 0.4: Browse, Zip, Diff)

Now that my basic extension is working well on my computer, I would like others to use it. The best way to distribute a Chrome Extension is to publish it on Chrome Web Store. However, we need to make it more secure before releasing it to everyone.

Restrict the Content Security Policy

In order to mitigate a large class of potential cross-site scripting issues, Chrome's extension system has incorporated the general concept of Content Security Policy (CSP) . This introduces some fairly strict policies that will make extensions more secure by default, and provides you with the ability to create and enforce rules governing the types of content that can be loaded and executed by your extensions and applications.

Since, we have been using manifest_version 2, we have the default content security policy of:

script-src 'self'; object-src 'self'

which means

  1. Eval and related functions are disabled
  2. Inline JavaScript will not be executed
  3. Only local script and and object resources are loaded

We will tighten our content security policy further in manifest.json

"content_security_policy": "default-src 'self'; style-src 'self' data: 'unsafe-inline';",

Set Strict Mode - "use strict"

Next, we will update our JavaScript files for Strict Mode.

"use strict";

Quoting from W3Schools' page on Strict Mode:

Why Strict Mode?
Strict mode makes it easier to write "secure" JavaScript.
Strict mode changes previously accepted "bad syntax" into real errors.
As an example, in normal JavaScript, mistyping a variable name creates a new global variable. In strict mode, this will throw an error, making it impossible to accidentally create a global variable.
In normal JavaScript, a developer will not receive any error feedback assigning values to non-writable properties.
In strict mode, any assignment to a non-writable property, a getter-only property, a non-existing property, a non-existing variable, or a non-existing object, will throw an error.

In addition, we will also limit scope of our variables as much as possible. This means using let instead of var wherever applicable.

Add Helpful Hints on "Options" Page

Let's provide some help to the users for updating configuration in options.html.

<label>Site Name</label>
<input type="text" id="site"><br />
<span>(e.g. Wikipedia or English Wikipedia)</span>
<br /><br />
<label>URL</label>
<input type="text" id="url"><br />
<span>(e.g. https://en.wikipedia.org/wiki/, or</span>
<span>https://en.wikipedia.org/wiki/{0})</span>
<br /><br />
<label>Pattern</label>
<input type="text" id="pattern" value = "*"><br />
<span>Regex or wildcard pattern (e.g. *)</span>

This is how it looks

And add some validation on options in options.js

function saveOptions() {
  if(site.value.match(/^\w+(?:\s*\w+)*$/) 
  	&& url.value.match(/^(http|https):\/\/[^ "]+$/) 
  	&& pattern.value.match(/^(?:\\w|\\d|-|\.|\*|\+|\w|A-Z|a-z|\[|]|\(|\))+$/)){
    chrome.storage.sync.set({
      site: site.value,
      url: url.value,
      pattern: pattern.value
    }, function() {
      status.textContent = 'Options saved.';
      setTimeout(function() {
        status.textContent = '';
      }, 750);
    });
  } else {
      status.textContent = 'Invalid options.';
      setTimeout(function() {
        status.textContent = '';
      }, 1000);
  }
}

The extension is more secure than before, and is looking much better.

Next up - Part 4: Publishing the Extension (Coming soon!)



Great! Next, complete checkout for full access to Deskera Blog
Welcome back! You've successfully signed in
You've successfully subscribed to Deskera Blog
Success! Your account is fully activated, you now have access to all content
Success! Your billing info has been updated
Your billing was not updated