User:Timdream/New new security model
This is a counter proposal of FirefoxOS/New security model. Nothing will be implemented unless decided.
The original goals
(Unchanged from FirefoxOS/New security model.)
- Enable exposing "sensitive APIs" to 3rd party developers.
- Use the same update and security model for gaia and for 3rd party content.
- Don't require content which uses "senstivie APIs" to be installed. Users should be able to simply browse to it.
- Don't have separate cookie jars for separate apps. At least for normal content which doesn't use "sensitive APIs".
- Ensure that content which uses "sensitive APIs" always runs in a separate process. Enforce in the parent process that only these separate processes can trigger "sensitive APIs". I.e. hacking a child process should not permit access to more sensitive APIs.
- Enable content which uses "sensitive APIs" to have normal http(s) URLs such that they can use OAuth providers like facebook.
- Enable content which uses "sensitive APIs" to use service workers.
Specific goals we would like to achieve in this counter proposal.
- Be transparent to the current offline capability features, i.e. Service Workers or AppCache. In other word, do not make signed apps incidentally offline-capable.
- Allow hosting of signed content from static hosting, e.g. Amazon S3, Github Pages.
- Gracefully fallback to untrusted/unsigned app for browsers does not support signing.
The current Marketplace behaves like a Firefox OS-only walled garden, in which we let the developers mistakenly believe their content need to be packaged and reviewed to be included in Firefox OS. Packaged apps served from the Marketplace website also incidentally offline-capable (and labelled as such on Marketplace website), thus further lock the content in the Firefox OS.
The additionally goals are set to ensure the next iteration of our security model encourages our app developers adopt state-of-the-art Open Web technologies, not Firefox OS technologies -- and only transitions to be a reviewed/signed app when it needs additional permission.
At time of the writing, I found the proposal on FirefoxOS/New security model (a.k.a. Hosted Packaged Apps) differs from the normal Web deployment significantly, and will continue to deviate Firefox OS development from the goals set out in Booting to the Web announcement.
(Unchanged to the previous proposal)
We will require that all content which uses "sensitive APIs" is signed. For now only the firefox marketplace will be allowed to do the signing. Possibly this will be changed in the future, but that's likely more a policy change than a code change.
(Updated from the previous proposal below unless marked "unchanged")
Signing is done by having developers submit a collection of static content for a specific app and for a specific version to the Mozilla marketplace. The marketplace will review the app and then issue a signature file representing the set of the content approved. The developer can then download the signature and upload the signature along with the content to the developer's website.
The signature file should ensure the integrity of every resource in the collection. The signature of a given resource is only consider valid if it matches both the app identifier and the version identifier of the page included.
♦ Issue: (Unchanged) Should we allow other forms manual review of each app? Can the marketplace "review a developer" and give the developer access to automatic signing?
♦ Issue: Should we enable the marketplace to host signed content for developers which doesn't want to run a web server?
There is no package/packaging involved in the signing process. We might ask developer to zip the content and to send it to Marketplace simply because we have not fix bug 846931 yet, which would allow
<input file> to accept a folder.
♦ Issue: Or maybe the Marketplace could review the live website or a staged website online?
The format used for the signature file is still to be determined, but to serve it's purpose it should include a set of checksum representing the resources it signed against. We DO NOT include the exact URLs of the resources because we only verify the given resource content and does not care about where it is being loaded from. This enables app to load shared resource from a shared location.
The signature file however should include the manifest URL as the identifier of the origin the signature file granted.
♦ Issue: (Unchanged) Decide on exact signature format.
♦ Issue: Removing URLs from the signature file might prevent us from prefetching/caching signed resources should it become necessary.
To load a webpage in a signed content, the user would navigate to the page as usual. When Gecko loads the page, it would see the
X-Moz-App-Signature in the response header. The value of the header should be the URL of the signature file issued by Marketplace.
Before actually loading the page, the signature file should be downloaded, and the content of the page should be verified against the signature file. The signature file define the resources the page is allowed to load. We've ruled out referencing the signature file in HTML (e.g. in <html> or <meta>) because it might trigger necessary reloads.
♦ Issue: Github Pages (or any static hosting other than Amazon S3) doesn't actually allow setting a custom HTTP header.
The URL to the signature file is likely version'd to ensure we indeed referencing the correct signature file (that matches the current version of the page). A version'd URL (e.g.
https://code.jquery.com/jquery-2.1.3.min.js) will also work with CDN/Proxy level network caching, a common technique on the Web today.
The signature file should contain the URL to the webapp manifest and the checksum of the referenced webapp manifest. It should always match the webapp manifest referenced in the <meta> tag of the page (which aligned with how W3C app manifest is referenced). Whenever the signature file is updated, Gecko should also (re-)fetch the webapp manifest, verify it, to assert the proper permission and origin of the app.
♦ Issue: Can the webapp manifest itself bear the responsibility of the signature file?
♦ Issue: How do we prevent getting the old version of the webapp manifest? The webapp manifest URL is currently used as the origin identifier of the app -- we can't serve it from a version'd URL.
♦ Issue: Do we want to get rid of the signature file and instead make the every resource comes with a signature header? Of course the signature header must be signed against the same version/app of the page.
The integrity of the signature file, of course, should be verified.
We would NOT cache any content except for normal HTTP disk/memory caching. App developer will be responsible of introducing offline-capable feature(s) of their choice, i.e. Service Worker or AppCache. AppCache offline manifest, as simply a mean of delivery and assigning offline-cached resources, does not required to be signed. It's likely for Marketplace to also generate the offline-capable script/manifest automatically (what to generate would depend on how much we hate AppCache or love Service Workers).
♦ Issue: Should we sign the AppCache offline manifest? Would it be a security issue if we don't?
♦ Issue: AppCache offline manifest usually caches the same set of signed resources. Do we want to somehow simply the usage here of the developer choose to use AppCache?
We DO NOT consider fail to load one resource as a fail validation of the signature. We therefore do not attempt to load and verify all the resources specified in the signature before loading the page.
♦ Issue: Should we?
(Unchanged) Another thing that needs to be done before any content is served by the network layer is to look in the webapp manifest and populate the nsIPermissionManager database with any permissions enumerated in the webapp manifest. After having checked that the webapp manifest properly matches the signature of course.
All resources referenced by the page is likely from a version'd URL as well, per reason stated above.
(Unchanged, see FirefoxOS/New_security_model#CSP)
(Unchanged, see FirefoxOS/New_security_model#Process_isolation)
Installing and updating
Given the fact we have removed the offline capability of signed content, app developers are responsible to implement their own installing/updating scheme, independent of the signing scheme. If they use neither Service Worker nor AppCache, their page will behave exactly as any normal websites.
As described in the previous section, the signature should go along with the page. When a page is updated, Gecko should expect/receive/verify the new signature file with the updated page.
With AppCache, the signature file is offline-cached or purged with it's page. When the page is being updated because of a offline manifest change, the new signature file should be downloaded and offline-cached along with the new page. As previously described, each version of the page can only load the resource allowed in it's signature file.
Per previous paragraph, we do not expect the offline manifest to be signed.
♦ Issue: If we require the updated offline manifest to be signed with an updated signature file, we would need to receive the
X-Moz-App-Signature header from the HTTP response of the offline manifest.
(Following the format of original proposal, how Service Worker-backed app update the signature will be covered in the next paragraph.)
Neither AppCache offine manifest nor Service Worker Cache need to explicitly cache the signature file.
To confirm with the current UX requirement, we will need to allow user to control the update schedule of AppCache'd or Service Worker-backed apps. This incidentally will unify the way how user control signed web apps AND unsigned offline-capable web apps.
We do not monkey-patch the service worker spec to update Service Workers cache as a whole. Instead, we only have to deal with how to update the signature file when the app updates.
Additionally to explicit control over Caches, Service Worker script itself have access to sensitive APIs too. Therefore, they would have to be included in as a signed resource in the signature file for a signed page to register the worker at first place.
Per spec, a Service Worker-backed app updates when it's Service Worker script changes. As the updated script is the first script we run for the new set of permissions and signatures, we therefore need to receive the new signature file from the
X-Moz-App-Signature header included in the HTTP response of the updated script, instead of the original page of entry.
The manifest should be re-fetched/updated along with the new signature file.
Service Worker script should not put/manage the signature file in Caches. It is always managed by Gecko and cached/purged along with the Service Worker script or the page it associate with.
♦ Issue: We are likely creating one-to-many (and technical complexities) relationship between the signature file and the page/script. This needs further work to prevent state/version inconsistencies.
It's worthy noting since Service Worker script continue to be given the explicit and sole control over what to cache, the updated script can therefore choose not to re-download any unchanged resources -- we however require these unchanged resources to be verified with the new signature file to be able to run on the updated page.
It's possible for the Service Worker employ it's own logic to synthesize a resource update (e.g. per file delta update), instead of downloading the updated resource. The signature file therefore should be used to verify against the synthesized Service Worker Response.
♦ Issue: (likely an issue for the original proposal as well) Does the above verification apply to all resource types, or just JS files only? To what degree does the worker script allow to modify a resource without risking breaking the protection offered by CSP?
(Unchanged, see FirefoxOS/New_security_model#Origins_and_cookie_jars)
Relationship between signing and packaging
Packaging is no longer a requirement for the content to be signed. Package can still be used if the app developer wish to fulfill any use cases described on the spec draft repo readme.
When a given resource is a package, the signature file should list a package as one resource and sign the package as whole.
♦ Issue: Would that prevent streaming from working?