diff --git a/__tests__/plugins/signed-integrity/index.test.js b/__tests__/plugins/signed-integrity/index.test.js index 3a69185..a1e3cde 100644 --- a/__tests__/plugins/signed-integrity/index.test.js +++ b/__tests__/plugins/signed-integrity/index.test.js @@ -46,7 +46,7 @@ describe("plugin: signed-integrity", () => { } // debug - console.log(await getArmouredKey((await generateECDSAKeypair()).publicKey)) + console.log("pubkey: ", await getArmouredKey((await generateECDSAKeypair()).publicKey)) // ES384: ECDSA using P-384 and SHA-384 var header = btoa('{"alg": "ES384"}').replace(/\//g, '_').replace(/\+/g, '-').replace(/=/g, '') diff --git a/plugins/alt-fetch/README.md b/plugins/alt-fetch/README.md index 8a4661b..cd10e51 100644 --- a/plugins/alt-fetch/README.md +++ b/plugins/alt-fetch/README.md @@ -1,7 +1,7 @@ # Plugin: `alt-fetch` - **status**: stable -- **type**: [transport plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#transport-plugins) +- **type**: [transport plugin](../../docs/ARCHITECTURE.md#transport-plugins) This transport plugin uses standard [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) to retrieve remote content from alternative endpoints — that is, HTTPS endpoints that are not in the original domain. This enables retrieving content even if the website on the original domain is down for whatever reason. diff --git a/plugins/any-of/README.md b/plugins/any-of/README.md index 249a6fb..72ea66f 100644 --- a/plugins/any-of/README.md +++ b/plugins/any-of/README.md @@ -1,7 +1,7 @@ # Plugin: `any-of` - **status**: stable -- **type**: [composing plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#composing-plugins) +- **type**: [composing plugin](../../docs/ARCHITECTURE.md#composing-plugins) The `any-of` composing plugin runs all plugins configured in its `uses:` configuration field simultaneously (using [`Promise.any()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any)), and returns the firs successful response it receives. diff --git a/plugins/basic-integrity/README.md b/plugins/basic-integrity/README.md index 4ba6487..30a71b8 100644 --- a/plugins/basic-integrity/README.md +++ b/plugins/basic-integrity/README.md @@ -1,13 +1,13 @@ # Plugin: `basic-integrity` - **status**: beta -- **type**: [wrapping plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#wrapping-plugins) +- **type**: [wrapping plugin](../../docs/ARCHITECTURE.md#wrapping-plugins) This plugin sets statically configured [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) hashes on requests performed by configured wrapped transport plugins. This allows plugins that know how to handle it (or that use underlying browser APIs that automatically handle SRI, like [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch)) to verify integrity of retrieved content before returning it as a response. -**IMPORTANT NOTE:** this plugin, by itself, does *not* verify the integrity of fetched resources; it merely sets the integrity data on the requests. It's up to the wrapped plugin to actually use that data to verify integrity (or rely on browser APIs like `fetch()` to handle this automatically. +**IMPORTANT NOTE:** this plugin, by itself, does *not* verify the integrity of fetched resources; it merely sets the integrity data on the requests. It's up to the wrapped plugin to actually use that data to verify integrity (like the [`integrity-check`](../integrity-check/) plugin) or rely on browser APIs like `fetch()` to handle this automatically. ## Configuration @@ -16,11 +16,11 @@ The `basic-integrity` plugin supports the following configuration options: - `uses` (required) Array containing exactly one object which is in turn a configuration of a wrapped plugin. This plugin will be used to actually handle any requests. - - `integrity` (default: empty) + - `integrity` (default: empty) An object mapping absolute URLs (e.g. "`https://example.com/img/test.png`") to integrity hashes (e.g. "`sha384-kn5dhxz4RpBmx7xC7Dmq2N43PclV9U/niyh+4Km7oz5W0FaWdz3Op+3K0Qxz8y3z`"). Supported integrity hash algorithms [as per SRI specification](https://w3c.github.io/webappsec-subresource-integrity/#terms): `sha256`, `sha384`, `sha512`. The integrity string can contain multiple hashes, space-separated, [as per the standard](https://w3c.github.io/webappsec-subresource-integrity/#agility). - - `requireIntegrity` (default: `true`) + - `requireIntegrity` (default: `true`) Boolean value specifying if integrity data is required for a request to handled. That is: if a request is being handled for a URL that does not have integrity data associated with it, should the request be processed, or errored out? By default, `basic-integrity` plays it safe and assumes you want integrity data to be present for all resources being fetched; if you only want certain resources to have integrity verified, set this to `false`. Importantly, integrity data does not need to be explicitly configured in this plugin's config — if integrity data is available in the request already, that also counts, even if no specific data is configured for this URL in this plugin's config. diff --git a/plugins/cache/README.md b/plugins/cache/README.md index bfcd154..dba0753 100644 --- a/plugins/cache/README.md +++ b/plugins/cache/README.md @@ -1,10 +1,14 @@ # Plugin: `cache` - **status**: stable -- **type**: [stashing plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#stashing-plugins) +- **type**: [stashing plugin](../../docs/ARCHITECTURE.md#stashing-plugins) The `cache` plugin uses the [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to save content in visitor's browser for later use (when offline or when the website is down for whatever reason, for instance). As a stashing plugin, it is handled in a special way by LibResilient: - if any plugin configured *before* `cache` returns a successful response, the `cache` plugin caches it for later use. - if no plugin configured before `cache` succeeds, `cache` returns the cached response; afterwards, plugins configured *after* `cache` are run in the background to try retrieving a fresher response; if any of them succeeds, `cache` plugin caches it for later use. + +## Configuration + +The `cache` plugin does not have any configuration options. diff --git a/plugins/fetch/README.md b/plugins/fetch/README.md index cdc0140..4da1903 100644 --- a/plugins/fetch/README.md +++ b/plugins/fetch/README.md @@ -1,8 +1,12 @@ # Plugin: `fetch` - **status**: stable -- **type**: [transport plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#transport-plugins) +- **type**: [transport plugin](../../docs/ARCHITECTURE.md#transport-plugins) This transport plugin uses standard [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) to retrieve remote content from the original domain — which is exactly what would have happened normally if LibResilient was not deployed on a website. As per LibResilient architecture, this plugin adds `X-LibResilient-Method` and `X-LibResilient-ETag` headers to the returned response. + +## Configuration + +The `fetch` plugin does not have any configuration options. diff --git a/plugins/gun-ipfs/README.md b/plugins/gun-ipfs/README.md index 8216df3..b140d20 100644 --- a/plugins/gun-ipfs/README.md +++ b/plugins/gun-ipfs/README.md @@ -1,4 +1,14 @@ # Plugin: `gun-ipfs` - **status**: proof-of-concept, broken -- **type**: [transport plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#transport-plugins) +- **type**: [transport plugin](../../docs/ARCHITECTURE.md#transport-plugins) + +This plugin uses [GunDB](https://gun.eco/) as a source of information on current [IPFS CIDs](https://docs.ipfs.io/concepts/content-addressing/) of content, and retrieves that content using [JS IPFS](https://github.com/ipfs/js-ipfs). + +## Configuration + +*TBD* + +## Operation + +*TBD* diff --git a/plugins/integrity-check/README.md b/plugins/integrity-check/README.md index 3239923..dfe4db0 100644 --- a/plugins/integrity-check/README.md +++ b/plugins/integrity-check/README.md @@ -1,4 +1,30 @@ # Plugin: `integrity-check` - **status**: beta -- **type**: [wrapping plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#wrapping-plugins) +- **type**: [wrapping plugin](../../docs/ARCHITECTURE.md#wrapping-plugins) + +This plugin implements [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) checking using the [SubtleCrypto API](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto). + +It can be used in conjunction with plugins that set SRI data on requests (like [`basic-integrity`](../basic-integrity/)) to verify integrity of data retrieved via transport plugins that cannot be expected to verify integrity automatically. + +## Configuration + +The `integrity-check` plugin supports the following configuration options: + + - `uses` (required) + An Array containing exactly one object: config of the wrapped plugin that will actually handle the request. + For any request, once a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) is returned from that wrapped plugin, the `integrity-check` plugin will calculate the hash of the content and compare it to integrity data available in the Request. + + - `requireIntegrity` (default: `false`) + A flag signalling whether every requested URL has to have integrity data available. + If there is no integrity data available for an URL, and `requireIntegrity` is set to `true`, the request will not be allowed to proceed. + +## Operation + +The checks are performed based on the [`integrity` field of the Request object](https://developer.mozilla.org/en-US/docs/Web/API/Request/integrity), against the data returned from the configured wrapped plugin. + +If `requireIntegrity` configuration flag is set to `true`, requests with no `integrity` field will not be allowed to proceed; an error is returned instead. + +## Performance and usability considerations + +Calculating integrity hashes is CPU-intensive and while on most devices for small files (CSS, HTML, JS, images) it will be almost unnoticable to the user, enforcing integrity checks on large content (videos, etc.) might lead to considerable spike in reasource use. diff --git a/plugins/ipns-ipfs/README.md b/plugins/ipns-ipfs/README.md index 2390ebf..0ae6e6a 100644 --- a/plugins/ipns-ipfs/README.md +++ b/plugins/ipns-ipfs/README.md @@ -1,4 +1,12 @@ # Plugin: `ipns-ipfs` - **status**: proof-of-concept, broken -- **type**: [transport plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#transport-plugins) +- **type**: [transport plugin](../../docs/ARCHITECTURE.md#transport-plugins) + +## Configuration + +*TBD* + +## Operation + +*TBD* diff --git a/plugins/redirect/README.md b/plugins/redirect/README.md index 9712fd1..090661f 100644 --- a/plugins/redirect/README.md +++ b/plugins/redirect/README.md @@ -1,4 +1,25 @@ # Plugin: `redirect` - **status**: alpha -- **type**: [transport plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#transport-plugins) +- **type**: [transport plugin](../../docs/ARCHITECTURE.md#transport-plugins) + +This plugin redirects all requests, using a configured [HTTP Status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) and [message](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages), to URLs in a different domain. + +For each request, the plugin removes the scheme and domain components, and appends the rest of the URL with the contents of `redirectTo` configuration variable. This allows for seamless redirection of all requests for URLs in the original domain to a new location, in case the original domain is expected to be permanently unavailable. + +This plugin is, in a way, the last line of defense, and can be configured but not enabled (by setting the `enabled` configuration flag to `false`). In case of a permanent problem with the original domain visitors with the Service Worker installed and running can receive a [config update via alternative transports](../../docs/UPDATING_DURING_DISRUPTION.md) that enables this plugin, which in turn redirects them to the new domain of the website. + +## Configuration + +The `redirect` plugin supports the following configuration options: + + - `redirectTo` (required) + A string containing the base URL for all redirectons; should end in "`/`". + + - `redirectStatus` (default: `302`) + - `redirectStatusText` (default: "`Found`") + These two config variables define the [HTTP status code and message](https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections) to be used for the redirect. + + - `enabled` (default: `false`) + If set to `false` the plugin is disabled, but still loaded into the service worker. + This is useful if you want to have the redirect plugin loaded and on the ready in case the original website goes completely down. Having the plugin loaded but disabled means that it can be enabled by a configuration change, which [can be pushed out even when the original website is not accessible](../../docs/UPDATING_DURING_DISRUPTION.md). diff --git a/plugins/signed-integrity/README.md b/plugins/signed-integrity/README.md index 4abbbc3..5b5ce0b 100644 --- a/plugins/signed-integrity/README.md +++ b/plugins/signed-integrity/README.md @@ -1,4 +1,37 @@ -# Plugin: `signed-integrity +# Plugin: `signed-integrity` - **status**: alpha -- **type**: [wrapping plugin](https://gitlab.com/rysiekpl/libresilient/-/blob/master/docs/ARCHITECTURE.md#wrapping-plugins) +- **type**: [wrapping plugin](../../docs/ARCHITECTURE.md#wrapping-plugins) + +The `signed-integrity` plugin provides a way to retrieve authenticated integrity data for content fetched from untrusted sources (alternative endpoints, open proxies, etc). + +It does not provide for confidentiality (as this is not something LibResilient is designed to provide in general), and it does not by itself perform integrity checking — it only retrieves verified integrity data and sets it on a request. + +## Configuration + +The `signed-integrity` plugin supports the following configuration options: + + - `publicKey` (required) + A public key used for signature verification on integrity files, as a JSONWebKey object compatible with [SubtleCrypto `importKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey). Currently the algorithm is hard-coded as `ECDSA` with the `P-384` curve; `keyUsages` must include "`verify`". + + - `integrityFileSuffix` (default: "`.integrity`") + Suffix of integrity data files. This suffix is appended to each URL being fetched in order to retrieve authenticated integrity data for it. + + - `requireIntegrity` (default: `false`) + Is integrity data *required* for all requests? + If set to `true`, every request needs to have integrity data associated with it, either through it being retrieved by this plugin, or by the virtue of it having been already set on the request before it started being handled by this plugin. + + - `uses` (default: "[`fetch`](../fetch/)") + An Array containing exactly one object: config of the wrapped plugin that will actually handle requests. + That wrapped plugin will handle both the integrity file requests and the actual content requests for content being handled by the `signed-integrity` plugin. + By default, the [`fetch`](../fetch/) plugin is used, because it relies on the Fetch API that can be expected to actually verify integrity of fetched content. If you want to use a different transport plugin, remember to make sure that it verifies subresource integrity when provided in the request data, or wrap it in an integrity-checking wrapper plugin (like [`integrity-check`](../integrity-check/)) to make sure integrity is in fact verified when available. + +## Operation + +The `signed-integrity` plugin demonstrates how [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can be used to provide verification of authenticity of resources retrieved from not entirely trusted sources (alternative endpoints, open proxies, etc). For each content URL being fetched, the plugin first fetches integrity data from an URL built by appending `integrityFileSuffix` (by default: "`.integrity`") to the content URL, expecting it to contain a [JSON Web Token (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token). + +That JWT’s signature is verified using a configured public key (assumption being that it was signed with a related private key before pushing the content out to alternatve endpoints). JWT’s payload should contain an `integrity` field, which is then used to set the SRI data on the request being handled. Only then does the request for the actual content (now with [integrity data set on it](https://developer.mozilla.org/en-US/docs/Web/API/Request/integrity)) proceed. + +**IMPORTANT:** This plugin does not itself *check* integrity of the response! + +This is left to the wrapped plugin to perform that check. For example, integrity checks will happen automatically with [`fetch`](../fetch/) and [`alt-fetch`](../alt-fetch/) plugins, since they rely directly on the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/fetch). You can use the [`integrity-check`](../integrity-check/) plugin to perform integrity verification for transports that do cannot be assumed to perform integrity checks on their own.