better-npm-audit
Advanced tools
Comparing version
113
index.js
@@ -7,9 +7,8 @@ #!/usr/bin/env node | ||
const program = require("commander"); | ||
const { exec } = require("child_process"); | ||
const program = require('commander'); | ||
const { exec } = require('child_process'); | ||
const packageJson = require('./package'); | ||
const BASE_COMMAND = "npm audit"; | ||
const SEPARATOR = ","; | ||
const SPLIT_REGEX = /(https:\/\/(nodesecurity.io|npmjs.com)\/advisories\/)/; | ||
const DIGIT_REGEX = /^\d+$/; | ||
const BASE_COMMAND = 'npm audit'; | ||
const SEPARATOR = ','; | ||
const DEFAULT_MESSSAGE_LIMIT = 100000; // characters | ||
@@ -23,11 +22,11 @@ const MAX_BUFFER_SIZE = 1024 * 1000 * 50; // 50 MB | ||
*/ | ||
const mapLevelToNumber = (auditLevel) => { | ||
function mapLevelToNumber(auditLevel) { | ||
switch (auditLevel) { | ||
case "low": | ||
case 'low': | ||
return 1; | ||
case "moderate": | ||
case 'moderate': | ||
return 2; | ||
case "high": | ||
case 'high': | ||
return 3; | ||
case "critical": | ||
case 'critical': | ||
return 4; | ||
@@ -37,6 +36,2 @@ default: | ||
} | ||
}; | ||
function unique(value, index, self) { | ||
return self.indexOf(value) === index; | ||
} | ||
@@ -49,7 +44,7 @@ | ||
*/ | ||
function auditLog(auditCommand, fullLog) { | ||
function auditLog(auditCommand, fullLog, vulnerabilities) { | ||
// Execute `npm audit` command again, but this time we don't use the JSON flag | ||
const audit = exec(auditCommand); | ||
audit.stdout.on("data", (data) => { | ||
audit.stdout.on('data', data => { | ||
if (fullLog) { | ||
@@ -63,18 +58,26 @@ console.info(data); | ||
if (toDisplay.length < data.length) { | ||
console.info(""); | ||
console.info("..."); | ||
console.info(""); | ||
console.info( | ||
"[MAXIMUM EXCEEDED] Logs exceeded the maximum characters limit. Add the flag `-f` to see the full audit logs." | ||
); | ||
console.info(""); | ||
console.info(''); | ||
console.info('...'); | ||
console.info(''); | ||
console.info('[MAXIMUM EXCEEDED] Logs exceeded the maximum length limit. Add the flag `-f` to see the full audit logs.'); | ||
console.info(''); | ||
} | ||
} | ||
// Happy happy, joy joy | ||
console.info("🤝 All good!"); | ||
}); | ||
// Once the stdout has completed | ||
audit.stderr.on('close', () => { | ||
// Display the error if found vulnerabilities | ||
if (vulnerabilities.length > 0) { | ||
const message = `${vulnerabilities.length} vulnerabilities found. Node security advisories: ${vulnerabilities}`; | ||
throw new Error(message); | ||
} else { | ||
// Happy happy, joy joy | ||
console.info('🤝 All good!'); | ||
} | ||
}); | ||
// stderr | ||
audit.stderr.on("data", (data) => { | ||
console.info(data); | ||
audit.stderr.on('data', data => { | ||
console.error(data); | ||
}); | ||
@@ -94,11 +97,10 @@ } | ||
// NOTE: Increase max buffer size from default 1MB | ||
const audit = exec(`${auditCommand} --json` , { maxBuffer: MAX_BUFFER_SIZE }); | ||
const audit = exec(`${auditCommand} --json`, { maxBuffer: MAX_BUFFER_SIZE }); | ||
// Grab the data in chunks and buffer it as we're unable to | ||
// parse JSON straight from stdout | ||
let jsonBuffer = ""; | ||
audit.stdout.on("data", (data) => (jsonBuffer += data)); | ||
// Grab the data in chunks and buffer it as we're unable to parse JSON straight from stdout | ||
let jsonBuffer = ''; | ||
audit.stdout.on('data', data => (jsonBuffer += data)); | ||
// Once the stdout has completed process the output | ||
audit.stderr.on("close", (code) => { | ||
audit.stderr.on('close', () => { | ||
const { advisories } = JSON.parse(jsonBuffer); | ||
@@ -108,19 +110,13 @@ | ||
const vulnerabilities = Object.values(advisories) | ||
.filter((advisory) => mapLevelToNumber(advisory.severity) >= auditLevel) | ||
.map((advisory) => advisory.id) | ||
.filter((id) => userExceptionIds.indexOf(id) === -1); | ||
.filter(advisory => mapLevelToNumber(advisory.severity) >= auditLevel) | ||
.map(advisory => advisory.id) | ||
.filter(id => userExceptionIds.indexOf(id) === -1); | ||
// Display an error if we found vulnerabilities | ||
if (vulnerabilities.length > 0) { | ||
const message = `${vulnerabilities.length} vulnerabilities found. Node security advisories: ${vulnerabilities}`; | ||
throw new Error(message); | ||
} else { | ||
// Let's display the audit log instead | ||
auditLog(auditCommand, fullLog); | ||
} | ||
// Display the original audit logs | ||
auditLog(auditCommand, fullLog, vulnerabilities); | ||
}); | ||
// stderr | ||
audit.stderr.on("data", (data) => { | ||
console.info(data); | ||
audit.stderr.on('data', data => { | ||
console.error(data); | ||
}); | ||
@@ -131,18 +127,15 @@ } | ||
program.version("1.1.0"); | ||
program.version(packageJson.version); | ||
program | ||
.command("audit") | ||
.description("execute npm audit") | ||
.option("-i, --ignore <ids>", "Vulnerabilities ID(s) to ignore") | ||
.option( | ||
"-f, --full", | ||
`Display the full audit logs. Default to ${DEFAULT_MESSSAGE_LIMIT} characters.` | ||
) | ||
.option("-l, --level <auditLevel>", "The minimum audit level to include") | ||
.option("-p, --production", "Skip checking devDependencies") | ||
.action(function(options) { | ||
.command('audit') | ||
.description('execute npm audit') | ||
.option('-i, --ignore <ids>', 'Vulnerabilities ID(s) to ignore') | ||
.option('-f, --full', `Display the full audit logs. Default to ${DEFAULT_MESSSAGE_LIMIT} characters.`) | ||
.option('-l, --level <auditLevel>', 'The minimum audit level to include') | ||
.option('-p, --production', 'Skip checking devDependencies') | ||
.action(function (options) { | ||
if (options && options.ignore) { | ||
userExceptionIds = options.ignore.split(SEPARATOR).map(Number); | ||
console.info("Exception vulnerabilities ID(s): ", userExceptionIds); | ||
console.info('Exception vulnerabilities ID(s): ', userExceptionIds); | ||
} | ||
@@ -159,3 +152,3 @@ | ||
if (options && options.production) { | ||
auditCommand += " --production"; | ||
auditCommand += ' --production'; | ||
} | ||
@@ -162,0 +155,0 @@ |
{ | ||
"name": "better-npm-audit", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"author": "Jee Mok <jee.ict@hotmail.com>", | ||
@@ -29,2 +29,5 @@ "description": "Made to allow skipping certain vulnerabilities, and any extra handling that are not supported by the default npm audit in the future.", | ||
"main": "index.js", | ||
"bin": { | ||
"better-npm-audit": "./index.js" | ||
}, | ||
"dependencies": { | ||
@@ -31,0 +34,0 @@ "commander": "^2.19.0" |
@@ -12,7 +12,12 @@ # Better NPM Audit | ||
$ npm install better-npm-audit --save | ||
$ npm install better-npm-audit | ||
or | ||
## Package.json | ||
$ npm install -g better-npm-audit | ||
## Useage | ||
### Package.json | ||
```JSON | ||
@@ -27,2 +32,7 @@ { | ||
### Run Global | ||
`better-npm-audit audit` | ||
## Flags | ||
@@ -29,0 +39,0 @@ |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
6
20%171
6.21%12172
-0.78%129
-4.44%