This article covers the Firefox OS application security model in detail.

The key Web app security controls introduced by Firefox OS are:

  • Web apps are explicitly installed and launched, rather than being casually navigated to in a browser. Apps must be installed prior to use, and security controls govern the update and removal of apps to protect the user.
  • Access to new web APIs is controlled by a permissions system, where an app must declare the permissions it intends to use prior to installation. In order to gain access to more powerful APIs, the apps meet certain requirements, and be reviewed, approved, and signed by a Marketplace.
  • Web apps are sandboxed so they can only see their own resources (cookies, offline storage IndexedDB databases, and so on). Even if two apps happen to both load a page with the same URL, these two pages are not considered same-origin as they are running inside separate apps.

App Types

FirefoxOS supports three types of web apps: "web", "privileged" and internal ("certified"). An app's type is declared in its manifest, and determines the list of permissions it may request.

  • Web Apps: Most third-party apps will be "web" apps, which is the default type, and doesn't grant the app any additional permissions besides those already exposed to the Web. Web apps can be installed from any website, without any further verification. They can also be packaged but this does not allow any additional permissions.
  • Privileged Apps: These apps are allowed to request increased permissions, and as such privileged apps must be verified and signed by a Marketplace.
  • Internal/Certified Apps: Such apps can currently only be pre-installed on the device, as chosen by the OEM.

Note: For further details of the three types, see the App Manifest documentation.

App Delivery

Apps can be delivered by two different mechanisms in Firefox OS: hosted or packaged. Regular web apps can be delivered via either mechanism, whereas privileged and certified apps must be packaged.

Hosted apps

A hosted app consists solely of an application manifest file on the developer's web server, which contains a launch_path for what page should be shown when the app is launched. From a security point of view, hosted apps work very much like normal web sites. When a hosted app is loaded, the URL of the loaded pages are the normal URLs that those pages have on their web server, or loaded from the device if they have be previously stored in an appcache.

Packaged apps

A packaged app is an Open Web App that has all of its resources (HTML, CSS, JavaScript, app manifest, and so on) contained in a zip file, instead of having its resources on a web server. For details of this format, see Packaged apps

App Origin

For hosted apps, the origin of the app is the origin where the application manifest is located.

For packaged apps, the origin is unique application identified assigned upon installation. Privileged & Internal apps can also request a specific origin by specifying the origin parameter in the applications manifest.

App Installation

Apps are installed via the Apps JavaScript API:

  • Hosted Apps: Hosted apps are installed by calling navigator.mozApps.install(manifestURL), where manifestURL is a URL which specifies the location of the app. For further details, see Installing Apps.
  • Packaged Apps: Packaged apps are installed by calling navigator.mozApps.installPackage(packageURL). For the Packaged apps, the main application manifest is stored inside the package itself, so that it is signed. There is a second "mini-manifest", which is used to start the install process. See Installing Packaged Apps and Packaged apps for more information.

In order to secure that an app really wants to be installed as a web app we have to ensure that it's not possible to trick a web site into hosting an application manifest. This is done by requiring that the manifest is served with a specific mime-type, application/x-web-app-manifest+json. This restriction is relaxed when the manifest app, and thus the app manifest, is same-origin with the page that requested the app to be installed.

Updates

The update process for apps is described at Updating apps.

Permissions

Apps can be granted additional privileges on top of the ones granted to normal web sites. By default an app has the same permissions as normal web pages. In order to get additional permissions, the first step is for the app to enumerate the additional permissions it wants in the application manifest.

Manifest Declaration

For each additional permission that an app wants, the manifest must enumerate that permission in their manifest along with a human-readable description of why the app wants access to that permission. For example, if an app wants to use the navigator.geolocation API, it must include the following in its manifest:

"permissions": {
  "geolocation":{ 
    "description": "Required for autocompletion in the share screen",  
  }
},

This allows the app to then prompt for the geolocation permission, in the same way that a web page normally would. For further detail on manifests, see App manifest.

Note: Currently permissions usage intentions are not exposed to the user — see bug 823385.

Granting Permissions

When permissions are requested in the manifest, the permission is either set to allow or prompt, depending on the permissions. Allow permissions are granted by virtue of being declared in the manifest with no further approval needed. For prompt permissions, the user is prompted the first time the user accesses the related API, and has to make a choice prior to the API being granted. In general, Firefox OS only prompts users for permissions that have a privacy impact, and it is reasonable for the user to understand what they are being asked. For example, access to contacts is prompted, but access to make a raw TCP connection is implicitly granted since it is not reasonable for a user to understand the security implications of allowing this permission. Use of allow permissions is reviewed as part of Marketplace security review processes to ensure users are protected.

Revoking Permissions

Users are allowed to change their mind about prompt permissions at any time, and can revoke these permissions via the Firefox OS settings app. Allow permissions are not user configurable, however.

Web App Sandbox

Data stored per app

Each app runs in as a separate sandbox, meaning that all data stored by an app is separate from all data stored by another app. This includes things like cookie data, localStorage data, indexedDB data, and site permissions.

A diagram showing three Firefox OS apps all open is separate sandboxes, so none of them can affect each other.

This means that if the user has two apps installed, App A and App B, these apps will have a completely different set of cookies, different local data, and different permissions. This even applies if both of these apps open an <iframe> that points to the same origin. i.e. if both App A and App B open an <iframe> pointing to "http://www.mozilla.org", they will both render the website, however the website will be fetched and rendered with different cookies in the two apps.

