From bf26b842be775faf2961ac76355e9eecf262ed5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Mon, 12 Mar 2018 19:24:56 -0700 Subject: [PATCH 1/2] feat(checkData): optionally throw when checkData fails --- README.md | 4 ++++ index.js | 33 +++++++++++++++++++++++++++++++-- test/check.js | 12 ++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8011418..a6c07e7 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,9 @@ If `opts.pickAlgorithm` is provided, it will be used by [`Integrity#pickAlgorithm`](#integrity-pick-algorithm) when deciding which of the available digests to match against. +If `opts.error` is true, and verification fails, `checkData` will throw either +an `EBADSIZE` or an `EINTEGRITY` error, instead of just returning false. + ##### Example ```javascript @@ -396,6 +399,7 @@ const data = fs.readFileSync('index.js') ssri.checkData(data, ssri.fromData(data)) // -> 'sha512' ssri.checkData(data, 'sha256-l981iLWj8kurw4UbNy8Lpxqdzd7UOxS50Glhv8FwfZ0') ssri.checkData(data, 'sha1-BaDDigEST') // -> false +ssri.checkData(data, 'sha1-BaDDigEST', {error: true}) // -> Error! EINTEGRITY ``` #### `> ssri.checkStream(stream, sri, [opts]) -> Promise` diff --git a/index.js b/index.js index 5418256..ff7881f 100644 --- a/index.js +++ b/index.js @@ -216,10 +216,39 @@ module.exports.checkData = checkData function checkData (data, sri, opts) { opts = opts || {} sri = parse(sri, opts) - if (!Object.keys(sri).length) { return false } + if (!Object.keys(sri).length) { + if (opts.error) { + throw Object.assign( + new Error('No valid integrity hashes to check against'), { + code: 'EINTEGRITY' + } + ) + } else { + return false + } + } const algorithm = sri.pickAlgorithm(opts) const digest = crypto.createHash(algorithm).update(data).digest('base64') - return parse({algorithm, digest}).match(sri, opts) + const newSri = parse({algorithm, digest}) + const match = newSri.match(sri, opts) + if (match || !opts.error) { + return match + } else if (typeof opts.size === 'number' && (data.length !== opts.size)) { + const err = new Error(`data size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${data.length}`) + err.code = 'EBADSIZE' + err.found = data.length + err.expected = opts.size + err.sri = sri + throw err + } else { + const err = new Error(`Integrity checksum failed when using ${algorithm}: Wanted ${sri}, but got ${newSri}. (${data.length} bytes)`) + err.code = 'EINTEGRITY' + err.found = newSri + err.expected = sri + err.algorithm = algorithm + err.sri = sri + throw err + } } module.exports.checkStream = checkStream diff --git a/test/check.js b/test/check.js index e099716..029c0ee 100644 --- a/test/check.js +++ b/test/check.js @@ -28,6 +28,9 @@ test('checkData', t => { meta, 'Buffer data successfully verified' ) + t.doesNotThrow(() => { + ssri.checkData(TEST_DATA, sri, {error: true}) + }, 'error not thrown when error: true and data verifies') t.deepEqual( ssri.checkData(TEST_DATA, `sha512-${hash(TEST_DATA, 'sha512')}`), meta, @@ -59,6 +62,12 @@ test('checkData', t => { false, 'returns false when verification fails' ) + t.throws(() => { + ssri.checkData('nope', sri, {error: true}) + }, /Integrity checksum failed/, 'integrity error thrown when error: true with bad data') + t.throws(() => { + ssri.checkData('nope', sri, {error: true, size: 3}) + }, /data size mismatch/, 'size error thrown when error: true with bad size') t.equal( ssri.checkData('nope', 'sha512-nope'), false, @@ -74,6 +83,9 @@ test('checkData', t => { false, 'returns false on empty sri input' ) + t.throws(() => { + ssri.checkData('nope', '', {error: true}) + }, /No valid integrity hashes/, 'errors on empty sri input if error: true') t.deepEqual( ssri.checkData(TEST_DATA, [ 'sha512-nope', From 0ae0c237690d0b33613524a318ec617b8a61f8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Mon, 12 Mar 2018 19:25:04 -0700 Subject: [PATCH 2/2] chore(release): 5.3.0 --- CHANGELOG.md | 10 ++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f90bb70..5c06894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +# [5.3.0](https://github.com/zkat/ssri/compare/v5.2.4...v5.3.0) (2018-03-13) + + +### Features + +* **checkData:** optionally throw when checkData fails ([bf26b84](https://github.com/zkat/ssri/commit/bf26b84)) + + + ## [5.2.4](https://github.com/zkat/ssri/compare/v5.2.3...v5.2.4) (2018-02-16) diff --git a/package-lock.json b/package-lock.json index 82bb26c..4c7c976 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ssri", - "version": "5.2.4", + "version": "5.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 855e862..2973d23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssri", - "version": "5.2.4", + "version": "5.3.0", "description": "Standard Subresource Integrity library -- parses, serializes, generates, and verifies integrity metadata according to the SRI spec.", "main": "index.js", "files": [