Security best practices for Firefox front-end engineers

This article will help Firefox developers understand the security controls in place and avoid common pitfalls when developing front-end code for Firefox.

Existing Security Controls

Sanitizing all strings that enter the DOM through APIs such as innerHTML

When running system-privileged chrome code, we sanitize all HTML fragments that are created for chrome-privileged documents. This policy includes all DOM APIs that take a string and parse it into a DOM tree.

We use our built-in sanitizer with the following flags:

SanitizerAllowStyle
SanitizerAllowComments
SanitizerDropForms
SanitizerLogRemovals

The sanitizer removes all scripts (script tags, event handlers) and form elements (form, input, keygen, option, optgroup, select, button, datalist). The canonical truth for the list of whitelisted elements is the source code.

The last flag ensures that developers will identify and avoid the problems early on in the development cycle and before shipping the code.

Linter rules against unsanitized DOM interaction

The Security Assurance team maintains an ESLint rule that disallows unsafe uses of innerHTML and similar DOM APIs. The linter makes an exception for code that uses string literals that are hard coded in the source code, assuming benevolent developers. Developers are able to avoid tripping the rule by using escaping functions in combination with template strings, for example:

bar.innerHTML = escapeHTML`<a href='${url}'>About</a>`;

In system-privileged chrome code, any kind of remaining scripts will still be removed by our sanitizer.

Appendix

List of disallowed DOM APIs

  • innerHTML
  • outerHTML
  • insertAdjacentHTML()
  • createContextualFragment()
  • document.write()
  • document.writeln()

Please take a look at the repository for an updated list