Apps/Security: Difference between revisions

 
(156 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= Boot 2 Gecko App Security Model Discussion =
The intent of this page is to provide some background for how security works in B2G and Desktop/Android OpenWebApps. The target audience for this page is (at least for now) primarily people working on implementing B2G and the Open Webapps runtimes. Over time we should improve the pieces that affect web developers such that they can be used as developer documentation.
This page is for capturing information about the B2G/OWA security discussion.  
{{note|<b>This is not a design document and should not be considered authoritative at this time</b>}}
* Track the status of [[B2G_App_Security_Model]]
* Track the status of [[B2G_App_Security_Model/Threat_Model]]
* [https://developer.mozilla.org/en/OpenWebApps OWA developer page]
== Definitions ==
* '''WebApp''' - An application developed with web technologies (JS/HTML/CSS). May contain dynamic and static content
* '''Native App''' - A WebApp consisting solely of static content and run on a B2G capable device
* '''Gaia App''' - '''DEFINITION REQUIRED'''
* '''B2G App''' - '''DEFINITION REQUIRED''' which is meaningful in the context of the above app definitions
* '''Store''' - A marketplace where a user may download/purchase WebApps for their device
* above definition are up for discussion
* '''Extended Validation (EV) Certificate''' - A SSL certificate that undergoes additional authentication / verification steps before issuance.
** [http://www.cabforum.org/certificates.html Explanation]
** [http://www.cabforum.org/vetting.html Verification process]
* '''Content Security Policy (CSP)''' - A mechanism by which website administrators can define a policy which restricts what domains a website can load resources from
** [https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html Specification]
'''Important reading!'''  B2G applications are Open Web Apps, you can read about them here: https://developer.mozilla.org/en-US/apps


=== Concepts to be given Official Definitions ===
{{note|This is the official reference for the Apps and FirefoxOS Security Model.  Please do not edit this page without first discussing changes in dev-webapps@lists.mozilla.org}}


There is no real easy way to distinguish the following, all of which are iframes (!) in the B2G environment.  There is some considerable confusion as a result, especially due to the fact that the required security context and especially the interactions between parent and child iframes are ''different'' depending on the type of iframe.
=Open Web Apps Security and Privacy Model=


Names really therefore need to be given to the following:
=Introduction=
The open web application security and privacy model spans a wide variety of use cases, from typical web content to system-critical applications.  As such, a one-size-fits-all security model won't work.  Instead we need a range of options that balance out the flexibility and common design patterns for web applications while mitigating the additional risks that come with exposing sensitive APIs.  Additionally, providing users as-necessary insight into app use of their data helps them make more informed risk/reward decisions as they install apps and grant permissions.


* the root frame (top-level one into which the top gaia HTML is loaded)
=Discussion and Resources=
* individual gaia apps (sub-iframes, one per app)
List of webAPIs and corresponding security discussions: [[WebAPI]]
* any gaia app that opens up a public-facing (URL-based) iframe in which the contents of a URI are displayed: the browser app is one such
* iframes *within* that iframe - as in "iframes that you normally think of iframes being used for as an ordinary web developer".


Discussion which raises the issue of confused definitions, helps clarify them:
Implementation tracking bug [https://bugzilla.mozilla.org/show_bug.cgi?id=basecamp-security basecamp-security]
https://groups.google.com/d/msg/mozilla.dev.b2g/AQYPkIjKxjE/WYy0LPta9cMJ


== Bugs ==
Installation and updates: [[Gaia/System/Updates]]
* {{bug|707625}} - WebAPI permissions manager
== Requirements ==
=== Distribution / management of WebApps ===
# It should not be trivially easy for a rogue application to be listed on a marketplace / store
# A store may revoke a bad / malicious WebApp
# A telco can decide which stores to implicitly trust on their devices.  (an analogy in debian packaging terms is that the telco sets the initial contents of the /etc/apt/sources.list file)
# A user must be able to override the stores which they decide to implicity trust on their devices.  (an analogy in debian packaging terms is that the user should be able to set the contents of the /etc/apt/sources.list file)
# The distribution of applications must scale to mass-volume proportions (100 million or more phones; 1 million or more store-distributed application downloads or updates per day)
# The distribution of applications must be secure
# The development of applications must be straightforward, and rapid development cycles must be easy.
# The security of the distribution of applications through stores must not interfere with, or make awkward, the development of applications.
# The development of applications by a single developer must not compromise or interfere with the secure distribution of applications via any give store.


=== Management / granting of API permissions to WebApps ===
B2G OS and process security model: [[B2G/Architecture/Runtime_Security]]
# User should be able to view / control / modify permissions granted to WebApps
# WebApps should fail gracefully if not all permissions granted
# User should have control over APIs with privacy implications
# User should be able to audit usage of permissions (this is different from viewing what permissions an app has, since that does not tell you how or when it is used)
# Apps must not request permission to do something or use a function that it has not declared that it needs to do.  ('''TBD: If an app attempts to execute a function which the user has not authorised, what action should be taken? terminate the app? remove it? report it?''')


=Foundational Principles=
*Maintain core strengths and flexibility of the web
*Protect the security and privacy of the user
*Protect the device from poorly written & malicious applications
*With additional privileges come additional responsibilities for the developer and app store
*User choice and control - treat the user with respect and present them with choices that allow them to make informed decisions.  See our privacy operating principles [http://blog.mozilla.org/privacy/2011/01/12/mozillas-privacy-data-operating-principles/], specifically "Real Choices."


discussion links:
=Definitions=
# https://groups.google.com/forum/#!topic/mozilla.dev.b2g/AQYPkIjKxjE
==Explicitly granted permissions==
Permissions that need to be enumerated in the manifest and require user consent at "time of use" to enable, whether via a prompt or an in-content user mediated UI. The user can also inspect and modify the explicit permissions for any app via the permissions manager. When the user is prompted for explicit permissions, they need to be informed what is requested, why it's requested, and how the app will use data obtained through this permission.


=== Enforcement of permissions on device ===
==Implicitly granted permissions==
# Permissions should be enforced regardless of version of B2G installed
Permissions which are enumerated in the manifest and granted to that type of application without requiring any user interaction.  The user may be able to inspect, but not modify, the implicit permissions that an app requests via the permissions manager.


== Proposals ==
==Data Usage Intention==
=== App instance / version ===
Apps can make a commitment to users about their intended uses of data collected through a given API (for which the user is grants a permission).  This is a short string that reflects to users what risk might surface by granting an app permission to use the given API.  Users can leverage this ''Usage Intention'' to decide whether the value provided by the app is worth the risk or not.  Usage Intentions are attached to permissions as an annotation of not only why the permission is needed, but what the app will do with the data.
* {{note|Last updated March 14, 2012}}
* Possible definitions of what an app instance / version is
*# a static bundle of code authenticated by manifest + signature (or equivalent)
*# a dynamic stream of code authenticated by a specific origin (same origin applied, all assets must be loaded from https://<a host>)
*# an initial loader authenticated by a specific origin (https://<a host>), which can then load whatever it wants
*# unauthenticated code loaded over any channel, from any origin
* loosely ordered from best to worst (descending) security wise
* 1) and 2) could work with additional security mitigations
* attacker can use option 2) as a proxy for malicious content
* attacker can use option 2) as proxy to paid app (buy once, share with world)
** mitigation for this may be responsibility of app developer
* CSP can secure 1) and 2) to an extent
** define baseline CSP policy that apps have to adopt
* See [https://www.adobe.com/devnet/air/articles/introduction_to_air_security.html Intro to AIR security]


=== Types of Runnables ===
=Types of applications=
There are 3 types of installed application.  In additional, many webAPIs are also exposed to regular web content, so that category is included here for context. 


There are 4 (or more) types of possible runnables so far identified on B2G:
==Normal web content==
Not a type of application per our definition of installed apps, but part of the WebAPI security
continuum and so discussed here.
*No app store involved
*No manifest or installation experience
*No restrictions on origin or transport (i.e. HTTPS not required)
*All explicit permissions are requested at runtime, not persisted by default
*Most permissions requested via web intents


* 0) Kernel, drivers (including virtual device drivers), CLI tools(including services), browser engine and (maybe) plug-ins.
==Installed web application==
* 1) Packaged programs (i.e. B2G Gaia apps that are written in HTML/CSS/JS)
Unauthenticated applications provide a manifest, and can optionally be obtained through an app store.
* 2) Installed non-local Web apps (including sites).
*No restrictions on transport but limited to one app per origin (though an app may load assets and code from other origins).  
* 3) Non-installed Web apps (including sites).
*Installation experience with permissions being opt-in at install and runtime, limited to permissions enumerated in the manifest.  
* 4) B2G (Gaia) apps (same as 1) but manually installed in /usr/local, bypassing the Packaging system
*No app store code reviews as they serve no purpose (app can change anytime without user or reviewer consent).
*No SSL indicators, so trust is limited only to content user is willing to share with any website, and maximum privileges are likewise limited to what is available to normal web content.
*All explicit permissions are requested at runtime, showing user the app's data usage intentions, not persisted by default.
*Most permissions requested via web intents
*Same origin enforced


