From dbae9ecd84bd7dcae2356034a38db28ceae1a626 Mon Sep 17 00:00:00 2001 From: Vesa Luusua Date: Tue, 5 Feb 2019 15:15:51 +0200 Subject: [PATCH] Add audit script --- .auditrc | 14 +++++++++ .nsprc | 10 ------ package.json | 1 + scripts/audit.js | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 .auditrc delete mode 100644 .nsprc create mode 100644 scripts/audit.js diff --git a/.auditrc b/.auditrc new file mode 100644 index 00000000..e17295fa --- /dev/null +++ b/.auditrc @@ -0,0 +1,14 @@ +exports.exceptions = [ + // Severity: low, moment (< 2.19.3), currently used by react-dates + "https://npmjs.com/advisories/532", + + // Severity: low, lodash (< 4.17.5), used heavily in our CRA fork + "https://npmjs.com/advisories/577", + + // Severity: low, merge (< 1.2.1), used by Jest (CRA fork) + "https://npmjs.com/advisories/722", + + // Severity: high, webpack-dev-server (< 3.1.10), (CRA fork) + // Note: don't run webpack-dev-server on public web. + "https://npmjs.com/advisories/725", +]; diff --git a/.nsprc b/.nsprc deleted file mode 100644 index eb9adf46..00000000 --- a/.nsprc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "exceptions": [ - "https://nodesecurity.io/advisories/532", - "https://nodesecurity.io/advisories/157", - "https://nodesecurity.io/advisories/577", - "https://nodesecurity.io/advisories/654", - "https://nodesecurity.io/advisories/664", - "https://nodesecurity.io/advisories/678" - ] -} diff --git a/package.json b/package.json index 8a1345ae..e2b72503 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "prettier": "^1.15.3" }, "scripts": { + "audit": "yarn audit --json | node scripts/audit.js", "clean": "rm -rf build/*", "config": "node scripts/config.js", "dev": "node scripts/config.js --check && sharetribe-scripts start", diff --git a/scripts/audit.js b/scripts/audit.js new file mode 100644 index 00000000..e732987d --- /dev/null +++ b/scripts/audit.js @@ -0,0 +1,79 @@ +// Check possible npm dependency vulnerabilities +// Usage: execute "yarn run audit" in the shell +// +// You can add exceptions through .nsprc file, which is a hidden file in root folder. +// +// Note: to use this script, you should pipe in the output of 'yarn audit --json' + +const bfj = require('bfj'); +const fs = require('fs'); +const exceptions = require('../.auditrc').exceptions; + +const INDENT = ' '; +const isAuditAdvisory = o => o.type === 'auditAdvisory'; + +// get an advisory or empty object +const getAdvisory = o => (!o ? {} : !o.data ? {} : !o.data.advisory ? {} : o.data.advisory); +// get a resolution or empty object +const getResolution = o => (!o ? {} : !o.data ? {} : !o.data.resolution ? {} : o.data.resolution); + +// Read the output of 'yarn audit --json', which should be piped in through stdin +const stdinStream = process.stdin.resume(); +let advisories = {}; +bfj + .match(stdinStream, (key, value, depth) => depth === 0, { ndjson: true }) + .on('data', object => { + if (isAuditAdvisory(object) && Array.isArray(exceptions)) { + const { id, severity, title, url } = getAdvisory(object); + const { path } = getResolution(object); + const isInExceptionList = url && exceptions.includes(url); + + if (!isInExceptionList && url && path) { + const advisory = advisories[id] ? advisories[id] : { url, severity, title }; + const paths = advisory.paths ? advisory.paths : []; + advisories[id] = { ...advisory, paths: paths.concat(path) }; + } + } + }) + .on('dataError', error => { + // A syntax error was found in the JSON + console.error( + `An error occurred while processing data. + You need to pipe the results of "yarn audit --json" to this script from shell. + Error`, + error + ); + process.exit(1); + }) + .on('error', error => { + // Some kind of operational error occurred + console.error( + `An error occurred while processing data. + You need to pipe the results of "yarn audit --json" to this script from shell. + Error`, + error + ); + process.exit(1); + }) + .on('end', error => { + const advisoryKeys = Object.keys(advisories); + if (advisoryKeys.length > 0) { + console.log('Vulneralibilities found:'); + console.log('\n----------------------------------------\n'); + + advisoryKeys.forEach(key => { + const { title, severity, url, paths } = advisories[key]; + console.log(key, `(${title})`); + console.log('Severity:', severity); + console.log('More info:', url); + console.log('Affected dependencies:'); + paths.forEach(path => { + console.log(INDENT, path); + }); + console.log('\n----------------------------------------\n'); + }); + process.exit(1); + } else { + process.exit(); + } + });