FirefoxOS/New security model/Packaging: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(add quotation mark around moz-package-location)
Line 101: Line 101:
   }
   }
  ],
  ],
  moz-package-location:"https://example.com/myapp/app.pak"
  "moz-package-location":"https://example.com/myapp/app.pak"
  }
  }



Revision as of 10:01, 11 August 2015

Privileged Content

This page details implementation of signed privileged content for FxOS. The basic properties of privileged content is that:

  • they are enumerated in a manifest
  • signed to prevent modification
  • loaded into a unique origin which is granted special permissions(separate from other web content on the same domain)

Background: Packaged Content

bug 1036275 introduced packaged HTML content to Firefox. Packages must be served with "Content-Type: application/package" mime type.

An example of a regular package is shown below:

--gc0pJq0M:08jU534c0p
Content-Location: /index.html
Content-Type: text/html

<html>
  <head>
    <script src="scripts/app.js"></script>
    ...
  </head>
  ...
</html>

--gc0pJq0M:08jU534c0p
Content-Location: /scripts/app.js
Content-Type: text/javascript

module Math from '/scripts/helpers/math.js';
...

--gc0pJq0M:08jU534c0p
Content-Location: /scripts/helpers/math.js
Content-Type: text/javascript

export function sum(nums) { ... }
...

--gc0pJq0M:08jU534c0p--

Privileged Packages

The Signed Manifest

A packaged is denoted by setting a single packages header which is the signature over the first resource which MUST be the manifest, and must include a list of resources in the package, along with their hashes.

  manifest-signature: MRjdkly.... (Base64 JWS Signature over manifest content)

Package headers are specified by the w3c format and are headers which are sent inside the package, but prior to the first data part. Modifiying the above example, we get something like:

manifest-signature: MRjdkly.... (Base64 JWS Signature)
--gc0pJq0M:08jU534c0p
Content-Location: /someapp.webmanifest
Content-Type: application/manifest

{
"name": "My App", 
"description":"A great app!"
...

Manifest Requirements

moz-uuid

Signed packages must contain a uuid (ACTUAL NAME TBD) field. The unique identifier for a signed package is the tuple of the package origin and the app name. (e.g. foo.com!uuid). NOTE: Marketplace might supply this.

moz-permissions

We need the permissions of the signed package so in order to know what permissions to grant to the new process.

Resources

We add a resources section to the app manifest which enumerates content which needs to have integrity check. All resources are specified by relative URIs and meaning they must reside inside the package.

moz-package-location

We need a field in the manifest which specifies the origin for where the package is allowed to be hosted. This needs to be checked by gecko when a package is loaded to ensure that the package hasn't been moved and re-hosted.

Example

{
"moz-uuid": "some-uuid",
"moz-permissions": [
  {
    "systemXHR": {
      "description": "Needed to download stuff"
    },
    "devicestorage:pictures": {
      "description": "Need to load pictures"
    }
  }
],
"moz-resources": [
  {
    "src": "/index.html",
    "integrity": "sha256-kass...eoirW-e"
  },
  {
    "src": "/page2.html",
    "integrity": "sha256-kasguie...ngeW-e"
  },
  {
    "src": "/script.js",
    "integrity": "sha256-agjdia2...wgda"
  },
  {
    "src": "/library.js",
     "integrity": "sha256-geijfi...ae3W"
  }
],
"moz-package-location":"https://example.com/myapp/app.pak"
}

Processing Model

THIS SECTION IS OUT OF DATE.

When an app-manifest is encountered, while the page is loaded as normal, additional steps are initiated in parallel. Two main processes are started: - populating cache with app enumerated resources - verification of signed resources and granting of permissions

The normal loading process is:

  1. Gecko loads the manifest
  2. Gecko checks the signature of the manifest
  3. If signature verifies, a privileged child process is launched
  4. Web page is loaded as a normal web page inside this privileged process
  5. Although the _process_ is privileged, permission are restricted until verification is complete (i.e. ALL resources enumerated in the manifest have been loaded and passed integrity checks)

The verification process is as follows:

  1. After the manifest signature checks out, gecko starts downloading all files enumerated in the manifest
  2. Each resource has is checked against a digest from the manifest
  3. If the integrity check passes, the resource is cached
  4. Once all the resources have been cached, only then is content considered privileged and permissions available to it
  5. TODO: How do we enable permissions in a lazy manner? (ie after the window is already loaded)

To update a privileged app:

2.2. Update

  1. GET manifest, If-Modified-Since
  2. Look for what files have changed, by addition/deletion/integrity
  3. Update changed files

Verification failures are generally treated as network failures. See "Error Recovery" below for the approach to dealing with loading errors and partially loaded apps.

Cache population

TODO (initial thoughts only)

  • For all signed resources we should only cache them if the integrity check passes
  • We want to somehow keep track of the resources that have been integrity checked (if we adhere to the previous rule, can we assume that if cached, then the resource passed the integrity check?

Verification of resources & Permission Granting

TODO

  • We only want to grant permissions after ALL resources in the manifest have been verified
  • But we want to launch the process earlier to speed up performance
  • We'll need some kind of verifier worker that keeps track of loading, and link this to the PermissionManager (and apps manager, at least while we have an apps manager)
  • The delay here shouldn't be a problem for most privileged APIs, since MOST permissions are user granted, and therefore asynchronous by their nature. There will be a some complexity though as there are a number of APIs which are st to null if a permission is not present when the window(?) is created. We are going to need to make ALL permissions grant-able at any stage.

Error Handling & Recovery

Security Properties of Privileged Apps

  • Only signed scripts may be loaded
  • Only signed entry points can be navigated to
  • All privileged content must be served over a secure network connection.
  • No framing privileged content
  • Resources enumerated in the manifest must have their integrity checked prior to loading

Note:

  • Not all HTML must be signed. There is little value in making this a firm requirement since it isn't possible to prevent dynamic HTML changes (this risk is unchanged from previous packaged approach)
  • The resources which MUST be signed are:
    • scripts (CSP enforces that only signed scripts can be loaded in the origin)
    • entry points (entry point restrictions enforce that only signed entry points can be navigated to)
  • Developers should be encouraged to sign all static resources to prevent tampering