Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Subresource Integrity support #78

Merged
merged 1 commit into from
Apr 3, 2017
Merged

Subresource Integrity support #78

merged 1 commit into from
Apr 3, 2017

Conversation

zkat
Copy link
Owner

@zkat zkat commented Mar 22, 2017

This PR changes all digest-related API bits. Now, instead of having to always pair up a digest with a hashAlgorithm, a single string can be used. This is based on the Subresource Integrity spec, which is what browsers use for this sort of checking.

This is a major breaking change because it changes the way all the digest options are used. It'll also bump the index version again.

This PR will not change content storage format: that should keep using the hex version of the digest, because the current filesystem structure is much more friendly across platforms. base64 encodings have case-variance (which messed with OSX and Windows), as well as some characters like / and + that will inevitably confuse someone's tool/script at some point.

Note that hashAlgorithm will still be an option for put/put.stream.

The biggest reason for doing this is realizing how unergonomic it was to always have to pass in hashAlgorithm whenever get/put was being used with a digest -- in some cases requiring modification of opts. It has also been a source of bugs both in pacote and cacache itself. I'd much rather simplify this by keeping these two bits together.

@iarna
Copy link
Collaborator

iarna commented Mar 23, 2017

It's worth noting that the base64 variant they're using is not filesystem-safe, so you're going to have to reencode hashes before writing them to filenames.

I presume they're using RFC-4648 variation, though they don't seem to specify. (Their examples use openssl but its docs don't specify either.) The wikipedia page has a good summary of the many, many base64 variations.

(4648 has a filesystem safe variation, but the examples in the Subsource Integrity spec have / in them, so they clearly aren't using it.)

@zkat
Copy link
Owner Author

zkat commented Mar 23, 2017

@iarna I mentioned this in the description: the content format is not changing. Only the entry format and the JS-side API.

BREAKING CHANGE: The entire API has been overhauled to use SRI hashes instead of digest/hashAlgorithm pairs. SRI hashes follow the Subresource Integrity standard and support strings and objects compatible with [`ssri`](https://npm.im/ssri).

* This change bumps the index version, which will invalidate all previous index entries. Content entries will remain intact, and existing caches will automatically reuse any content from before this breaking change.

* `cacache.get.info()`, `cacache.ls(), and `cacache.ls.stream()` will now return objects that looks like this:

```
{
  key: String,
  integrity: '<algorithm>-<base64hash>',
  path: ContentPath,
  time: Date<ms>,
  metadata: Any
}
```

* `opts.digest` and `opts.hashAlgorithm` are obsolete for any API calls that used them.

* Anywhere `opts.digest` was accepted, `opts.integrity` is now an option. Any valid SRI hash is accepted here -- multiple hash entries will be resolved according to the standard: first, the "strongest" hash algorithm will be picked, and then each of the entries for that algorithm will be matched against the content. Content will be validated if *any* of the entries match (so, a single integrity string can be used for multiple "versions" of the same document/data).

* `put.byDigest()`, `put.stream.byDigest`, `get.byDigest()` and `get.stream.byDigest() now expect an SRI instead of a `digest` + `opts.hashAlgorithm` pairing.

* `get.hasContent()` now expects an integrity hash instead of a digest. If content exists, it will return the specific single integrity hash that was found in the cache.

* `verify()` has learned to handle integrity-based caches, and forgotten how to handle old-style cache indices due to the format change.

* `cacache.rm.content()` now expects an integrity hash instead of a hex digest.
@zkat zkat merged commit b1e731f into latest Apr 3, 2017
@zkat zkat deleted the zkat/integrity branch April 3, 2017 07:40
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants