I’m wondering about this due to recent security incidents related to third party js.
It seems to me, that if the origional, trusted, html/js has the hashes of the third party js, then it should be possible to verify that it has not been tampered with.
There is a feature is most modern browsers today called “Subresource Integrity” that is supposed to help with this. It looks something like this:
When retrieving the file, the browser first hashes it and makes sure it’s the correct hash. If it’s not, it refuses to run it. Here is the full spec: https://w3c.github.io/webappsec-subresource-integrity/
Would be nice if we could hook js-ipfs into that somehow.
A IPFS hash like
QmYtUc4iTCbbfVSDNKvtQqrfyezPPnFvE33wFmutw9PBBk which is base58, would have to converted into base64 and adding the hash function before (which means we have the hash function twice…)
Then somehow overload the loading of resources and load them from IPFS instead. Maybe something we can do with the ipfs-companion (https://github.com/ipfs/ipfs-companion) @lidel?
Yup, I was looking into ways we could utilize SRI attribute some time ago.
Actually, if you load content-addressed asset such as script or stylesheet via js-ipfs or a local gateway, IPFS will provide you with same guarantees as SRI without any additional configuration
So, how can IPFS add a real value on top of (or instead of) SRI?
Opportunistically load static assets from IPFS (where BOTH browser user and website owner opt-in)
Site owner: make sure immutable assets are under valid IPFS paths (
Browser user: install browser extension and have local gateway running
Result: assets will be loaded via IPFS and go-ipfs daemon will take care of hash checks (even if no SRI is defined in site’s HTML)
Opportunistically load static assets from IPFS (requires ONLY website owner to opt-in)
Similar to the above, but website owner installs a service worker that replaces HTTP requests with IPFS ones in a way that is transparent to the end user – see this experiment: https://github.com/ipfs/in-web-browsers/issues/55
This could also be implemented without Service Worker, e.g. as a plain script that detects IPFS paths in
src attributes and replaces them with data URL build from bytes read via js-ipfs. Or performs SRI2IPFS lookups somehow.
Distributed CDN for all assets with SRI attribute (requires browser extension)
It is safe to assume that asset with SRI is immutable. Browser extension could automatically mirror such content to IPFS (ipfs-companion/issues/96). There is chicken-and-egg problem that makes implementation quite complex: if we try to load via IPFS, but it is not there, then we load via HTTP and publish to IPFS.
Anyway, assuming it is feasible to use transformed hash from SRI for IPFS lookups, this scheme would create a distributed, deduplicated version of global CDNs such as http://jsdelivr.com
- Potential problems
- SRI -> CID lookups won’t work unless we explicitly disable chunking while adding assets to IPFS:
I think 1:1 conversion between SRI and CIDv0 (multihash) would work only for small, non-chunked files, as bigger files would produce different hashes (and we live in times when
.js file bigger than 256KiB).
Is it possible to disable chunking?
- redirecting to local gateway would break some sites - we would have to disable this for sites with restrictive CSP rules etc