Add audit script

This commit is contained in:
Vesa Luusua 2019-02-05 15:15:51 +02:00
parent 49ad3f9395
commit dbae9ecd84
4 changed files with 94 additions and 10 deletions

14
.auditrc Normal file
View file

@ -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",
];

10
.nsprc
View file

@ -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"
]
}

View file

@ -66,6 +66,7 @@
"prettier": "^1.15.3" "prettier": "^1.15.3"
}, },
"scripts": { "scripts": {
"audit": "yarn audit --json | node scripts/audit.js",
"clean": "rm -rf build/*", "clean": "rm -rf build/*",
"config": "node scripts/config.js", "config": "node scripts/config.js",
"dev": "node scripts/config.js --check && sharetribe-scripts start", "dev": "node scripts/config.js --check && sharetribe-scripts start",

79
scripts/audit.js Normal file
View file

@ -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();
}
});