docs: CONTEINT_INTEGRITY.md updated and amended with signed-integrity plugin info

merge-requests/9/merge
Michał 'rysiek' Woźniak 2022-01-13 22:22:52 +00:00
rodzic d42b6a11c0
commit 9d6186e7f3
1 zmienionych plików z 17 dodań i 4 usunięć

Wyświetl plik

@ -8,15 +8,15 @@ On the other hand, when using `alt-fetch` and fetching content from multiple end
## Subresource Integrity
To some extent, this is what [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can help fix.
[Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) can help fix it to some extent.
It was introduced to provide assurances when including content hosted on third-party endpoints, like major CDNs. In the HTML code, not just an URL for a `<script>` or `<link>` element would be specified, but also an `integrity` value. The browser then fetches the content and immediately checks if the hash matches the `integrity` value set on the relevant element.
## SRI and LibResilient
SRI can be used with LibResilient directly, by specifying the `integrity` value on `<script>` and `<link>` elements in HTML, of course. These values will be provided by the Service Worker to each plugin that is handling the request. If integrity verification fails, the plugin returns an error, and the next plugin takes over, as per regular LibResilient request handling flow.
SRI can of course be used with LibResilient directly, by specifying the `integrity` value on `<script>` and `<link>` elements in HTML. These values will be provided by the Service Worker to each plugin that is handling the request. If integrity verification fails, the plugin returns an error, and the next plugin takes over, as per regular LibResilient request handling flow.
However, whether or not integrity is *actually* verified depends on the plugin used.
However, whether or not integrity is *actually* verified depends on the plugins used.
For example, integrity (when set for a given request) *will* be verified when using `fetch` and `alt-fetch` plugins, simply because under the hood these plugins use the regular [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), as implemented by the browser. The Fetch API [`fetch()` method](https://developer.mozilla.org/en-US/docs/Web/API/fetch) accepts an `integrity` init param, and is expected to use it to verify integrity.
@ -97,6 +97,16 @@ self.LibResilientConfig.plugins = [{
}]
```
## Integrity data for dynamic resources
Ideally, there would be a way to fetch integrity data dynamically, such that it would not have to be configured for each resource beforehand. This would enable SRI to be used to also secure dynamic websites that use LibResilient. This would require a way of fetching the integrity data for each URL, and then authenticating it -- after all, the *reason* why we need SRI is *because* we don't trust the transports.
The `signed-integrity` proof-of-concept plugin implements exactly that. For each URL, it implicitly tries to first fetch that URL combined with `.integrity` (so, for `/favicon.ico` it would first try to fetch `/favicon.ico.integrity`). It expects it to contain a [JSON Web Token](https://en.wikipedia.org/wiki/JSON_Web_Token), signed by an ECDSA private key (controlled by the website admin and not accessible to anyone else). The related public key is added to `signed-integrity` configuration.
The JWT is verified using that configured public key; its payload should contain an `integrity` field with the integrity data for the target URL (so, for `favicon.ico` in our example above). That integrity data is then added to the request for the target URL that is then handled by a wrapped transport plugin.
This way, the `signed-integrity` plugin would replace the `integrity` plugin in scenarios above, making it possible to provide SRI for dynamic resources. It is up to the wrapped plugin to actually verify the integrity based on data in the request.
## Downsides
The downside of the **`integrity-check`** plugin is that performance can be expected to be worse than if integrity checking was done directly by the browser (as part of a Fetch API `fetch()` call).
@ -107,10 +117,13 @@ The downside of the **`basic-integrity`** plugin is that it requires the integri
This makes it very static, and not very useful for most (rather dynamic) websites.
The downside of the **`signed-integrity`** plugin, apart from it being a proof-of-concept currently, is the added complexity and effectively doubling of the number of requests (for each URL, an additional integrity URL is also fetched).
As with any security measure, the plugin offers additional protection (in this case, from Person-in-the-Middle attacks by the transport providers) at the cost of reliability -- for example, bad configuration (incorrect public key) might mean content that is possible to fetch will be inaccessible.
## Future development
There are a few potential avenues of making content integrity more useful in LibResilient:
1. [Making config updates possible during disruption](%3) (that is, even if the site's main domain is inaccessible), and generally making the config more dynamic and easy to push changes to, would make `basic-integrity` plugin considerably more useful.
1. Implementing some form of [dynamic integrity source, verified by cryptographic signatures](#28), would make it possible to fetch the integrity data for a given resource while fetching that resource, authenticate integrity data using a public key, and then use the authenticated integrity data to verify the content itself.
1. For IPFS-based transport plugins, [integrity data could be extracted directly from the CID](https://gitlab.com/rysiekpl/libresilient/-/issues/1#note_727844150). This would make it possible to verify integrity of content fetched using them (if we don't trust it for whatever reason) without providing integrity data separately.