better-npm-audit
Advanced tools
Comparing version 1.11.2 to 1.12.0
@@ -0,4 +1,8 @@ | ||
## 1.12.0 (June 18, 2021) | ||
* [Display warning when exceptionIds are unused](https://github.com/jeemok/better-npm-audit/pull/38) | ||
## 1.11.2 (June 11, 2021) | ||
* Fixed security CVE-2020-28469: Bump glob-parent from 5.1.1 to 5.1.2 | ||
* [Fixed security CVE-2020-28469: Bump glob-parent from 5.1.1 to 5.1.2](https://github.com/jeemok/better-npm-audit/pull/37) | ||
@@ -11,3 +15,3 @@ ## 1.11.1 (June 11, 2021) | ||
* Added environment variable support `process.env.NPM_CONFIG_AUDIT_LEVEL` to set the audit level | ||
* [Added environment variable support `process.env.NPM_CONFIG_AUDIT_LEVEL` to set the audit level](https://github.com/jeemok/better-npm-audit/pull/36) | ||
@@ -14,0 +18,0 @@ ## 1.10.1 (June 7, 2021) |
42
index.js
@@ -11,3 +11,3 @@ #!/usr/bin/env node | ||
const packageJson = require('./package'); | ||
const { isWholeNumber, mapLevelToNumber, getVulnerabilities, filterValidException } = require('./utils/common'); | ||
const { isWholeNumber, mapLevelToNumber, getRawVulnerabilities, filterValidException, filterExceptions } = require('./utils/common'); | ||
const { readFile } = require('./utils/file'); | ||
@@ -28,7 +28,8 @@ const consoleUtil = require('./utils/console'); | ||
* Handle the analyzed result and log display | ||
* @param {Array} vulnerabilities List of found vulerabilities | ||
* @param {Array} vulnerabilities List of found vulnerabilities | ||
* @param {String} logData Logs | ||
* @param {Object} configs Configurations | ||
* @param {Array} unusedExceptionIds List of unused exceptionsIds. | ||
*/ | ||
function handleFinish(vulnerabilities, logData = '', configs = {}) { | ||
function handleFinish(vulnerabilities, logData = '', configs = {}, unusedExceptionIds = []) { | ||
const { | ||
@@ -56,5 +57,12 @@ displayFullLog = false, | ||
if (unusedExceptionIds.length > 0) { | ||
// eslint-disable-next-line max-len | ||
const message = `${unusedExceptionIds.length} vulnerabilities where ignored but did not result in a vulnerabilities: ${unusedExceptionIds}. They can be removed from the .nsprc file or -ignore -i flags.`; | ||
consoleUtil.info(message); | ||
} | ||
// Display the error if found vulnerabilities | ||
if (vulnerabilities.length > 0) { | ||
consoleUtil.error(`${vulnerabilities.length} vulnerabilities found. Node security advisories: ${vulnerabilities}`); | ||
// Exit failed | ||
@@ -71,6 +79,7 @@ process.exit(1); | ||
* @param {String} auditCommand The NPM audit command to use (with flags) | ||
* @param {Boolean} displayFullLog True if full log should be displayed in the case of no vulerabilities | ||
* @param {Array} vulnerabilities List of vulerabilities | ||
* @param {Boolean} displayFullLog True if full log should be displayed in the case of no vulnerabilities | ||
* @param {Array} vulnerabilities List of vulnerabilities | ||
* @param {Array} unusedExceptionIds List of unused exceptionsIds. | ||
*/ | ||
function auditLog(auditCommand, displayFullLog, vulnerabilities) { | ||
function auditLog(auditCommand, displayFullLog, vulnerabilities, unusedExceptionIds) { | ||
// Execute `npm audit` command again, but this time we don't use the JSON flag | ||
@@ -86,3 +95,3 @@ const audit = exec(auditCommand); | ||
// Once the stdout has completed | ||
audit.stderr.on('close', () => handleFinish(vulnerabilities, bufferData, { displayFullLog })); | ||
audit.stderr.on('close', () => handleFinish(vulnerabilities, bufferData, { displayFullLog }, unusedExceptionIds)); | ||
@@ -96,5 +105,5 @@ // stderr | ||
* @param {String} auditCommand The NPM audit command to use (with flags) | ||
* @param {Number} auditLevel The level of vulernabilities we care about | ||
* @param {Boolean} fullLog True if the full log should be displayed in the case of no vulerabilities | ||
* @param {Array} exceptionIds List of vulernability IDs to ignore | ||
* @param {Number} auditLevel The level of vulnerabilities we care about | ||
* @param {Boolean} fullLog True if the full log should be displayed in the case of no vulnerabilities | ||
* @param {Array} exceptionIds List of vulnerability IDs to ignore | ||
*/ | ||
@@ -114,7 +123,14 @@ function audit(auditCommand, auditLevel, fullLog, exceptionIds) { | ||
audit.stderr.on('close', () => { | ||
// Grab any un-filtered vunerablities at the appropriate level | ||
const vulnerabilities = getVulnerabilities(jsonBuffer, auditLevel, exceptionIds); | ||
// Grab any un-filtered vulnerabilities at the appropriate level | ||
const rawVulnerabilities = getRawVulnerabilities(jsonBuffer, auditLevel); | ||
// filter out exceptions | ||
const vulnerabilities = filterExceptions(rawVulnerabilities, exceptionIds); | ||
// Display the unused exceptionId's | ||
const exceptionsIdsAsArray = Array.isArray(exceptionIds) ? exceptionIds : [exceptionIds]; | ||
const unusedExceptionIds = exceptionsIdsAsArray.filter(id => !rawVulnerabilities.includes(id)); | ||
// Display the original audit logs | ||
auditLog(auditCommand, fullLog, vulnerabilities); | ||
auditLog(auditCommand, fullLog, vulnerabilities, unusedExceptionIds); | ||
}); | ||
@@ -121,0 +137,0 @@ |
{ | ||
"name": "better-npm-audit", | ||
"version": "1.11.2", | ||
"version": "1.12.0", | ||
"author": "Jee Mok <jee.ict@hotmail.com>", | ||
@@ -5,0 +5,0 @@ "description": "Made to allow skipping certain vulnerabilities, and any extra handling that are not supported by the default npm audit in the future.", |
@@ -231,2 +231,8 @@ # Better NPM Audit | ||
## Changelog | ||
You can find the changelog [here](https://github.com/jeemok/better-npm-audit/blob/master/CHANGELOG.md). | ||
<br /> | ||
## Special mentions | ||
@@ -238,2 +244,4 @@ | ||
- [@MrHus](https://github.com/MrHus) for the logging of unused exceptions from the .nsprc file and -ignore flags. Courtesy of 42 BV. | ||
<br /> | ||
@@ -240,0 +248,0 @@ |
@@ -10,3 +10,3 @@ const sinon = require('sinon'); | ||
const consoleUtil = require('../utils/console'); | ||
const { isWholeNumber, mapLevelToNumber, getVulnerabilities, isJsonString, filterValidException } = require('../utils/common'); | ||
const { isWholeNumber, mapLevelToNumber, getRawVulnerabilities, isJsonString, filterValidException, filterExceptions } = require('../utils/common'); | ||
const { handleFinish, handleUserInput, BASE_COMMAND, SUCCESS_MESSAGE, LOGS_EXCEEDED_MESSAGE } = require('../index'); | ||
@@ -143,2 +143,9 @@ | ||
}); | ||
it('should know how to filter raw vulnerabilities based on the exceptionIds', () => { | ||
const exceptions = [1213, 1500, 1555, 9999]; | ||
const result = filterExceptions([975, 1213, 976, 985, 1500, 1084, 1179, 1523, 1555, 1556, 1589, 9999], exceptions); | ||
expect(result).to.have.length(8).and.to.deep.equal([975, 976, 985, 1084, 1179, 1523, 1556, 1589]); | ||
}); | ||
}); | ||
@@ -359,2 +366,31 @@ | ||
it('should inform the developer when exceptionsIds are unused', () => { | ||
const stubProcess = sinon.stub(process, 'exit'); | ||
const stubErrorConsole = sinon.stub(consoleUtil, 'error'); | ||
const stubInfoConsole = sinon.stub(consoleUtil, 'info'); | ||
const vulnerabilities = [1165, 1890, 1337]; | ||
const exceptionIds = [2000, 4242]; | ||
expect(stubProcess.called).to.equal(false); | ||
expect(stubErrorConsole.called).to.equal(false); | ||
expect(stubInfoConsole.called).to.equal(false); | ||
handleFinish(vulnerabilities, '', {}, exceptionIds); | ||
expect(stubProcess.called).to.equal(true); | ||
expect(stubProcess.calledWith(1)).to.equal(true); | ||
expect(stubErrorConsole.called).to.equal(true); | ||
expect(stubErrorConsole.calledWith('3 vulnerabilities found. Node security advisories: 1165,1890,1337')).to.equal(true); | ||
expect(stubInfoConsole.called).to.equal(true); | ||
// eslint-disable-next-line max-len | ||
const message = `2 vulnerabilities where ignored but did not result in a vulnerabilities: 2000,4242. They can be removed from the .nsprc file or -ignore -i flags.`; | ||
expect(stubInfoConsole.calledWith(message)).to.equal(true); | ||
stubProcess.restore(); | ||
stubErrorConsole.restore(); | ||
stubInfoConsole.restore(); | ||
}); | ||
it('should be able to handle normal log display correctly', () => { | ||
@@ -428,3 +464,3 @@ const stub = sinon.stub(console, 'info'); | ||
const auditLevel = 0; // info | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -437,3 +473,3 @@ expect(result).to.have.length(0).and.to.deep.equal([]); | ||
const auditLevel = 0; // info | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -446,3 +482,3 @@ expect(result).to.have.length(11).and.to.deep.equal([975, 976, 985, 1084, 1179, 1213, 1500, 1523, 1555, 1556, 1589]); | ||
const auditLevel = 1; // low | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -455,3 +491,3 @@ expect(result).to.have.length(11).and.to.deep.equal([975, 976, 985, 1084, 1179, 1213, 1500, 1523, 1555, 1556, 1589]); | ||
const auditLevel = 2; // moderate | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -464,3 +500,3 @@ expect(result).to.have.length(5).and.to.deep.equal([975, 976, 985, 1213, 1555]); | ||
const auditLevel = 3; // high | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -473,3 +509,3 @@ expect(result).to.have.length(2).and.to.deep.equal([1213, 1555]); | ||
const auditLevel = 4; // critical | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -479,22 +515,2 @@ expect(result).to.have.length(1).and.to.deep.equal([1555]); | ||
}); | ||
describe('using exceptions', () => { | ||
it('should be able to filter out all vulnerabilities correctly', () => { | ||
const jsonString = JSON.stringify(V6_JSON_BUFFER); | ||
const auditLevel = 4; // critical | ||
const exceptions = [1213, 1500, 1555]; | ||
const result = getVulnerabilities(jsonString, auditLevel, exceptions); | ||
expect(result).to.have.length(0).and.to.deep.equal([]); | ||
}); | ||
it('should be able to filter out targeted vulnerabilities correctly', () => { | ||
const jsonString = JSON.stringify(V6_JSON_BUFFER); | ||
const auditLevel = 0; // info | ||
const exceptions = [1213, 1500, 1555, 9999]; | ||
const result = getVulnerabilities(jsonString, auditLevel, exceptions); | ||
expect(result).to.have.length(8).and.to.deep.equal([975, 976, 985, 1084, 1179, 1523, 1556, 1589]); | ||
}); | ||
}); | ||
}); | ||
@@ -507,3 +523,3 @@ | ||
const auditLevel = 0; // info | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -516,3 +532,3 @@ expect(result).to.have.length(0).and.to.deep.equal([]); | ||
const auditLevel = 0; // info | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -525,3 +541,3 @@ expect(result).to.have.length(11).and.to.deep.equal([1555, 1213, 1589, 1523, 1084, 1179, 1556, 975, 976, 985, 1500]); | ||
const auditLevel = 1; // low | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -534,3 +550,3 @@ expect(result).to.have.length(10).and.to.deep.equal([1555, 1213, 1589, 1523, 1084, 1179, 1556, 975, 976, 985]); | ||
const auditLevel = 2; // moderate | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -543,3 +559,3 @@ expect(result).to.have.length(5).and.to.deep.equal([1555, 1213, 975, 976, 985]); | ||
const auditLevel = 3; // high | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -552,3 +568,3 @@ expect(result).to.have.length(2).and.to.deep.equal([1555, 1213]); | ||
const auditLevel = 4; // critical | ||
const result = getVulnerabilities(jsonString, auditLevel); | ||
const result = getRawVulnerabilities(jsonString, auditLevel); | ||
@@ -558,22 +574,2 @@ expect(result).to.have.length(1).and.to.deep.equal([1555]); | ||
}); | ||
describe('using exceptions', () => { | ||
it('should be able to filter out all vulnerabilities correctly', () => { | ||
const jsonString = JSON.stringify(V7_JSON_BUFFER); | ||
const auditLevel = 4; // critical | ||
const exceptions = [1555, 1213]; | ||
const result = getVulnerabilities(jsonString, auditLevel, exceptions); | ||
expect(result).to.have.length(0).and.to.deep.equal([]); | ||
}); | ||
it('should be able to filter out targeted vulnerabilities correctly', () => { | ||
const jsonString = JSON.stringify(V7_JSON_BUFFER); | ||
const auditLevel = 0; // info | ||
const exceptions = [1213, 1500, 1555, 9999]; | ||
const result = getVulnerabilities(jsonString, auditLevel, exceptions); | ||
expect(result).to.have.length(8).and.to.deep.equal([1589, 1523, 1084, 1179, 1556, 975, 976, 985]); | ||
}); | ||
}); | ||
}); |
@@ -32,3 +32,3 @@ const get = require('lodash.get'); | ||
*/ | ||
function getVulnerabilities(jsonBuffer = '', auditLevel = 0, exceptionIds = []) { | ||
function getRawVulnerabilities(jsonBuffer = '', auditLevel = 0) { | ||
// NPM v6 uses `advisories` | ||
@@ -43,4 +43,3 @@ // NPM v7 uses `vulnerabilities` | ||
.filter(advisory => mapLevelToNumber(advisory.severity) >= auditLevel) // Filter out if there is requested audit level | ||
.map(advisory => advisory.id) // Map out the vulnerabilities IDs | ||
.filter(id => !exceptionIds.includes(id)); // Filter out exceptions provided by user | ||
.map(advisory => advisory.id); // Map out the vulnerabilities IDs | ||
} | ||
@@ -58,4 +57,3 @@ | ||
return acc.concat(cleanedArray); | ||
}, []) | ||
.filter(id => !exceptionIds.includes(id)); // Filter out exceptions provided by user | ||
}, []); | ||
} | ||
@@ -67,2 +65,12 @@ | ||
/** | ||
* Takes the rawVulnerabilities and filters out the exceptionIds | ||
* @param {Array} rawVulnerabilities List of raw vulnerabilities to filter | ||
* @param {Array} exceptionIds List of exception vulnerabilities | ||
* @return {Array} Returns the list of found vulnerabilities | ||
*/ | ||
function filterExceptions(rawVulnerabilities, exceptionIds = []) { | ||
return rawVulnerabilities.filter(id => !exceptionIds.includes(id)); | ||
} | ||
/** | ||
* Filter the given list in the `.nsprc` file for valid exceptions | ||
@@ -133,3 +141,4 @@ * @param {Object} fileException The exception object | ||
mapLevelToNumber, | ||
getVulnerabilities, | ||
getRawVulnerabilities, | ||
filterExceptions, | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
246982
3164
252