This commit is contained in:
2022-07-18 02:50:52 +00:00
parent befd344ab0
commit 06181b34d6
8569 changed files with 818704 additions and 352705 deletions
+32
View File
@@ -2,6 +2,38 @@
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.
### [8.0.1](https://github.com/npm/ssri/compare/v8.0.0...v8.0.1) (2021-01-27)
### Bug Fixes
* simplify regex for strict mode, add tests ([76e2233](https://github.com/npm/ssri/commit/76e223317d971f19e4db8191865bdad5edee40d2))
## [8.0.0](https://github.com/npm/ssri/compare/v7.1.0...v8.0.0) (2020-02-18)
### ⚠ BREAKING CHANGES
* SRI values with `../` in the algorithm name now throw
as invalid (which they always probably should have!)
* adds a new error that will be thrown. Empty SRIs are
no longer considered valid for checking, only when using integrityStream
to calculate the SRI value.
PR-URL: https://github.com/npm/ssri/pull/12
Credit: @claudiahdz
### Features
* remove figgy-pudding ([0e78fd7](https://github.com/npm/ssri/commit/0e78fd7b754e2d098875eb4c57238709d96d7c27))
### Bug Fixes
* harden SRI parsing against ../ funny business ([4062735](https://github.com/npm/ssri/commit/4062735d1281941fd32ac4320b9f9965fcec278b))
* IntegrityStream responds to mutating opts object mid-stream ([4a963e5](https://github.com/npm/ssri/commit/4a963e5982478c6b07f86848cdb72d142c765195))
* throw null when sri is empty or bad ([a6811cb](https://github.com/npm/ssri/commit/a6811cba71e20ea1fdefa6e50c9ea3c67efc2500)), closes [#12](https://github.com/npm/ssri/issues/12)
## [7.1.0](https://github.com/npm/ssri/compare/v7.0.1...v7.1.0) (2019-10-24)
Generated Vendored
+64 -48
View File
@@ -1,29 +1,31 @@
'use strict'
const crypto = require('crypto')
const figgyPudding = require('figgy-pudding')
const MiniPass = require('minipass')
const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512']
// TODO: this should really be a hardcoded list of algorithms we support,
// rather than [a-z0-9].
const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i
const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/
const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/
const SRI_REGEX = /^([a-z0-9]+)-([^?]+)([?\S*]*)$/
const STRICT_SRI_REGEX = /^([a-z0-9]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)?$/
const VCHAR_REGEX = /^[\x21-\x7E]+$/
const SsriOpts = figgyPudding({
algorithms: { default: ['sha512'] },
error: { default: false },
integrity: {},
options: { default: [] },
pickAlgorithm: { default: () => getPrioritizedHash },
sep: { default: ' ' },
single: { default: false },
size: {},
strict: { default: false }
})
const defaultOpts = {
algorithms: ['sha512'],
error: false,
options: [],
pickAlgorithm: getPrioritizedHash,
sep: ' ',
single: false,
strict: false
}
const getOptString = options => !options || !options.length ? ''
const ssriOpts = (opts = {}) => ({ ...defaultOpts, ...opts })
const getOptString = options => !options || !options.length
? ''
: `?${options.join('?')}`
const _onEnd = Symbol('_onEnd')
@@ -38,21 +40,27 @@ class IntegrityStream extends MiniPass {
this[_getOptions]()
// options used for calculating stream. can't be changed.
const { algorithms = defaultOpts.algorithms } = opts
this.algorithms = Array.from(
new Set(opts.algorithms.concat(this.algorithm ? [this.algorithm] : []))
new Set(algorithms.concat(this.algorithm ? [this.algorithm] : []))
)
this.hashes = this.algorithms.map(crypto.createHash)
}
[_getOptions] () {
const opts = this.opts
const {
integrity,
size,
options
} = { ...defaultOpts, ...this.opts }
// For verification
this.sri = opts.integrity ? parse(opts.integrity, opts) : null
this.expectedSize = opts.size
this.sri = integrity ? parse(integrity, this.opts) : null
this.expectedSize = size
this.goodSri = this.sri ? !!Object.keys(this.sri).length : false
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(opts) : null
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(this.opts) : null
this.digests = this.goodSri ? this.sri[this.algorithm] : null
this.optString = getOptString(opts.options)
this.optString = getOptString(options)
}
emit (ev, data) {
@@ -101,7 +109,7 @@ class IntegrityStream extends MiniPass {
class Hash {
get isHash () { return true }
constructor (hash, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const strict = !!opts.strict
this.source = hash.trim()
@@ -138,7 +146,7 @@ class Hash {
}
toString (opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
if (opts.strict) {
// Strict mode enforces the standard as close to the foot of the
// letter as it can.
@@ -172,8 +180,12 @@ class Integrity {
return this.toString()
}
isEmpty () {
return Object.keys(this).length === 0
}
toString (opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
let sep = opts.sep || ' '
if (opts.strict) {
// Entries must be separated by whitespace, according to spec.
@@ -187,7 +199,7 @@ class Integrity {
}
concat (integrity, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const other = typeof integrity === 'string'
? integrity
: stringify(integrity, opts)
@@ -201,7 +213,7 @@ class Integrity {
// add additional hashes to an integrity value, but prevent
// *changing* an existing integrity hash.
merge (integrity, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const other = parse(integrity, opts)
for (const algo in other) {
if (this[algo]) {
@@ -217,7 +229,7 @@ class Integrity {
}
match (integrity, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const other = parse(integrity, opts)
const algo = other.pickAlgorithm(opts)
return (
@@ -232,14 +244,9 @@ class Integrity {
}
pickAlgorithm (opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const pickAlgorithm = opts.pickAlgorithm
const keys = Object.keys(this)
if (!keys.length) {
throw new Error(`No algorithms available for ${
JSON.stringify(this.toString())
}`)
}
return keys.reduce((acc, algo) => {
return pickAlgorithm(acc, algo) || acc
})
@@ -248,7 +255,8 @@ class Integrity {
module.exports.parse = parse
function parse (sri, opts) {
opts = SsriOpts(opts)
if (!sri) return null
opts = ssriOpts(opts)
if (typeof sri === 'string') {
return _parse(sri, opts)
} else if (sri.algorithm && sri.digest) {
@@ -266,7 +274,7 @@ function _parse (integrity, opts) {
if (opts.single) {
return new Hash(integrity, opts)
}
return integrity.trim().split(/\s+/).reduce((acc, string) => {
const hashes = integrity.trim().split(/\s+/).reduce((acc, string) => {
const hash = new Hash(string, opts)
if (hash.algorithm && hash.digest) {
const algo = hash.algorithm
@@ -275,11 +283,12 @@ function _parse (integrity, opts) {
}
return acc
}, new Integrity())
return hashes.isEmpty() ? null : hashes
}
module.exports.stringify = stringify
function stringify (obj, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
if (obj.algorithm && obj.digest) {
return Hash.prototype.toString.call(obj, opts)
} else if (typeof obj === 'string') {
@@ -291,7 +300,7 @@ function stringify (obj, opts) {
module.exports.fromHex = fromHex
function fromHex (hexDigest, algorithm, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const optString = getOptString(opts.options)
return parse(
`${algorithm}-${
@@ -302,7 +311,7 @@ function fromHex (hexDigest, algorithm, opts) {
module.exports.fromData = fromData
function fromData (data, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const algorithms = opts.algorithms
const optString = getOptString(opts.options)
return algorithms.reduce((acc, algo) => {
@@ -325,7 +334,7 @@ function fromData (data, opts) {
module.exports.fromStream = fromStream
function fromStream (stream, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const istream = integrityStream(opts)
return new Promise((resolve, reject) => {
stream.pipe(istream)
@@ -340,9 +349,9 @@ function fromStream (stream, opts) {
module.exports.checkData = checkData
function checkData (data, sri, opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
sri = parse(sri, opts)
if (!Object.keys(sri).length) {
if (!sri || !Object.keys(sri).length) {
if (opts.error) {
throw Object.assign(
new Error('No valid integrity hashes to check against'), {
@@ -379,10 +388,17 @@ function checkData (data, sri, opts) {
module.exports.checkStream = checkStream
function checkStream (stream, sri, opts) {
opts = SsriOpts(opts)
const checker = integrityStream(opts.concat({
integrity: sri
}))
opts = ssriOpts(opts)
opts.integrity = sri
sri = parse(sri, opts)
if (!sri || !Object.keys(sri).length) {
return Promise.reject(Object.assign(
new Error('No valid integrity hashes to check against'), {
code: 'EINTEGRITY'
}
))
}
const checker = integrityStream(opts)
return new Promise((resolve, reject) => {
stream.pipe(checker)
stream.on('error', reject)
@@ -395,13 +411,13 @@ function checkStream (stream, sri, opts) {
}
module.exports.integrityStream = integrityStream
function integrityStream (opts) {
return new IntegrityStream(SsriOpts(opts))
function integrityStream (opts = {}) {
return new IntegrityStream(opts)
}
module.exports.create = createIntegrity
function createIntegrity (opts) {
opts = SsriOpts(opts)
opts = ssriOpts(opts)
const algorithms = opts.algorithms
const optString = getOptString(opts.options)
+22 -26
View File
@@ -1,32 +1,32 @@
{
"_args": [
[
"ssri@7.1.0",
"/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series"
"ssri@8.0.1",
"/home/node/nuxt"
]
],
"_from": "ssri@7.1.0",
"_id": "ssri@7.1.0",
"_from": "ssri@8.0.1",
"_id": "ssri@8.0.1",
"_inBundle": false,
"_integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==",
"_integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
"_location": "/ssri",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ssri@7.1.0",
"raw": "ssri@8.0.1",
"name": "ssri",
"escapedName": "ssri",
"rawSpec": "7.1.0",
"rawSpec": "8.0.1",
"saveSpec": null,
"fetchSpec": "7.1.0"
"fetchSpec": "8.0.1"
},
"_requiredBy": [
"/cacache"
],
"_resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz",
"_spec": "7.1.0",
"_where": "/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series",
"_resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
"_spec": "8.0.1",
"_where": "/home/node/nuxt",
"author": {
"name": "Kat Marchán",
"email": "kzm@sykosomatic.org"
@@ -35,23 +35,18 @@
"url": "https://github.com/npm/ssri/issues"
},
"dependencies": {
"figgy-pudding": "^3.5.1",
"minipass": "^3.1.1"
},
"description": "Standard Subresource Integrity library -- parses, serializes, generates, and verifies integrity metadata according to the SRI spec.",
"devDependencies": {
"standard": "^14.3.0",
"standard-version": "^7.0.0",
"tap": "^14.8.2",
"weallbehave": "^1.2.0",
"weallcontribute": "^1.0.8"
"standard": "^16.0.3",
"standard-version": "^9.1.0",
"tap": "^14.10.6"
},
"engines": {
"node": ">= 8"
},
"files": [
"*.js"
],
"files": [],
"homepage": "https://github.com/npm/ssri#readme",
"keywords": [
"w3c",
@@ -75,16 +70,17 @@
"url": "git+https://github.com/npm/ssri.git"
},
"scripts": {
"postrelease": "npm publish && git push --follow-tags",
"coverage": "tap",
"lint": "standard",
"postrelease": "npm publish",
"posttest": "npm run lint",
"prepublishOnly": "git push --follow-tags",
"prerelease": "npm t",
"pretest": "standard",
"release": "standard-version -s",
"test": "tap -J --coverage test/*.js",
"update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",
"update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'"
"test": "tap"
},
"tap": {
"check-coverage": true
},
"version": "7.1.0"
"version": "8.0.1"
}