A result of this is that if the user logs in to, for example, Facebook while using App A, this in no way affects App B's ability to interact with the user's account on Facebook. The login cookie that Facebook sets when the user logs in using App A is only available in App A. If App B opens an <iframe> to Facebook, the cookie wouldn't be there and so when App B opens Facebook, it receives the Facebook login page rather than the user's account.

Apps can't open each other

This means that apps can't open other apps by using iframes. If App A creates an <iframe> with the src set to the URL of App B, this won't actually open App B in the <iframe>. It will simply open the website located at that URL. It will not use any of App B's cookies and so it will behave no differently than if App B wasn't installed on the user's device.

This applies even for packaged apps (more about them below). If App A tries to open the packaged App B using an <iframe> pointing to the app:// URL of App B, this will simply fail to load. If this results in a 404 or some other type of error is still to be determined, but it will definitely fail to load. And it will fail in the same way no matter if App B is installed on the user's device or not, as to make it impossible for App A to determine if App B is installed.

The same thing happens if the top-level frame of App A is navigated to a URL for App B. We always know for a given frame which app is opened in it, therefore when attempting to load the App B URL in the App A frame, this will behave exactly like the two situations described above, i.e. in no way will App B's resources, like cookies or other local data, be used.

Motivation

There are both benefits and downsides to this approach. The downside is that if the user interacts with the same web site through several apps, he/she will have to log in to every app. Likewise, if a web site wants to store data locally, and the user interacts with this web site in several apps, the data will end up getting duplicated in each app, which could be a problem if it's a large amount of data.

The main benefit of this approach is that it's a more stable model. There is no way that several apps could interact with each other through a third-party website in unexpected ways such that installing an app causes another app to stop working. When an app is uninstalled there is no way that data for another app could be lost, or that another app will stop working due to functional dependence on the uninstalled app.

There are also large security benefits. A user can safely use his AwesomeSocial app to log in to Facebook without having to worry that the SketchGame app can mount any type of attack for getting at the user's Facebook data by exploiting bugs or other shortcomings in the Facebook web site.

There are also good privacy benefits. The user can safely install the PoliticalPartyPlus app without having to worry that MegaCorpEmployeeApp will be able to detect that the app was installed or what data it has created.

Sandboxed Permissions

In the same way that web site data is sandboxed per app, so is permission data. If App A loads a page from http://maps.google.com and that page requests to use geolocation and the user says "yes, and remember this decision for all times", this only means that http://maps.google.com has access to geolocation within App A. If App B then opens http://maps.google.com, that page won't have access to geolocation unless the user grants that permission again.

And just like in the normal browser, permissions are separated by origin. If App A is granted permission to use Geolocation, this does not mean that all origins running in App A have the permission to use Geolocation. If App A opens an <iframe> to http://maps.google.com, then http://docs.google.com still has to ask the user for permission before geolocation access is granted.

Browser API Sandbox

To additionally secure applications that open a large set of URLs, such as browsers, we have added a browserContent flag. The browserContent flag allows each app to have not one, but two sandboxes: one for the app itself, and one for any "web content" that it opens. For example:

Say that the MyBrowser app is loaded from the https://mybrowser.com domain. This is the domain the scripts and resources are loaded within. The scripts and resources belong to this domain.

Now, if a page in this app creates an <iframe mozbrowser>, a different sandbox is created and used for this <iframe>, which is different from the sandbox used by the app. So for example if this <iframe> is navigated to https://mybrowser.com, it will result in different cookies being used inside the <iframe mozbrowser>. Likewise, the contents inside the <iframe mozbrowser> will see different IndexedDB and localStorage databases from the ones opened by the app.

This also applies if the MyBrowser app wants to create integration with, for example, Google Maps to implement location-based browsing. If the app opens an <iframe> to http://maps.google.com, it will receive a set of cookies for the http://maps.google.com website. If the user then navigates inside the <iframe mozbrowser> containing http://maps.google.com, this will use different cookies and different permissions to the top level app.

Another example where this is useful is in a Yelp-like app. Yelp has the ability to visit a restaurant's website directly in the app. By using <iframe mozbrowser> to open the restaurant website, the Yelp app ensures that the restaurant website can't contain an <iframe> pointing back to Yelp's app (which points to http://yelp.com). If it does, the website will only receive the Yelp website, rather than the Yelp app. So there is no way that the restaurant website can mount an attack against the app since the contained Yelp website won't share any permissions or data with the Yelp app.

App Security Summary

The table below summarizes the different types of Firefox OS apps, and describes the format, installation, and update processes for open web apps running on Firefox OS.

Web App Types
Type Delivery Permission Model Installation Updates
Web Hosted or Packaged Less sensitive permissions, which are not dangerous to expose to unvalidated web content. Installed from anywhere Can be updated transparently to user or explicitly via a marketplace, depending on where the app was installed from, and the delivery mechanism.
Privileged Packaged & Signed Privileged APIs requiring validation and authentication of the app. Installed from a trusted marketplace Updated via a trusted marketplace, user prompted to approve download and installation of updates.
Internal Packaged Powerful and dangerous APIs not available to third-party apps. Pre-installed on the device Updated only as part of system level updates.

Note: For version 1.0 of Firefox OS, although web apps can be installed from any website/marketplace, privileged apps can only be installed from the Mozilla Marketplace, as support for multiple trusted marketplaces is not yet complete.

 

Document Tags and Contributors

Last updated by: foxbrush,
Hide Sidebar