Marketplace/Reviewers/Apps/Guide/Firefox OS Add-on Security

From MozillaWiki
< Marketplace‎ | Reviewers‎ | Apps‎ | Guide
Revision as of 12:32, 5 October 2015 by Cruetten (talk | contribs) (moved)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Security Guide for Firefox OS Add-on Reviewers

This is a guide for reviewers of Firefox OS add-ons (also known as "new-style add-ons") that focuses on the security aspects. FxOS add-ons have different security properties than apps, but before you start, please familiarize yourself with the general threat model for Firefox OS apps by reading our security guidelines for app developers and our security reviewer training.

FxOS add-ons are distributed and installed just like apps as ZIP archives. Superficially indistinguishable, it's easy to tell them apart once you look inside: If the archive contains a file called manifest.webapp, it's a web app. If it contains a file called manifest.json instead, it's a Web Extension. If it contains both, it's an app and the add-on manifest is ignored.

General considerations

In the scope of Firefox OS, add-ons (also known as new-style add-ons are a modernized variant of Firefox Extensions (also known as old-style add-ons. They adhere to the Web Extensions standard that is also supported in Google Chrome and Opera. While this in theory they are compatible, in practice they tend to use FxOS-specific features or interact with FxOS-specific apps.

The main difference old- and new-style add-ons is the manifest which is structured differently and uses different properties.

FxOS add-ons come in two major varieties: Content Scripts, and Background Pages. (Gecko is currently not supporting Event Pages, a non-persistent variant of Background Pages, but will be.) Content Scripts inject JavaScript files into web pages and apps, and background pages react to system events they register for. FxOS add-ons can also bundle both, but this document focuses on Content Scripts which are the most powerful and by far most common type.

Content Scripts

Content scripts don't live on their own. They are injected into existing apps or web pages. The injection behavior is exclusively defined in the manifest. Here's an example of the manifest.json file of a password manager:

{
  "manifest_version": 2,
  "name": "Password Manager",
  "description": "It is a password manager",
  "version": "0.0.1",
  "role": "addon",

  "content_scripts": [{
	"matches": "<all_urls>",
	"js": ["js/ContentManager.js"]
  },{
	"matches": ["app://system.gaiamobile.org/index.html"],
	"js": ["js/PasswordManager.js"]
  }]
}

This manifest tells us:

  • The add-on only bundles content scripts, two of them.
  • "js/ContentManager.js" is injected into "<all_urls>".
  • "js/PasswordManager.js" is injected into "app://system.gaiamobile.org/index.html", the system app.

Or in other words: Whenever the browser opens any web page (and that includes every app), js/ContentManager.js is executed, and whenever it loads the main page of the system app, js/PasswordManager.js is executed. Pretty much what you'd expect of a password manager.

Matches

For content scripts the main security concern with the manifest hence is the "matches" lines. Where scripts are injects determines the level of access and privileges it can obtain – and in the worst case abuse.

Matches follow the scheme://host/path format. Where scheme can be any of http, https, file, ftp, or app. ? can be used to match an arbitrary character, * matches anything. There is also the <all_urls> alias which is equivalent to * which in turn is equivalent to *://*/*.

If you're interested in the details, take a look at the source code of MatchPattern.jsm.

Execution Timing

Timing of content script execution is controlled by their run_at manifest key. However, the default option document_idle is the only one currently supported in Firefox OS. This means they are all executed after all other scripts have loaded. Keep this in mind, because it can create nasty race conditions when the content script modifies the injectee's behavior by live-patching its init functions.

Execution Context

A content script does not run in the target context it is injected to, but in its private sandbox. Since its ‘this’ object is different from that on the target context, its window and document objects are also different. However, target context’s window and document objects can be accessed through a proxy object that is available in its scope.

A content script can

  • access and modify all the target context’s objects and data.
  • inject JS files into the target context through the target's DOM.
  • access its Runtime API.
  • access the Web Extensions API.
  • can modify the target's web content through the webRequest API.
  • indirectly make API calls with the permissions of the target context by injecting js.
  • bypass the target context's CSP policy.
  • register event listeners. [arbitrarily?]
  • patch function calls in the target context and modify their behavior

A content script can not

  • be accessed from JS code running in the target context.
  • directly call APIs that require permission.

Threat model

Once you know where an add-on injects its content scripts, use the following table as a guide.

Content Scripts Threat Model (Summary)
Injection target Threat Recommendations
<all_urls>, * Global data exfiltration, performance issues Ensure injected script doesn't slow down the system, escalate to experienced sec reviewer
System App Full device compromise Escalate to experienced sec reviewer
SMS app SMS content exfiltration, sending costly premium SMS ...
Contacts app Contact data exfiltration, redirection of calls and messages ...
Specific privileged apps Abuse of app permissions Carefully audit match pattern
Specific certified apps Abuse of app permissions Escalate to experienced security reviewer
All web pages Password stealing, data exfiltration, performance issues
Specific web pages ... ...
any Injecting unsafe scripts into contexts Look for creation of script elements.