Security Automation

Firefox OS uses some automation to spot security errors throughout the development & build process. This article aims to documents how to work with those.

ESLint Security Checks in Firefox OS Gaia

Firefox OS Gaia uses ESLint to perform some basic security checks. We use https://github.com/mozfreddyb/eslint-plugin-no-unsafe-innerhtml. These checks are built into the Makefile as well as the git commit hook. The idea of these checks is to ensure that certain provably insecure coding patterns are avoided in our code base. We encourage developers to use the sanitizer.js library in gaia shared.

Unsafe assignment to innerHTML spotted

Fixing the test error

This error message suggests that you are using an unsafe coding pattern. Please do not assign variables to innerHTML, if at all possible. The new way requires the sanitizer.js library:

// if not included in the current project, you need require the sanitizer.js library from shared/js/
foo.innerHTML = Sanitizer.escapeHTML`<a href="${link}">click</a>`

Ignoring the test failure

If you can not apply this new coding style, please see below on how to get help.

Unsafe call to insertAdjacentHTML spotted

Fixing the test error

This error message suggests that you are using an unsafe coding pattern. Please do not simply call insertAdjacentHTML with a pure variable parameter. The new way requires the sanitizer.js library:

// if not included in the current project, you need require the sanitizer.js library from shared/js/
node.insertAdjacentHTML('afterend', Sanitizer.escapeHTML`<a href="${link}">click</a>`);

Ignoring the test failure

If you can not apply this new coding style, please see below on how to get help.

Storing and re-using the escaped HTML

The sanitizer has two basic usages. The first one is explained above, where we try to fix the most common errors. If you really need to generate your HTML somewhere else and e.g. cache it, you won't be able to run `escapeHTML` on a string that still carries the distinction between static HTML and user inputs. Thus, there is another feature in Sanitizer that allows you to create an object that contains escaped HTML which is guaranteed to be safe and thus allowed for direct innerHTML assignments (and insertAdjacentHTML calls): createSafeHTML and unwrapSafeHTML

// create the HTML object for later usage
function storeGreeting(username) {
  var safeHTML = Sanitizer.createSafeHTML`<p>Hello ${username}</p>`;
  cache.store('greeting', safeHTML)
}
// re-use the existing safe-HTML object
function useGreeting(domNode) {
  var htmlObj = cache.retrieve('greeting');
  domNode.innerHTML = Sanitizer.unwrapSafeHTML(htmlObj);
}

 

What if the new pattern can not be applied

If you cannot apply the escapeHTML pattern, try to work with the createSafeHTML and unwrapSafeHTML flow. If this does not work, don't worry. Every rule has its exceptions. If you think your example is not unsafe, you can file a bug that blocks against bug 1155131. Even better, you can submit a pull request and improve our automation, so that it will no longer complain about scripts like yours.

If you want your unsafe example to be discussed further even though it is unsafe, please raise this with the Firefox OS Security Team by requesting the sec-review? flag on your implementation bug towards fxos@security.bugs.

Implementation Details

Document Tags and Contributors

 Contributors to this page: chrisdavidmills, freddyb, marumari
 Last updated by: chrisdavidmills,