Remotely Hosted Resources

From MozillaWiki
Jump to: navigation, search

A remotely hosted resource is a way to write and ship code for Firefox that is:

  1. implemented using regular HTML/CSS/JS
  2. unprivileged
  3. not necessarily checked-in to mozilla-central

The goals we're trying to achieve are to:

  • speed up development time
  • speed up deployment time
  • increase safety
  • increase security
  • increase product quality via quicker iteration enabled

Some of the motivation and benefits for remote pages are described further in a separate blog post.

This document is concerned about describing the techniques used to create remotely hosted resources.

Core Architecture Overview

Newtab objects at runtime

The pages are loaded from the network and are cached locally. Offline capability is implemented via Service Worker APIs. An additional layer of offline capability can be added by shipping a local copy of the resources within Firefox, and loading that in case the network is not available..

Another core piece of this architecture is about how to provide additional functionality to an otherwise unprivileged document. We do so by defining and implementing purpose-built Web APIs. We do so by creating new Web APIs made specially for the features desired. Those APIs are only enabled for the origin we choose and probably localhost for testing.

Resource Updates

Updates to the pages are controlled via Cache-Control headers. I.e one can control how often Firefox will fetch new copies of the pages just by setting a header.

However, there will be two speeds for updates that are divided by the IDL boundary: IDL implementations and desktop-code and the remote resources which are consumers of the IDL.

To be clear:

  • The Web IDL definitions and implementations need to be landed in mozilla-central and ride the release trains
  • The remote resources can be updated out-of-band to the Firefox release schedule, but need to be aware of Firefox version differences

To manage this change management, for the newtab page, we use a concept of versioning for the newtab page, baked in the requested page's URL.

Here's an example:

Firefox 87 may request for a page at https://newtab.cdn.mozilla.net/v10/release/en-US/index.html, but Firefox 88 may request for a page at https://newtab.cdn.mozilla.net/v11/release/en-US/index.html.

This has a couple of great properties:

  1. New API's could require new page versions, to reduce complexity within the page
  2. Users that haven't updated would still have a working copy of the page

As mentioned in a section above, there is some code that would need to be landed in mozilla-central. These would include the implementations of the interfaces, the modules providing functionality to the IDL implementations, the code that loads the remote pages and potentially more. In addition to the feature implementation, one could also include the remotely hosted resources and load them up in case of network unavailability.

For the newtab page, we control the loading of the page in https://dxr.mozilla.org/mozilla-central/source/browser/components/about/AboutRedirector.cpp. The remote URL is provided by https://dxr.mozilla.org/mozilla-central/source/browser/components/newtab/aboutNewTabService.js.

Security

Using unprivileged code is a boon for security. By only enabling the functionality required, we are applying the Principle of Least Privilege. However, because the code we are executing is also remotely-hosted, we need to ensure ourselves of the origin and integrity of the resources.

We do so by employing a number of measures:

  • HTTPS with key-pinning for transport security
  • Since we employ a third party for delivery via CDN, Content Signature verification, to ensure data has not been tampered at rest
  • Sub-Resource Integrity to ensure that sub-resources haven't been tampered
  • CSP via meta tag is planned to be used after marionette can run tests
  • Resource URLs not permanently overridable to avoid hijacking
Resource Signing Network Diagram