From d6793b6e3723153edda71224355d844080608758 Mon Sep 17 00:00:00 2001 From: Christian Flach Date: Wed, 13 Jul 2022 01:36:52 +0200 Subject: [PATCH] Add a separate, more detailed explainer for the `isolated-app:` scheme. (#2) * Add a separate, more detailed explainer for the isolated-app: scheme. * Apply suggestions from code review Co-authored-by: Thomas Steiner * Apply suggestions from code review Co-authored-by: Reilly Grant * Add explicit encoding and decoding sections. Co-authored-by: Thomas Steiner Co-authored-by: Reilly Grant --- README.md | 6 ++-- Scheme.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 Scheme.md diff --git a/README.md b/README.md index 69fb2ca..26caf58 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This proposal should _not_ be considered a desirable model for most web-based ap The core of this proposal is making application updates explicit. Unlike TLS keys, which have to be available online to establish new connections, the key used to sign the Web Bundle can be kept securely offline and is used infrequently. The channel through which updates are distributed creates another point where the new resources can be checked for potentially malicious content. This is different from bundling [Signed HTTP Exchanges](https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html) because we don’t intend to create a verifiable mirror of a subset of a site’s resources, but a holistically verifiable version of an entire application. For this reason Isolated Web Apps should use a new origin for content served from these bundles. -The reason for this is both practical and philosophical. If the identity of the site were still based on a DNS name, then it would still be vulnerable to a temporary loss of control over that domain or the infrastructure used to validate ownership of the domain. Philosophically, we also want to avoid building an alternative to certificate authorities which shares the same namespace. Isolated Web Apps therefore use a new scheme (tentatively, `isolated-app://`) where the authority section of the URL is a hash of the public key used to sign the Web Bundle containing the application resources. +The reason for this is both practical and philosophical. If the identity of the site were still based on a DNS name, then it would still be vulnerable to a temporary loss of control over that domain or the infrastructure used to validate ownership of the domain. Philosophically, we also want to avoid building an alternative to certificate authorities which shares the same namespace. Isolated Web Apps therefore use a new scheme (tentatively, `isolated-app://`) where the authority section of the URL is based on the public key used to sign the Web Bundle containing the application resources. More details on the scheme are available in [this explainer](./Scheme.md). An application can be upgraded by replacing its Web Bundle with a new version signed by the same key. Since the key hash is the same, the application retains any local storage associated with the previous version. To prevent downgrade attacks, implementations may require either a `"version"` field in the [Web Application Manifest](https://www.w3.org/TR/appmanifest/), or the signature timestamp to be monotonically increasing. @@ -65,7 +65,7 @@ Designing more trustworthy web contexts and packaging applications based on web * Mike West proposed “[Securer Contexts](https://github.com/mikewest/securer-contexts/blob/master/README.md)” upon which the isolation and injection protection presented here are based. * Google uses signed ZIP archives for both Chrome Apps and Extensions. -* Mozilla [proposed](https://wiki.mozilla.org/Apps/Security) signed ZIP archives for applications on Firefox OS and a “[new security model](https://wiki.mozilla.org/FirefoxOS/New_security_model)” for such applications. +* Mozilla [proposed](https://wiki.mozilla.org/Apps/Security) signed ZIP archives for applications on Firefox OS and a “[new security model](https://wiki.mozilla.org/FirefoxOS/New_security_model)” for such applications. * The [Browser Extension Community Group](https://www.w3.org/community/browserext/) [suggests](https://browserext.github.io/browserext/#packaging) packaging Web Extensions in ZIP archives but leaves the details up to the implementation. * The [MiniApps Working Group](https://www.w3.org/2021/miniapps/) also [defines](https://w3c.github.io/miniapp-packaging/) a format based on ZIP archives. * Electron defines a [custom](https://github.com/electron/asar) archive format for efficient loading of application resources. @@ -75,7 +75,7 @@ Designing more trustworthy web contexts and packaging applications based on web Meta and Cloudflare have [announced](https://blog.cloudflare.com/cloudflare-verifies-code-whatsapp-web-serves-users/) a collaboration to resolve the same threat of tampering with the code for the WhatsApp web app that this proposal addresses. Their approach is similar to [Binary Transparency](https://binary.transparency.dev/), using [a browser extension](https://github.com/facebookincubator/meta-code-verify) to compare the running code against a manifest of expected hashes that is distributed out-of-band with the application. In this case, the manifest is served by Cloudflare while the site is served by Meta. This has the advantage of not requiring a new way to distribute their application. Users who don’t have the extension installed visit the site as usual, while users with the extension have additional protection. One can imagine a future in which the validation logic is embedded into the browser, bringing this protection to more users. As with [OSCP](https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol) however, an attacker who can compromise the user’s connection to the site may also be able to compromise their connection to the validation endpoint and the current design fails open. -This proposal addresses that vulnerability by defining a single moment at which the application is vulnerable to a network attacker, that is, the moment when a bundle is downloaded, and afterwards resources are not fetched over the network. The Code Verify system could be improved by blocking access to the site until the manifest has been fetched, so that only verified resources can be loaded rather than warning the user that the resources have been tampered with after the fact. At that point however, the benefit of individually fetching resources over the network is weakened and using a signed Web Bundle, as proposed here, allows fetching and verification to be completed as a single step. +This proposal addresses that vulnerability by defining a single moment at which the application is vulnerable to a network attacker, that is, the moment when a bundle is downloaded, and afterwards resources are not fetched over the network. The Code Verify system could be improved by blocking access to the site until the manifest has been fetched, so that only verified resources can be loaded rather than warning the user that the resources have been tampered with after the fact. At that point however, the benefit of individually fetching resources over the network is weakened and using a signed Web Bundle, as proposed here, allows fetching and verification to be completed as a single step. ## Acknowledgements diff --git a/Scheme.md b/Scheme.md new file mode 100644 index 0000000..ae56c89 --- /dev/null +++ b/Scheme.md @@ -0,0 +1,105 @@ +# `isolated-app:` Scheme Explainer + +This document provides a more detailed look at the `isolated-app:` scheme, which is part of the proposal for [Isolated Web Apps](./README.md). +Isolated Web Apps are a new proposal to build applications using web technologies, but with additional security properties compared to normal web pages. +Isolated Web Apps bundle all their contents inside a web bundle that is then [signed to make its integrity verifiable](https://github.com/WICG/webpackage/blob/main/explainers/integrity-signature.md). +A key difference between Isolated Web Apps and normal web pages is that Isolated Web Apps do not rely on DNS name resolution and HTTPS certificate authorities. +Instead, they need to be explicitly downloaded and installed by the user, such as from an app store or via enterprise configuration. +A user agent can verify the integrity of an Isolated Web App by checking the signature and comparing its corresponding public key to a list of known trusted public keys. + +## `isolated-app:` Scheme + +Since Isolated Web Apps do not use HTTPS certificate authorities and also need to be independent of domains and name resolution, a new URL scheme is needed to signify this difference. +The tentative name of this new scheme is `isolated-app:`, highlighting how Isolated Web Apps are isolated from each other and the web through enforced Content Security Policy and Cross-Origin Isolation. +When loading an `isolated-app:` URL, the user agent checks the signatures of the underlying web bundle and whether it trusts the public key that was used to sign it. +A user agent might trust, for example, public keys configured via enterprise policy, public keys of known distribution mechanisms/stores, or separately allow-listed public keys of individual Isolated Web Apps. +`isolated-app:` URLs are considered Secure Contexts, just like HTTPS pages, and thus have access to APIs like Service Workers. `isolated-app:` URLs look like so: + +``` +isolated-app://signed-web-bundle-id/path/inside/app.js?some-query#foo +^ ://^ /^ ?^ #^ +scheme opaque host path query fragment +``` + +### Host + +URLs with the `isolated-app:` scheme use a Signed Web Bundle ID (see next section) as their opaque host, as defined in the [URL standard](https://url.spec.whatwg.org/). +The Signed Web Bundle ID being the host adds the requirement that it must be a valid hostname (see [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986)). This requirement is satisfied by using [base32 encoding](https://datatracker.ietf.org/doc/html/rfc4648), with padding removed. +It is the user agent’s responsibility to map the Signed Web Bundle ID contained in the opaque host to an installed Isolated Web App and its associated Web Bundle. The URL path is then used to fetch resources as relative URLs from the bundle. + +### Port & Credentials + +Isolated Web App URLs do not use usernames, passwords, or ports. +All three of these components are therefore always `null`. +Isolated Web App URLs with a port or credentials must not be loaded and must result in an HTTP error. + +### Path, Query, Fragment + +These work like one would expect from HTTP(S) URLs, as described in the URL specification. + +## Signed Web Bundle IDs + +Isolated Web Apps are identified by their _Signed Web Bundle ID_. +The Signed Web Bundle ID is an ASCII string which contains an identifier followed by a suffix that represents the type of identifier. +The general format of Signed Web Bundle IDs looks like this: + +``` +lowercase(base32EncodeWithoutPadding([identifier] [identifier type] [identifier type length])) + [ ------------ suffix ------------------ ] +``` + +### Suffix + +The suffix consists of two parts: The last byte indicates how many bytes are used to describe the identifier type, and the `n` bytes before it are used to describe the identifier type. +Currently, the following two suffixes are defined: + +`0x00 0x00 0x02`: This suffix indicates that the ID is a user-agent-specific value that can be used for testing and development purposes. +For example, loading a Web Bundle from the local filesystem which is not signed. + +`0x00 0x01 0x02`: This suffix is used for [Ed25519](https://datatracker.ietf.org/doc/html/rfc8032) public keys as Signed Web Bundle ID. +It is prefixed by the 32-byte representation of the Ed25519 public key that is used to sign the web bundle (see [this explainer](https://github.com/WICG/webpackage/blob/main/explainers/integrity-signature.md) for more details about the signing process). +Since this Signed Web Bundle ID is only dependent on the signing key, it makes it possible to have the same Signed Web Bundle ID regardless of the distribution mechanism of the Isolated Web App, without requiring a central authority to manage keys. + +### Encoding + +Given an identifier and the suffix representing the type of the identifier, both must be concatenated and then base32-encoded. +Potential padding introduced by the base32 encoding must be discarded and the result transformed into lowercase. +The resulting string is a Signed Web Bundle ID. + +### Decoding + +Given a Signed Web Bundle ID, it must first be transformed into uppercase. +If the string's length is not a multiple of 8, a number of padding characters (`=`) must be added until its length is a multiple of 8. +Then, the string must be base32-decoded. +Next, the last byte must be read to determine the length of the identifier type. +Assuming that there are `n` bytes in total and that the last byte contains the number `l`, the `identifier` can be reconstructed by reading bytes `[0, n-l-1)`, and the `identifier type` can be reconstructed by reading bytes `[n-l-1, n-1)`. + +### Example for Ed25519 keys + +Public Ed25519 key (hex, 32 bytes): +``` +01 23 43 43 33 42 7A 14 42 14 +a2 b6 c2 d9 f2 02 03 42 18 10 +12 26 62 88 f6 a3 a5 47 14 69 +00 73 +``` + +Public key and suffix (hex, 35 bytes): +``` +01 23 43 43 33 42 7A 14 42 14 +a2 b6 c2 d9 f2 02 03 42 18 10 +12 26 62 88 f6 a3 a5 47 14 69 +00 73 00 01 02 +``` + +Base32-encoded public key and suffix (56 chars long): +``` +AERUGQZTIJ5BIQQUUK3MFWPSAIBUEGAQCITGFCHWUOSUOFDJABZQAAIC +``` + +Since the length of the public key and suffix is a multiple of 5, no padding is generated that would need to be removed. + +Signed Web Bundle ID (56 chars long): +``` +aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic +``` \ No newline at end of file