(It seems all type 1 runnables can be implements as type 2 or 0. Maybe
==Installed privileged application==
we needn't treat them as a seperate type)
Authenticated application approved by an app store.  Equivalent in functionality and security to apps on other mobile platforms.
*App is comprised of an explicit list of assets contained in a zip package.
*App is approved by app store after a code review or some equivalent risk management process.
*App store signs the app manifest which contains the list of assets and their corresponding hashes.
*At install app assets are verified & remain stored locally in package.
*Require a Content Security Policy to mitigate content injection attacks and maintain application integrity.
*All explicit permissions are requested at runtime, showing user the app's data usage intentions, and persisted by default.
*User can monitor permission state and change app permissions via consistent permission notification UI
*Privileges granted are limited to explicit list of application assets; we must enforce security boundaries between privileged code and any unprivileged content that the app may also load.
*No same-origin restrictions for app content; same origin still enforced for non-app content.


For type 0 & 1, a deployment mechanism like apt/yum works fine (and
===Why create a "privileged" application type?===
seems required for type 0). But for type 2 & 3, such mechanism may not
Some permissions are sensitive enough that we don't want just any webapp to get access to it. For example, the DeviceStorage API lets a website delete all the pictures in the user's "pictures folder". The API implementation does ask the user for permission before doing this, however we don't feel that it is enough protection for the user if the only thing standing behind the user and 10 years of lost pictures is a simple "do you want to allow this" dialog.
cover. I'm afraid that many apps will be implemented as type 2 or 3
for smooth of (re)deployment (and this is a huge advantage for web
apps to native ones).


=== Trusted store with permissions delegation ===
There are also some APIs that are too hard to explain to the user what consequences approving a certain permission would have, such as raw TCP socket access. For these we can't rely on users making well informed choices and so we need an alternative solution.
{{note|Last updated March 14, 2012}}
* Mozilla (telco store) acts as an authority for permissions requests
* WebApps request permissions in manifest
* Each store contains a set of permissions they can grant
* The "root" store may grant any permissions
* A store (parent) may permit a trusted store (child) to grant a subset of parent's permissions
** {{note|This is opposite of the FLASK model which does not use a permissions hierarchy. There are problems if a child store inadvertently grants too permissive of permissions to an app (genie out of the bottle).}}
** ACME is a root store
** ACME allows Roadrunner Store to grant (Throw, Eat) permissions to WebApps it trusts
** Roadrunner Store may further permit Coyote store a subset of (Throw, Eat) permissions
** Coyote Store may then grant WebApps it trust a subset of what Roadrunner Store granted
* Permissions granted to a WebApp are the intersection of permissions requested by manifest and permissions a store may grant
** WidgetIncApp is listed on ACME store
** WidgetIncApp requests Hammer, Nail permissions
** ACME store has been granted Hammer, Screw permissions by telco
** WidgetIncApp receives (Hammer, Nail)∩(Hammer, Screw) == Hammer permissions
** There was discussion of a "privileged store" which is a store blessed to allow access to certain APIs such as dialer
** "blessed" apps must always be served from the store with access to source code
* Selfhosting of WebApp
** A WebApp can be self-hosted and query a trusted store on install
** The WebApp will be granted permissions based on what the trusted store would have granted the WebApp
*** WidgetInc wants to host WidgetIncApp from widget.lol
*** WidgetInc has already uploaded WidgetIncApp to ACME Store
*** User visits widget.lol to install WidgetIncApp which contains a pointer to ACME Store
*** Runtime queries ACME Store to see what permissions should be given to WidgetIncApp


=== [http://www.cs.utah.edu/flux/fluke/html/flask.html FLASK] and SELinux for enforcing permissions ===
To support this we are also supporting a security model where the store takes on the responsibility of ensuring that an app won't behave maliciously with the permissions that it is granted. So for example the store takes on the responsibility of ensuring that an app won't use TCP sockets to scan for data on internal networks and save it on the developers website. And the store makes sure that an app won't delete all the user's pictures even if the user says ok to granting the app permission to use the DeviceStorage API. At least not without making it abundantly clear to the user that that is what will happen, and gives the user plenty of room for error.


The Flask Architecture makes it possible to implement various Access Control systems.  SELinux is technically an implementation of Mandatory access control based on Flask Architecture.
Several mechanisms are used to enable to store to do this:


* Tested architecture that is used SELinux
* The app will have to be reviewed by the store. Including reviewing all of the code that makes up the app.
* Follows a mandatory access control model where no permissions are granted by default
* The app will be signed by the store to ensure that hacking the store website doesn't allow a hacker to install arbitrary content on users devices.
* There is no inheritance of ACLs / permissions
* The app will use a [https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html CSP] policy to harden the app itself against bugs which would allow an attacker to inject code into the app. This will also make reviewing the app easier.
** If an executable were to change / do something new, it wouldn't have its old permissions: it is given entirely new ones
** However this means that B2G must be broken down into separate executables, communicating via files, sockets etc. (as opposed to running multiple threads and processes sharing the same easily-corruptible memory-space and file descriptors)
* "what you can do (in the new executable) depends on who you were, where you are *AND* what the current executable is."
* Adopting for use in B2G means writing an interface that mediates API / systemcalls
** Suggestion was a JSONRPC service, because even without SELinux, one executable cannot compromise another executable merely across a socket boundary: it would be necessary for the compromised executable to attempt buffer-overruns (etc.) of the service (even if the service was on the same machine).
** Another suggestion is to implement "NCALRPC" in the underlying XPCOM infrastructure, which would allow XPCOM-based components to seamlessly communicate entire functions across executable boundaries.
* API access would be enforced across security contexts
** e.g. A page loaded over HTTPS would be a different context from HTTP. We may grant different access to the former context.
** an app, which for best results would run either its javascript engine or better its own entire gecko engine as a separate executable, would be granted a security context which allowed it only the rights to execute or access other programs (such as a dialer).
** in the case of JSONRPC service(s), the app would be granted SE/Linux permissions to access the URL which activated the dialer (this is one possible implementation)
* use of WebAPIs in the current implementation is ''impossible to properly protect against compromise''. '''once a process or thread is compromised, all other threads and processes must also be considered to be compromised'''.


Full Discussion on NSA's SE-Linux Mailing List:
=== Default CSP policy ===
http://marc.info/?l=selinux&m=133190422130989&w=2


Summary points of Discussion on NSA's SE-Linux Mailing List:
The CSP policy applied to all privileged and certified apps is:


* As B2G is based on Android, it may be worthwhile investigating http://selinuxproject.org/page/SEAndroid
<code>default-src *; script-src 'self'; object-src 'none'; style-src 'self'</code>
** Apart from anything it will save time on developing the base permission set (to cover the main OS)
** SE-Android is being developed by the NSA ''specifically'' to avoid the need for Android developers to get involved with the "low-level" SE-Linux permissions system.
* ''Stephen Smalley (NSA) has the following recommendation'':  See http://www.nsa.gov/research/selinux/related.shtml for some links to work done to apply Flask to various other applications like PostgreSQL, Xorg, and D-BUS.
** Following Stephen's recommendation would allow the creation of very special permissions that are specifically relevant to B2G, for proper enforcement at the Linux Kernel level.


=== Debian Keyring (Package Management) for distribution of apps ===
This puts the following restrictions on pages in privileged apps:


The primary advantage of apt (or yum) package distribution is that it uses person-orientated PKI as the fundamental basis of trust. By contrast, SSL PKI is host-based and thus any distribution model that relies solely on SSL PKI will be tied solely and exclusively to that host. Debian packages, however, being GPG-signed by people, can be distributed without limit or restriction, not even requiring a network (CD or other offline media is possible and supported).
* Scripts can only be loaded from the package.
* Scripts can not use data:-URIs
* Inline scripts can not be used
* eval() can not be used. Neither can eval-like functions like setTimeout or "new Function". setTimeout can still be used as long as the first argument is a Function object rather than a string.
* onXXX attributes can't be used in the markup of pages. You can still write javascript code like <code>myelement.onXXX = someFunction;</code> as long as you don't assign onXXX to a string, but rather to a Function object.
* <object>, <embed> and <applet> are fully disabled. In other words, plugins won't work at all. Including flash.
* CSS can only be loaded from the package. Inline CSS is however allowed.


* Last updated March 14, 2012
This does not restrict any of the following:
* Items in () denote the equivalent in WebApp world
* infrastructure already exists
* Code is cryptographically signed by multiple parties
** Package (WebApp) maintainer (author / company)
** Package is signed by FTP masters (marketplace / store?)
* Signed packages / manifests are separate from binaries (HTML content)
** We need a way to verify that the WebApp content has not changed
* The runtime checks that the binary+signature match and that the signature originates from a trusted keyring (store)
* A user may choose to add more sources (stores)
* A user must add the source's keyring (store's public key?) to disable warning about untrusted source
* To compromise an app with proper code signing requires the following extremely difficult tasks to be carried out:
*# compromise the site hosting the app
*# compromise the keys (developer *and* FTP master) signing the app (assuming you require app updates to be signed with the same key)
*# compromise or trigger the update mechanism for the app
*# wait for updates to trickle out


==== dealing with rogue applications ====
* <code>&lt;iframe>s</code> can still point to any URL.
* Images can still be loaded from anywhere. Including when loaded using an <code>&lt;img></code> element, when using CSS background images or when using other types of CSS images.
* Media (audio and video) can still be loaded from anywhere.
* Network connections can still be opened anywhere using data-centric APIs like <code>XMLHttpRequest</code> or <code>WebSocket</code>.


this section covers how an application may be replaced if discovered to be malicious
There is no way for privileged apps to relax this policy. However we may in the future add the ability for packaged apps to define their own CSP policies, in which case that would allow apps to apply more restrictive policies. However such policies would be merged with the above policy which means that it still wouldn't allow the app to relax the policy.


* automatic updates must be enabled (apt-get upgrade)
==Certified application==
* people who wish to remain on a "stable" store must have a security-line equivalent to "deb http://security.debian.org/.... "
This category is reserved for apps that require approval by carrier or OEM due to risk of
* rogue applications have a package with a version number "1 higher" than the rogue application's previous package
device corruption or risk to critical functionality. These include apps such as the system settings app, default dialer (to ensure emergency services are always accessible), core radio and power management, etc. Not intended for 3rd party applications. Similar to Privileged apps, except:
* the updated package can:
*All permissions are implicit.
** be a properly bug-fixed version
*User cannot modify permissions (as it could break the device; ex. disable settings permission for the settings app)
** contain warnings that the user must explicitly agree to prior to acceptance
*Approval of certified apps is limited to explicit list of authorized app stores.
** in extreme cases simply replace the files with a blank app that announces "This Application Caused Serious Problems, It Had To Go, Make Sure You Check Your Data N System N Stuff".
*Require the same Content Security Policy as Privileged apps
*Not a common application type; reserved only for critical applications


==== debconf shim for B2G / gaia apps ====
==Application Scope==
Foundational assumption was that there was only one app per domain.  This is because an origin is effectively the only security boundary in the browser, and determining the security implications of allowing apps with different permissions on the same domain is a time consuming exercise for the 1.0 timeframe.


This section is best understood after examining an existing debconf frontend such as debconf-kde-helper in debian, or ubiquity-frontend-debconf in ubuntu.  There is also an application in debian called "gkdebconf" which should also be examined.  All of these applications communicate with debconf whilst applications are being installed and configured.  The front-end deals with presentation of questions to the user, and relays their responses to the installation process.
Note that privileged and certified apps have their own unique origin via the app:// scheme.


The proposal is therefore very simply to write a debconf front-end which is also a gaia application.  Below is a description of the process.
=Permissions=
This sections describes the permission model for applications.


# a user goes to a store (GUI front-end TBD)
== Extended permissions ==
# this "store" triggers the command "sudo apt-get update" in the background (or this occurs on a regular basis)
# they go "i wanna app wiv a cherry on top"
# the selection fires off a LOCAL COMMAND "sudo apt-get install cherry-on-top".
# the GUI uses the dpkg / debconf communication system to inform them of progress
# the GUI then walks them through the security questions (which is all part of debconf)
* we would distribute a debconf frontend app for B2G
* B2G app communicates with dpkg/debconf through something like a unix pipe
* the fetching of the app is an implementation detail, FTP, rsync, HTTPS doesn't matter as long as the package is properly signed
* B2G app only receives  progress updates
* it may be possible to leverage the existing Debian package infrastructure
** {{note|If leveraging the good-will of debian to host B2G and also Gaia apps, there may be license (advertising clause) issues that need to be resolved}}


==== New URI proposal (apt:// or yum://) ====
Applications can be granted additional privileges on top of the ones granted to normal websites. By default an application has no permissions on top of the ones normal webpages have. In order to get additional permissions, the first step is for the app to enumerate the additional permissions it wants in the application manifest.


This is a very simple proposal to allow applications to be installed in a familiar way (URLs) yet allow the installation process to go through security checks with the minimum of additional programming and modifications to the B2G codebase.  A URI could be embedded into application pages (JS or static HTML) for example "apt://phonedialer".
For each additional permission that an app wants, the manifest has to explicitly enumerate that permission along with a human-readable description of why the app wants access to that permission. This description will be surfaced at various points in the UI, and is also used when the app is reviewed.


In the instance where that application - phonedialer - has already been installed, the application is activated.  However, if the application has not been installed, B2G would hand off the command to apt (or yum, if yum is selected instead).  Instead of firing up the application, the debconf shim (see section above) would be activated.  This would show the download progress (of both the package and its dependencies), check the digital signatures, run through the installation process including presenting the security questions.  Finally at the end, the debconf B2G-aware front-end would be closed, and the application opened up instead.
An example of a fragment of a manifest:


The syntax for the URI could also be extended to include the specific version of the package to be installed (if required). apt://packagename?version=1.2.1 for example. Also, different archives (stores) could be specified.  Doing so would require an additional step in the installation process to add that store to the /etc/apt/sources.list file, requiring the permission of the user before doing so.
  permissions: {
  browser: {
    description: "To enable showing web pages";
  };
  "wifi-information": {
    description: "To alert you about unencrypted wifi networks in your area";
  }
  }


Overall this approach has several technical advantages as well as being very simple to understand.  If a package is wanted, put "apt://{packagename}" in a B2G web page, anywhere online.  B2G devices will know what to do, and will install the package if it's not already available.
== Privileged-app-only Permissions ==


For developers however the deployment of the infrastructure required to host an entire debian archive may be too much. In such circumstances however there is a very simple additional proposition which takes care of that: either a deb:// URI or simply to activate installation and execution of packages when a "http://{fqp}/packagename.deb" URL is encountered.
Some permissions are sensitive enough that we don't want to just hand them to any app. For example a permission which enables pages to read or modify pictures from the users picture folder is very sensitive. For such an API we in addition to requiring the app to enumerate the permission in the app manifest, require that the app is a "Privileged App". See details about this in the section for Privileged Apps below.


=== Permissions manager ===
== Permission Prompts ==
* User can deny permissions at install time
* User can always go to manager to see what permissions an app has been granted
* User can modify permissions through the manager
* Certain APIs are defined as "sensitive"
** Sensitive APIs will request "capabilities" e.g. access USB, access wifi
* Levels of access for capabilities
** Allow
** Prompt (default to remember)
** Prompt (default to not remember)
** Deny
*** There were concerns that the levels should only be Allow/Deny
* Contractual enforcement of permissions
** WidgetInc may come to Mozilla (telco) with request for access to sensitive APIs
** Mozilla (telco) may draft a contract with WidgetInc giving them access to the sensitive APIs under certain conditions
* WebApps may be granted default permissions
** e.g. access to storage, access to change context menu
* capabilities may be restricted based on technical restrictions of the site
** e.g.  strict-transport security, EV-certificate
==== Kernel permissions manager ====


{lkcl.15mar12.2223hrs - it's not clear to me what this section refers to: a userspace application that interacts with the user to help them select the level of access that they wish to grant to a particular application, or to the actual kernel-side implementation that enforces the permissions, or a developer "assistance" suite of software which helps the developer to create the permission set that's to be associated with the application when it's installed}
Just because a permission is enumerated in the manifest doesn't mean that an app will be automatically granted that permission at time of installation. For many APIs, like the wifi-information API, enumerating the permission in the manifest simply means that the app can attempt to use it. When used, the user will be prompted and asked if it's ok to grant the permission to the app. During this prompt, the description provided in the manifest will be displayed to the user. However it will be displayed in such a way that it is clear that the description comes from the app developer, and not from B2G itself.


* separate process that controls access to permissions
The overall flow will be:
* responsible for
* All permissions prompts are at runtime, at the time of the corresponding API request
*# query permissions, true/false if permissions X is granted
* User may be able to review permissions which may be requested at install time via a pulldown, but cannot set them
*#* support for prompting user in event permission isn't granted
* Implicit permissions for each application type are not visible or user controllable (classified as low-risk)
*# add / remove permissions
* Permissions for high risk APIs are prompted for at runtime with a corresponding rationale (data usage intention) for the request
*# audit permissions
* Permissions that could compromise the system are available only to certified apps and therefore never prompted for
*# support observers for permission change
* Full details of implicit vs explicit permissions for each WebAPI are available here: https://wiki.mozilla.org/WebAPI
* permissions requested are based on "uri signatures"
** to be determined what the signature is: domain, partial url, other?
* permissions representation
** type - usb, web, radio, etc
** uri signature
** value
** source - user, manifest, system
** expiration type - never, time-based, session, other?
** expiration time
** allow message - for UI / prompting user
** deny message
* app obtains permission by querying / asking central process
* OS support required for properly constructing signature, app should not be able to influence this
** there needs to be a unique identifier than an app can't spoof
* permissions requests can be cached
** cache needs to be invalidated on permission change


=== Other (topics that don't fall into above proposals) ===
== Implicit access ==
* Last updated March 14, 2012
* SSL should be used for content delivery
** can provide authentication for client-store communication
*** complicated compared to code signing since each mirror will either need same key or store/app needs to know each valid mirror
** provides end-to-end security
** does not address concerns of a malicious app
* W^X / NX for WebApps
* should the JS "eval" function have a permission added to it?
* bypassing the official package system speeds up app development
** at the risk of destabilising a system!
** should still be allowed though (with caveat that warranty just got voided)
** concept of /usr/local and /usr should be mirrored in B2G with e.g. /usr/gaia/apps and /usr/local/gaia/apps
* self-host discussion http://groups.google.com/group/mozilla.dev.b2g/msg/b079d34ccdec0f85
** The scenario is that we have an untrusted store attempting to sell an app which is hosted on a trusted store, how is this solved?


==== The Problem With Using SSL ====
Not all permissions will result in the user getting prompted when the permission is first used. In some cases it's very hard to describe to the user what granting the permission means.


SSL is a host-based PKI infrastructure.  Thus, it ties everything to hosts.  Hosts become the target for attacks; hosts become the weak link; hosts become subject to scalability, which, in the context of a million hits a day from a hundred million mobile phones, instantly highlights that SSL is wildly inappropriate (by contrast, the various well-established and proven GNU/Linux distributions use ''person''-based PKI, based around GPG/PGP).
In this situation we can't rely on the user to make the security decision. Instead we will have to rely on a technical code-review of the app before it is published in a store to ensure that the app doesn't do anything it shouldn't with the extended permission. See the "Privileged apps" section above for how this works.


One problem is that SSL (when used with PKI Certificates for Authentication, aka Certificate 'pinning') is that the solution becomes the problem.  When a device may '''only''' download from a site over HTTPS where only those devices which have the appropriate public key may connect to that site, then if the app becomes popular then the site will quickly be overwhelmed.
In this situation access is granted implicitly at install time.


The other problem with relying solely on SSL is that it requires trusting the full set of root certificates on the device. This is obviously not a B2G/OWA specific problem but it does seem to be a little worse in this case, '''especially''' in hostile environments when the government has or can easily obtain a root cert. This is why we sign desktop Firefox updates as well as verifying them against a hash downloaded over SSL. Defense in depth.
''Open question'': Should we enable users looking at the list of prompted and implicit permissions at the time of installation?


The third problem can be expressed as "faith in SSL is fairly low".  In other words, the difference between HTTP and HTTPS is so small that people may be tempted to just start using HTTP, because setting up SSL and getting a PKI Certificate set up is "too inconvenient".
== <code>access</code> property ==


The fourth problem is that SSL doesn't protect against a Server being compromised.  In fact, it would give a false sense of security as the SSL Certificate may have been compromised without the server admin's knowledge.
For some APIs there is an additional "access" property which allows specifying if the app wants read, write or create access. This looks like:


== Open questions ==
permissions: {
# What happens when a WebApp is revoked?
  contacts: {
#* removed from store?
    description: "To find friends to send your awesome high-scores to.";
#* removed from user device?
    access: "readwrite";
#* refund?
  };
# What is the identifier used when a WebApp is revoked?
}
#* origin (scheme + host + port)
 
#* certificate / hash embed inside WebApp manifest
Valid values for the access property are:
# Should eval() and similar functions be considered sensitive APIs / restricted?
* "readonly": Ability to read data and be notified about changes to data. No ability to write data at all.
#* Adobe AIR restricts eval() in the application sandbox [http://help.adobe.com/en_US/air/html/security/WS485a42d56cd1964150c3d3a8124ef1cbd62-7ffe.html (docs)]
* "createonly": Ability to create new data. Not read, modify any existing data.
# Should self-signed certificates be allowed?
* "readcreate": Ability to read existing data as well as create new data. No ability to modify existing data.
# What would be signed?
* "readwrite": Full ability to read and modify any data.
#* CSS
 
#* scripts
In the above, deleting existing data counts as modifying it.
#* content
 
#* other
These access levels aren't surfaced to the user at all. They are only there as a level of protection and to help during the code review of the app to determine what they need to look for while reviewing an app. So for example in an app which is requesting "createonly" access to the Contacts API doesn't have to be reviewed to see if it is doing anything unexpected with read contacts information (such as save it to the server without first asking the user), since the app can't ever read contact information.
 
But even for an app which requests "readwrite" access to the Contacts API, as soon as the app performs a reading or writing operation B2G will prompt the user about permitting access, and if the user grants access, full read and write access will be granted. There is no need for additional prompts assuming that the user checks the "remember this decision" checkbox.
 
''Open Question'': We could surface in the prompt which of the above four types are being requested. It wouldn't increase the number of prompts that we have, but it would mean having to deal with what happens if the access changes for example from "readonly" to "readcreate" during an update.
 
==Data Usage Intentions==
The data usage intentions (provided by apps as a rationale for a permission) can serve many purposes to help users with choice and control over their data.
 
== On the Hook ==
Apps that make promises via usage intentions have essentially provided assurance to the user that their data will be used in a certain way.  If it turns out the app developers use the data for another purpose (say actually recording Stashy photos and posting them on a public twitter feed), users have a clear way to explain how the app is operating deceptively.
 
== Pre-Validation with Privacy Policies ==
Many apps will have a privacy policy.  An app store has the opportunity to pre-screen apps based on the usage intentions in their manifest and the privacy policy they provide.  So long as the two are consistent, users have a commitment from the app about what it intends to do with their data.  Apps that are not consistent or vague can be rejected from an app store.
 
== Auditing ==
To provide a "trail of activity", B2G or other app runtime could additionally maintain a capability-access log for each app that keeps track of requests for capabilities and the usage intentions over time.  That way a curious user could analyze the log to see how often an app used a permission, why it used it, and perhaps help illustrate abuse of their consent.
 
==Network access==
Network access is assumed as an implicit permission for all apps (as it seems strange to prevent access to something all web content normally has).  However the issue of network consumption has been raised as a valid concern. 
 
Its not clear this is an issue for the security model to solve however, and would be better solved via an explicit consumption API that can help the user manage and limit resource utilization.  Considered out of scope for the security model in general.
 
==Background Apps==
Apps running in the background may trigger permission requests.  Since app requests should be in context of the user's interaction with the app, we should suppress any permission requests for non-foreground apps.  It is up the developer to properly surface permissions requests while the app is interacting with the user.
 
==Background Services==
Services need to be certified apps as they have no way of surfacing permission requests to users since they have no UI.  This means we should minimize the set of use cases that absolutely require true services.
 
==Power User==
Power users should be able to override the default trust roots to allow them to install arbitrary apps as privileged or certified.  This is highly dangerous and should include a correspondingly strong disclaimer or equivalent workflow.
 
==Same Origin Policy==
Same origin policy should not be enforced for certified apps or privileged apps, since each app has its own cookie store.  The app would have to declare its intent to bypass same-origin policy.
 
== Permission Manager ==
 
= Application Sandboxing =
 
== Data stored per app ==
 
Each application runs in as a separate sandbox, meaning that all data stored by an application is separate from all data stored by another application. This includes things like cookie data, localStorage data, indexedDB data and site permissions.
 
This means that if the user has two apps installed, App A and App B, these apps will have completely different set of cookies, different local data and different permission. This even applies if both of these apps open an <iframe> which point 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 Bs ability to interact with the users 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 open 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 users 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 different than as 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 by 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, and so 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 website through several apps, he/she will have to log in in every app. Likewise, if a website wants to store data locally, and the user interacts with this website 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 3rd 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 of 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 types of attack for getting at the users facebook data by exploiting bugs or other shortcomings in the facebook website.
 
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 ==
 
And just like website data is sandboxed per app, so are permission grants. 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. This means that 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://maps.google.com still has to ask the user for permission before geolocation access is granted.
 
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 where the scripts and resources are loaded within. The scripts and resources <i>belong</i> 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 - i.e. 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, that will open an iframe which will receive a set of cookies for the http://maps.google.com website. If the user then navigates inside web content area, i.e. inside the <iframe mozbrowser>, to http://maps.google.com, this will use different cookies and different permissions than 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.
 
The security model can be shown in a simple picture
 
<pre>
+---------------------------------+
| APP-001                        |---->App-Sandbox
|   ----->Cookie-A
|   ----->indexedDBStorage-A
|          |
|  +--------------------------+  |
|  + http://maps.google.com  +-------->Internal-Sandbox
|  +--------------------------+  |
|  |       |  |
|  |       |-->Cookie-B
|  |       |-->indexedDBStorage-B
|  |    +------------------+  |  |
|  |    | maps.google.com  |  |  |
|  |    +------------------+---------->iFrame opened in web-app
|  |    |                  |---------->Cookie-C
|  |    |                  |  |------->indexedDBStorage-C
|  |    |                  |  |  |
|  |    |                  |  |  |
|  |    +------------------+  |  |
|  +--------------------------+  |
|   |
+---------------------------------+
 
 
 
 
+---------------------------------+
| APP-002                        |---->App-Sandbox
|   ----->Cookie-D
|   ----->indexedDBStorage-D
|          |
|  +--------------------------+  |
|  + http://maps.google.com  +-------->Internal-Sandbox
|  +--------------------------+  |
|  |       |  |
|  |       |-->Cookie-E
|  |       |-->indexedDBStorage-E
|  |    +------------------+  |  |
|  |    | maps.google.com  |  |  |
|  |    +------------------+---------->iFrame opened in web-app
|  |    |                  |---------->Cookie-E
|  |    |                  |  |------->indexedDBStorage-E
|  |    |                  |  |  |
|  |    |                  |  |  |
|  |    +------------------+  |  |
|  +--------------------------+   |
|   |
+---------------------------------+
</pre>
 
== Apps can run content from many domains ==
 
As has been discussed above, an app can always contain content from multiple domains. This is exactly like how a website today can create an <iframe> pointing to a different domain.
 
But just like for websites today, a webpage which contains an <iframe> pointing to a different origin can't reach into that iframe and modify or touch the objects there. And like with normal websites, permissions are separated by origin, meaning that just because a permission is granted to an app, doesn't mean that any <iframe>s that that app opens has access to the same permissions.
 
== Data management ==
 
appid/browserContent flag in B2G
separate profiles on desktop/android
 
== Process sandboxes ==
 
=Application Lifecycle=
This section describes the format, installation and updates process for applications.
 
== Delivery mechanisms ==
 
B2G will support two formats for distributing apps, "hosted" and "packaged". Hosted apps work much like websites do today in that the resources for the app are located on a webserver and loaded through http. These can be cached for faster startup, but they still generally are delivered a lot like a normal website.
 
Packaged apps are delivered as a .zip file which contains the resources that the app consists of.
 
Generally speaking, it's entirely up to the app developer to choose between hosted or packaged apps. There are no differences as far as capabilities goes.
 
However, there are some APIs that are only available to "Privileged Apps", which currently requires the app to be packaged due to signing requirements. See section below for Privileged apps.
 
== Hosted apps ==
 
A hosted app consists solely of an [http://mozilla.github.com/webapps-spec/ application manifest] file on the developer's web server. Often the manifest will also point to an appcache manifest which allows an app to be cashed for faster startup and to enable offline usage, but otherwise doesn't affect the app at all.
 
From a security point of view, hosted apps work very much like normal websites. When a hosted app is loaded, the URL of the loaded pages are the normal URLs that those pages have on their web server. So to link to a specific page or resource in the app, the same URL is used as when linking to that page or URL on the website.
 
This doesn't change the fact that hosted apps, like all apps, are subject to the application sandbox described above.
 
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 website 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.
 
==Packaged apps ==
 
The second distribution format that B2G will support is packaged apps. A packaged app consists of a normal zip file which contains both the manifest and the application resources. When a packaged app is installed, the zip file is downloaded and the manifest is read from a well-known location inside the zip file.
 
Unlike a hosted app, packaged apps doesn't have an obvious URL that their resources can be loaded from. The way to refer to a resource in a packaged app is by using the <code>app:</code> protocol. The format for a <code>app:</code> URL is as follows
 
<code>app://identifier/path/within/zipfile/file.html</code>
 
The <code>identifier</code> is a uuid generated at install time. This identifier will remain constant as long as the app is installed. (Eventually the identifier might become the ''home domain'' of the app, but we don't have such a concept yet).
 
Whenever a resource is loaded using the <code>app:</code> protocol, this will only allow loading resources from the zip file associated with the current app. I.e. if you specify an <code>identifier</code> for another app, it will behave exactly as if you specify an invalid identifier or an identifier for an app which isn't installed.
 
Relative links within <code>app:</code> works just like relative links within <code>http:</code>. Simply using a URL like &lt;img src="/images/picture.jpg"> will load the image named "images/picture.jpg" in the zip package. You can also use markup like &lt;a href="foo/bar.html"> to refer to a page relative the current page.
 
''Open question'': We probably need to allow linking to an app:// page. However we could forbid putting an app:// page in an &lt;iframe>. Other than by other app:// pages of course.
 
One important thing to note about this is that the app protocol doesn't have a concept of a domain. In other words, packaged apps aren't same-origin with any "normal" websites. This is because we don't know the home domain of the developers or the app. We only know which store was used to install the app.
 
A result of this is that any time XMLHttpRequest is used to read data from a website, it's considered a cross-origin read and so the website has to support CORS. Eventually we'll want to enable packaged apps having a home domain, but that's not yet supported.
 
Just like with hosted apps, we want to make sure that a hosting website can't be tricked into hosting a app package. The risk is fairly low even if that could happen since even if the user got an app installed, as mentioned above, that app won't be same-origin with the website that the package came from. However to be safe we still apply the same security restrictions as for hosted apps. I.e. the package has to be served with a specific MIME type, or has to be same-origin with the page installing the package.
 
More information about why we developed a packaged apps solution is available here: [[Apps/PackagingProposal]]
 
==Format for privileged and certified apps==
We need an application delivery mechanism that provides assurances on app integrity and authenticity, and also allows for well-defined application & privilege scope enforcement so integrity can be maintained at runtime.
 
Thus all privileged and certified apps will be in packaged format.  This package will be provided to the app store for the review, which will then sign it upon approval.  Upon installation, the client will verify that the signature is valid and chains to a privileged app store.
 
Privileged and certified apps will be accessed via a unique scheme (app://).  The domain will correspond to the app id.
 
== App Signing ==
 
''Definition of the signing format goes here.''
[https://wiki.mozilla.org/Apps/PrivilegedApplication/SigningService Signing Service]
 
== Updates ==
 
A lot of the update model is still being defined. Requirements are being collected here at [[Gaia/System/Updates]]
 
==Privileged Application Review Guidelines==
We need a set of guidelines that define an acceptable level of security and privacy review for privileged applications.  This should include:
*Ensuring that requested permissions are used for the purposes stated (in the permission rationale)
*Use of implicit permissions is appropriate
*Any interfaces between privileged app content and unprivileged external content have appropriate mitigations to prevent elevation of privilege attacks
 
The store is responsible for reviewing the app to ensure that it doesn't do anything dangerous with the permissions it is granted.
 
Since the OpenWebApps API allows any website to become a store, only stores approved by B2G will be allowed to install Privileged apps. Our goal is that multiple stores will become approved for installing privileged app, but given how much responsibility is put on the store, we need to ensure that we put agreements in place to protect users before approving a store for being allowed to install privileged apps.
 
=Out of scope for 1.0=
==Magic button==
This is a proposal to used a privileged button that grants access to certain APIs (camera, for example).  This button would be located in the app's UI but rendered by the OS.  It would have a consistent look & feel, and could not by styled, overlaid or obscured by the app. 
 
Clicking this button would implicitly enable access to the camera.  Clicking this button again (or providing a separate stop button) would turn off access again. 
 
This is out of scope for 1.0.  We do not have the time to fully understand the design and implementation issues with this approach, but it has a lot of merit and we will investigate it further for a subsequent release.
==USB, Bluetooth, and NFC access==
… for 3rd party apps.  These have not been identified as priority use cases for 1.0 and require substantial research.  We will support these in a subsequent release.
==Certified apps as a 3rd party use case==
We may someday have use cases that require certified 3rd party apps, but at this time all 3rd party apps that have been identified can be effectively implemented as privileged apps from a security and UX standpoint.  We have no plans to support 3rd party apps as certified apps.

Latest revision as of 22:28, 10 December 2012

The intent of this page is to provide some background for how security works in B2G and Desktop/Android OpenWebApps. The target audience for this page is (at least for now) primarily people working on implementing B2G and the Open Webapps runtimes. Over time we should improve the pieces that affect web developers such that they can be used as developer documentation.

Note: This is the official reference for the Apps and FirefoxOS Security Model. Please do not edit this page without first discussing changes in dev-webapps@lists.mozilla.org

Open Web Apps Security and Privacy Model

Introduction

The open web application security and privacy model spans a wide variety of use cases, from typical web content to system-critical applications. As such, a one-size-fits-all security model won't work. Instead we need a range of options that balance out the flexibility and common design patterns for web applications while mitigating the additional risks that come with exposing sensitive APIs. Additionally, providing users as-necessary insight into app use of their data helps them make more informed risk/reward decisions as they install apps and grant permissions.

Discussion and Resources

List of webAPIs and corresponding security discussions: WebAPI

Implementation tracking bug basecamp-security

Installation and updates: Gaia/System/Updates

B2G OS and process security model: B2G/Architecture/Runtime_Security

Foundational Principles

  • Maintain core strengths and flexibility of the web
  • Protect the security and privacy of the user
  • Protect the device from poorly written & malicious applications
  • With additional privileges come additional responsibilities for the developer and app store
  • User choice and control - treat the user with respect and present them with choices that allow them to make informed decisions. See our privacy operating principles [1], specifically "Real Choices."

Definitions

Explicitly granted permissions

Permissions that need to be enumerated in the manifest and require user consent at "time of use" to enable, whether via a prompt or an in-content user mediated UI. The user can also inspect and modify the explicit permissions for any app via the permissions manager. When the user is prompted for explicit permissions, they need to be informed what is requested, why it's requested, and how the app will use data obtained through this permission.

Implicitly granted permissions

Permissions which are enumerated in the manifest and granted to that type of application without requiring any user interaction. The user may be able to inspect, but not modify, the implicit permissions that an app requests via the permissions manager.

Data Usage Intention

Apps can make a commitment to users about their intended uses of data collected through a given API (for which the user is grants a permission). This is a short string that reflects to users what risk might surface by granting an app permission to use the given API. Users can leverage this Usage Intention to decide whether the value provided by the app is worth the risk or not. Usage Intentions are attached to permissions as an annotation of not only why the permission is needed, but what the app will do with the data.

Types of applications

There are 3 types of installed application. In additional, many webAPIs are also exposed to regular web content, so that category is included here for context.

Normal web content

Not a type of application per our definition of installed apps, but part of the WebAPI security continuum and so discussed here.

  • No app store involved
  • No manifest or installation experience
  • No restrictions on origin or transport (i.e. HTTPS not required)
  • All explicit permissions are requested at runtime, not persisted by default
  • Most permissions requested via web intents

Installed web application

Unauthenticated applications provide a manifest, and can optionally be obtained through an app store.

  • No restrictions on transport but limited to one app per origin (though an app may load assets and code from other origins).
  • Installation experience with permissions being opt-in at install and runtime, limited to permissions enumerated in the manifest.
  • No app store code reviews as they serve no purpose (app can change anytime without user or reviewer consent).
  • No SSL indicators, so trust is limited only to content user is willing to share with any website, and maximum privileges are likewise limited to what is available to normal web content.
  • All explicit permissions are requested at runtime, showing user the app's data usage intentions, not persisted by default.
  • Most permissions requested via web intents
  • Same origin enforced

Installed privileged application

Authenticated application approved by an app store. Equivalent in functionality and security to apps on other mobile platforms.

  • App is comprised of an explicit list of assets contained in a zip package.
  • App is approved by app store after a code review or some equivalent risk management process.
  • App store signs the app manifest which contains the list of assets and their corresponding hashes.
  • At install app assets are verified & remain stored locally in package.
  • Require a Content Security Policy to mitigate content injection attacks and maintain application integrity.
  • All explicit permissions are requested at runtime, showing user the app's data usage intentions, and persisted by default.
  • User can monitor permission state and change app permissions via consistent permission notification UI
  • Privileges granted are limited to explicit list of application assets; we must enforce security boundaries between privileged code and any unprivileged content that the app may also load.
  • No same-origin restrictions for app content; same origin still enforced for non-app content.

Why create a "privileged" application type?

Some permissions are sensitive enough that we don't want just any webapp to get access to it. For example, the DeviceStorage API lets a website delete all the pictures in the user's "pictures folder". The API implementation does ask the user for permission before doing this, however we don't feel that it is enough protection for the user if the only thing standing behind the user and 10 years of lost pictures is a simple "do you want to allow this" dialog.

There are also some APIs that are too hard to explain to the user what consequences approving a certain permission would have, such as raw TCP socket access. For these we can't rely on users making well informed choices and so we need an alternative solution.

To support this we are also supporting a security model where the store takes on the responsibility of ensuring that an app won't behave maliciously with the permissions that it is granted. So for example the store takes on the responsibility of ensuring that an app won't use TCP sockets to scan for data on internal networks and save it on the developers website. And the store makes sure that an app won't delete all the user's pictures even if the user says ok to granting the app permission to use the DeviceStorage API. At least not without making it abundantly clear to the user that that is what will happen, and gives the user plenty of room for error.

Several mechanisms are used to enable to store to do this:

  • The app will have to be reviewed by the store. Including reviewing all of the code that makes up the app.
  • The app will be signed by the store to ensure that hacking the store website doesn't allow a hacker to install arbitrary content on users devices.
  • The app will use a CSP policy to harden the app itself against bugs which would allow an attacker to inject code into the app. This will also make reviewing the app easier.

Default CSP policy

The CSP policy applied to all privileged and certified apps is:

default-src *; script-src 'self'; object-src 'none'; style-src 'self'

This puts the following restrictions on pages in privileged apps:

  • Scripts can only be loaded from the package.
  • Scripts can not use data:-URIs
  • Inline scripts can not be used
  • eval() can not be used. Neither can eval-like functions like setTimeout or "new Function". setTimeout can still be used as long as the first argument is a Function object rather than a string.
  • onXXX attributes can't be used in the markup of pages. You can still write javascript code like myelement.onXXX = someFunction; as long as you don't assign onXXX to a string, but rather to a Function object.
  • <object>, <embed> and <applet> are fully disabled. In other words, plugins won't work at all. Including flash.
  • CSS can only be loaded from the package. Inline CSS is however allowed.

This does not restrict any of the following:

  • <iframe>s can still point to any URL.
  • Images can still be loaded from anywhere. Including when loaded using an <img> element, when using CSS background images or when using other types of CSS images.
  • Media (audio and video) can still be loaded from anywhere.
  • Network connections can still be opened anywhere using data-centric APIs like XMLHttpRequest or WebSocket.

There is no way for privileged apps to relax this policy. However we may in the future add the ability for packaged apps to define their own CSP policies, in which case that would allow apps to apply more restrictive policies. However such policies would be merged with the above policy which means that it still wouldn't allow the app to relax the policy.

Certified application

This category is reserved for apps that require approval by carrier or OEM due to risk of device corruption or risk to critical functionality. These include apps such as the system settings app, default dialer (to ensure emergency services are always accessible), core radio and power management, etc. Not intended for 3rd party applications. Similar to Privileged apps, except:

  • All permissions are implicit.
  • User cannot modify permissions (as it could break the device; ex. disable settings permission for the settings app)
  • Approval of certified apps is limited to explicit list of authorized app stores.
  • Require the same Content Security Policy as Privileged apps
  • Not a common application type; reserved only for critical applications

Application Scope

Foundational assumption was that there was only one app per domain. This is because an origin is effectively the only security boundary in the browser, and determining the security implications of allowing apps with different permissions on the same domain is a time consuming exercise for the 1.0 timeframe.

Note that privileged and certified apps have their own unique origin via the app:// scheme.

Permissions

This sections describes the permission model for applications.

Extended permissions

Applications can be granted additional privileges on top of the ones granted to normal websites. By default an application has no permissions on top of the ones normal webpages have. In order to get additional permissions, the first step is for the app to enumerate the additional permissions it wants in the application manifest.

For each additional permission that an app wants, the manifest has to explicitly enumerate that permission along with a human-readable description of why the app wants access to that permission. This description will be surfaced at various points in the UI, and is also used when the app is reviewed.

An example of a fragment of a manifest:

permissions: {
  browser: {
    description: "To enable showing web pages";
  };
  "wifi-information": {
    description: "To alert you about unencrypted wifi networks in your area";
  }
}

Privileged-app-only Permissions

Some permissions are sensitive enough that we don't want to just hand them to any app. For example a permission which enables pages to read or modify pictures from the users picture folder is very sensitive. For such an API we in addition to requiring the app to enumerate the permission in the app manifest, require that the app is a "Privileged App". See details about this in the section for Privileged Apps below.

Permission Prompts

Just because a permission is enumerated in the manifest doesn't mean that an app will be automatically granted that permission at time of installation. For many APIs, like the wifi-information API, enumerating the permission in the manifest simply means that the app can attempt to use it. When used, the user will be prompted and asked if it's ok to grant the permission to the app. During this prompt, the description provided in the manifest will be displayed to the user. However it will be displayed in such a way that it is clear that the description comes from the app developer, and not from B2G itself.

The overall flow will be:

  • All permissions prompts are at runtime, at the time of the corresponding API request
  • User may be able to review permissions which may be requested at install time via a pulldown, but cannot set them
  • Implicit permissions for each application type are not visible or user controllable (classified as low-risk)
  • Permissions for high risk APIs are prompted for at runtime with a corresponding rationale (data usage intention) for the request
  • Permissions that could compromise the system are available only to certified apps and therefore never prompted for
  • Full details of implicit vs explicit permissions for each WebAPI are available here: https://wiki.mozilla.org/WebAPI

Implicit access

Not all permissions will result in the user getting prompted when the permission is first used. In some cases it's very hard to describe to the user what granting the permission means.

In this situation we can't rely on the user to make the security decision. Instead we will have to rely on a technical code-review of the app before it is published in a store to ensure that the app doesn't do anything it shouldn't with the extended permission. See the "Privileged apps" section above for how this works.

In this situation access is granted implicitly at install time.

Open question: Should we enable users looking at the list of prompted and implicit permissions at the time of installation?

access property

For some APIs there is an additional "access" property which allows specifying if the app wants read, write or create access. This looks like:

permissions: {
  contacts: {
    description: "To find friends to send your awesome high-scores to.";
    access: "readwrite";
  };
}

Valid values for the access property are:

  • "readonly": Ability to read data and be notified about changes to data. No ability to write data at all.
  • "createonly": Ability to create new data. Not read, modify any existing data.
  • "readcreate": Ability to read existing data as well as create new data. No ability to modify existing data.
  • "readwrite": Full ability to read and modify any data.

In the above, deleting existing data counts as modifying it.

These access levels aren't surfaced to the user at all. They are only there as a level of protection and to help during the code review of the app to determine what they need to look for while reviewing an app. So for example in an app which is requesting "createonly" access to the Contacts API doesn't have to be reviewed to see if it is doing anything unexpected with read contacts information (such as save it to the server without first asking the user), since the app can't ever read contact information.

But even for an app which requests "readwrite" access to the Contacts API, as soon as the app performs a reading or writing operation B2G will prompt the user about permitting access, and if the user grants access, full read and write access will be granted. There is no need for additional prompts assuming that the user checks the "remember this decision" checkbox.

Open Question: We could surface in the prompt which of the above four types are being requested. It wouldn't increase the number of prompts that we have, but it would mean having to deal with what happens if the access changes for example from "readonly" to "readcreate" during an update.

Data Usage Intentions

The data usage intentions (provided by apps as a rationale for a permission) can serve many purposes to help users with choice and control over their data.

On the Hook

Apps that make promises via usage intentions have essentially provided assurance to the user that their data will be used in a certain way. If it turns out the app developers use the data for another purpose (say actually recording Stashy photos and posting them on a public twitter feed), users have a clear way to explain how the app is operating deceptively.

Pre-Validation with Privacy Policies

Many apps will have a privacy policy. An app store has the opportunity to pre-screen apps based on the usage intentions in their manifest and the privacy policy they provide. So long as the two are consistent, users have a commitment from the app about what it intends to do with their data. Apps that are not consistent or vague can be rejected from an app store.

Auditing

To provide a "trail of activity", B2G or other app runtime could additionally maintain a capability-access log for each app that keeps track of requests for capabilities and the usage intentions over time. That way a curious user could analyze the log to see how often an app used a permission, why it used it, and perhaps help illustrate abuse of their consent.

Network access

Network access is assumed as an implicit permission for all apps (as it seems strange to prevent access to something all web content normally has). However the issue of network consumption has been raised as a valid concern.

Its not clear this is an issue for the security model to solve however, and would be better solved via an explicit consumption API that can help the user manage and limit resource utilization. Considered out of scope for the security model in general.

Background Apps

Apps running in the background may trigger permission requests. Since app requests should be in context of the user's interaction with the app, we should suppress any permission requests for non-foreground apps. It is up the developer to properly surface permissions requests while the app is interacting with the user.

Background Services

Services need to be certified apps as they have no way of surfacing permission requests to users since they have no UI. This means we should minimize the set of use cases that absolutely require true services.

Power User

Power users should be able to override the default trust roots to allow them to install arbitrary apps as privileged or certified. This is highly dangerous and should include a correspondingly strong disclaimer or equivalent workflow.

Same Origin Policy

Same origin policy should not be enforced for certified apps or privileged apps, since each app has its own cookie store. The app would have to declare its intent to bypass same-origin policy.

Permission Manager

Application Sandboxing

Data stored per app

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

This means that if the user has two apps installed, App A and App B, these apps will have completely different set of cookies, different local data and different permission. This even applies if both of these apps open an <iframe> which point 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 Bs ability to interact with the users 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 open 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 users 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 different than as 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 by 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, and so 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 website through several apps, he/she will have to log in in every app. Likewise, if a website wants to store data locally, and the user interacts with this website 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 3rd 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 of 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 types of attack for getting at the users facebook data by exploiting bugs or other shortcomings in the facebook website.

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

And just like website data is sandboxed per app, so are permission grants. 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. This means that 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://maps.google.com still has to ask the user for permission before geolocation access is granted.

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 where 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 - i.e. 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, that will open an iframe which will receive a set of cookies for the http://maps.google.com website. If the user then navigates inside web content area, i.e. inside the <iframe mozbrowser>, to http://maps.google.com, this will use different cookies and different permissions than 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.

The security model can be shown in a simple picture

+---------------------------------+
| APP-001                         |---->App-Sandbox
|				  ----->Cookie-A
|				  ----->indexedDBStorage-A
|        			  |
|  +--------------------------+   |
|  + http://maps.google.com   +-------->Internal-Sandbox
|  +--------------------------+   |
|  |			      |   |
|  |			      |-->Cookie-B
|  |			      |-->indexedDBStorage-B
|  |    +------------------+  |   |
|  |    | maps.google.com  |  |   |
|  |    +------------------+---------->iFrame opened in web-app
|  |    |                  |---------->Cookie-C
|  |    |                  |  |------->indexedDBStorage-C
|  |    |                  |  |   |
|  |    |                  |  |   |
|  |    +------------------+  |   |
|  +--------------------------+   |
|				  |
+---------------------------------+




+---------------------------------+
| APP-002                         |---->App-Sandbox
|				  ----->Cookie-D
|				  ----->indexedDBStorage-D
|        			  |
|  +--------------------------+   |
|  + http://maps.google.com   +-------->Internal-Sandbox
|  +--------------------------+   |
|  |			      |   |
|  |			      |-->Cookie-E
|  |			      |-->indexedDBStorage-E
|  |    +------------------+  |   |
|  |    | maps.google.com  |  |   |
|  |    +------------------+---------->iFrame opened in web-app
|  |    |                  |---------->Cookie-E
|  |    |                  |  |------->indexedDBStorage-E
|  |    |                  |  |   |
|  |    |                  |  |   |
|  |    +------------------+  |   |
|  +--------------------------+   |
|				  |
+---------------------------------+

Apps can run content from many domains

As has been discussed above, an app can always contain content from multiple domains. This is exactly like how a website today can create an <iframe> pointing to a different domain.

But just like for websites today, a webpage which contains an <iframe> pointing to a different origin can't reach into that iframe and modify or touch the objects there. And like with normal websites, permissions are separated by origin, meaning that just because a permission is granted to an app, doesn't mean that any <iframe>s that that app opens has access to the same permissions.

Data management

appid/browserContent flag in B2G separate profiles on desktop/android

Process sandboxes

Application Lifecycle

This section describes the format, installation and updates process for applications.

Delivery mechanisms

B2G will support two formats for distributing apps, "hosted" and "packaged". Hosted apps work much like websites do today in that the resources for the app are located on a webserver and loaded through http. These can be cached for faster startup, but they still generally are delivered a lot like a normal website.

Packaged apps are delivered as a .zip file which contains the resources that the app consists of.

Generally speaking, it's entirely up to the app developer to choose between hosted or packaged apps. There are no differences as far as capabilities goes.

However, there are some APIs that are only available to "Privileged Apps", which currently requires the app to be packaged due to signing requirements. See section below for Privileged apps.

Hosted apps

A hosted app consists solely of an application manifest file on the developer's web server. Often the manifest will also point to an appcache manifest which allows an app to be cashed for faster startup and to enable offline usage, but otherwise doesn't affect the app at all.

From a security point of view, hosted apps work very much like normal websites. When a hosted app is loaded, the URL of the loaded pages are the normal URLs that those pages have on their web server. So to link to a specific page or resource in the app, the same URL is used as when linking to that page or URL on the website.

This doesn't change the fact that hosted apps, like all apps, are subject to the application sandbox described above.

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 website 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.

Packaged apps

The second distribution format that B2G will support is packaged apps. A packaged app consists of a normal zip file which contains both the manifest and the application resources. When a packaged app is installed, the zip file is downloaded and the manifest is read from a well-known location inside the zip file.

Unlike a hosted app, packaged apps doesn't have an obvious URL that their resources can be loaded from. The way to refer to a resource in a packaged app is by using the app: protocol. The format for a app: URL is as follows

app://identifier/path/within/zipfile/file.html

The identifier is a uuid generated at install time. This identifier will remain constant as long as the app is installed. (Eventually the identifier might become the home domain of the app, but we don't have such a concept yet).

Whenever a resource is loaded using the app: protocol, this will only allow loading resources from the zip file associated with the current app. I.e. if you specify an identifier for another app, it will behave exactly as if you specify an invalid identifier or an identifier for an app which isn't installed.

Relative links within app: works just like relative links within http:. Simply using a URL like <img src="/images/picture.jpg"> will load the image named "images/picture.jpg" in the zip package. You can also use markup like <a href="foo/bar.html"> to refer to a page relative the current page.

Open question: We probably need to allow linking to an app:// page. However we could forbid putting an app:// page in an <iframe>. Other than by other app:// pages of course.

One important thing to note about this is that the app protocol doesn't have a concept of a domain. In other words, packaged apps aren't same-origin with any "normal" websites. This is because we don't know the home domain of the developers or the app. We only know which store was used to install the app.

A result of this is that any time XMLHttpRequest is used to read data from a website, it's considered a cross-origin read and so the website has to support CORS. Eventually we'll want to enable packaged apps having a home domain, but that's not yet supported.

Just like with hosted apps, we want to make sure that a hosting website can't be tricked into hosting a app package. The risk is fairly low even if that could happen since even if the user got an app installed, as mentioned above, that app won't be same-origin with the website that the package came from. However to be safe we still apply the same security restrictions as for hosted apps. I.e. the package has to be served with a specific MIME type, or has to be same-origin with the page installing the package.

More information about why we developed a packaged apps solution is available here: Apps/PackagingProposal

Format for privileged and certified apps

We need an application delivery mechanism that provides assurances on app integrity and authenticity, and also allows for well-defined application & privilege scope enforcement so integrity can be maintained at runtime.

Thus all privileged and certified apps will be in packaged format. This package will be provided to the app store for the review, which will then sign it upon approval. Upon installation, the client will verify that the signature is valid and chains to a privileged app store.

Privileged and certified apps will be accessed via a unique scheme (app://). The domain will correspond to the app id.

App Signing

Definition of the signing format goes here. Signing Service

Updates

A lot of the update model is still being defined. Requirements are being collected here at Gaia/System/Updates

Privileged Application Review Guidelines

We need a set of guidelines that define an acceptable level of security and privacy review for privileged applications. This should include:

  • Ensuring that requested permissions are used for the purposes stated (in the permission rationale)
  • Use of implicit permissions is appropriate
  • Any interfaces between privileged app content and unprivileged external content have appropriate mitigations to prevent elevation of privilege attacks

The store is responsible for reviewing the app to ensure that it doesn't do anything dangerous with the permissions it is granted.

Since the OpenWebApps API allows any website to become a store, only stores approved by B2G will be allowed to install Privileged apps. Our goal is that multiple stores will become approved for installing privileged app, but given how much responsibility is put on the store, we need to ensure that we put agreements in place to protect users before approving a store for being allowed to install privileged apps.

Out of scope for 1.0

Magic button

This is a proposal to used a privileged button that grants access to certain APIs (camera, for example). This button would be located in the app's UI but rendered by the OS. It would have a consistent look & feel, and could not by styled, overlaid or obscured by the app.

Clicking this button would implicitly enable access to the camera. Clicking this button again (or providing a separate stop button) would turn off access again.

This is out of scope for 1.0. We do not have the time to fully understand the design and implementation issues with this approach, but it has a lot of merit and we will investigate it further for a subsequent release.

USB, Bluetooth, and NFC access

… for 3rd party apps. These have not been identified as priority use cases for 1.0 and require substantial research. We will support these in a subsequent release.

Certified apps as a 3rd party use case

We may someday have use cases that require certified 3rd party apps, but at this time all 3rd party apps that have been identified can be effectively implemented as privileged apps from a security and UX standpoint. We have no plans to support 3rd party apps as certified apps.