New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

better-npm-audit

Package Overview
Dependencies
Maintainers
1
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

better-npm-audit - npm Package Compare versions

Comparing version 1.1.1 to 1.2.0

.github/workflows/npm-publish.yml

189

index.js

@@ -7,14 +7,31 @@ #!/usr/bin/env node

const program = require('commander');
const { exec } = require('child_process');
const program = require("commander");
const { exec } = require("child_process");
const AUDIT_COMMAND = 'npm audit';
const SEPARATOR = ',';
const BASE_COMMAND = "npm audit";
const SEPARATOR = ",";
const SPLIT_REGEX = /(https:\/\/(nodesecurity.io|npmjs.com)\/advisories\/)/;
const DIGIT_REGEX = /^\d+$/;
const DEFAULT_MESSSAGE_LIMIT = 100000; // characters
const MAX_BUFFER_SIZE = 1024 * 1000 * 50; // 50 MB
function isNumber(string) {
return DIGIT_REGEX.test(string);
}
/**
* Converts an audit level to a numeric value for filtering purposes
* @param {String} auditLevel The npm audit level
* @return {Number} The numeric value, higher is more severe
*/
const mapLevelToNumber = (auditLevel) => {
switch (auditLevel) {
case "low":
return 1;
case "moderate":
return 2;
case "high":
return 3;
case "critical":
return 4;
default:
return 0;
}
};

@@ -25,68 +42,118 @@ function unique(value, index, self) {

/**
* Re-runs the audit in human readable form
* @param {String} auditCommand The NPM audit command to use (with flags)
* @param {Boolean} fullLog True if the full log should be displayed in the case of no vulerabilities
*/
function auditLog(auditCommand, fullLog) {
// Execute `npm audit` command again, but this time we don't use the JSON flag
const audit = exec(auditCommand);
audit.stdout.on("data", (data) => {
if (fullLog) {
console.info(data);
} else {
const toDisplay = data.substring(0, DEFAULT_MESSSAGE_LIMIT);
console.info(toDisplay);
// Display additional info if it is not the full message
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("");
}
}
// Happy happy, joy joy
console.info("🤝 All good!");
});
// stderr
audit.stderr.on("data", (data) => {
console.info(data);
});
}
/**
* Run the main Audit
* @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
*/
function audit(auditCommand, auditLevel, fullLog) {
// Execute `npm audit` command to get the security report, taking into account
// any additional flags that have been passed through. Using the JSON flag
// to make this easier to process
// NOTE: Increase max buffer size from default 1MB
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));
// Once the stdout has completed process the output
audit.stderr.on("close", (code) => {
const { advisories } = JSON.parse(jsonBuffer);
// Grab any un-filtered vunerablities at the appropriate level
const vulnerabilities = Object.values(advisories)
.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);
}
});
// stderr
audit.stderr.on("data", (data) => {
console.info(data);
});
}
let userExceptionIds = [];
program
.version('1.1.0')
program.version("1.1.0");
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.`)
.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);
console.info('Exception vulnerabilities ID(s): ', userExceptionIds);
userExceptionIds = options.ignore.split(SEPARATOR).map(Number);
console.info("Exception vulnerabilities ID(s): ", userExceptionIds);
}
// Execute `npm audit` command to get the security report
const audit = exec(AUDIT_COMMAND);
// Grab the audit level passed in, or all by default
let auditLevel = 0;
if (options && options.level) {
auditLevel = mapLevelToNumber(options.level);
}
// stdout
audit.stdout.on('data', data => {
// Split the security report string by the URL at the end, and get the first 4 characters;
// This might contains of other words than the IDs,
// eg: ['===', 'http', 'node', '534', 'http', 'node', '118', 'http', 'node', '146', 'http', 'node', '975', 'http', 'node', '976']
const rawIds = data.split(SPLIT_REGEX).map(str => str.substring(0, 4).trim());
// Remove everything except for numbers from the array
const numberIds = rawIds.filter(str => isNumber(str));
// Remove duplicates
const uniqueIds = numberIds.filter(unique);
// Check if there is any more exceptions other than the user selected to ignore
const vulnerabilities = uniqueIds.filter(id => (userExceptionIds.indexOf(id) === -1));
// Throw error if we found more exceptions
if (vulnerabilities.length > 0) {
const message = `${vulnerabilities.length} vulnerabilities found. Node security advisories: ${vulnerabilities}`;
throw new Error(message);
}
else {
// If the display-all flag is passed in, display full audit logs
if (options.full) {
console.info(data);
}
// Otherwise, trim audit logs within the maximum characters limit
else {
const toDisplay = data.substring(0, DEFAULT_MESSSAGE_LIMIT);
// Display into console
console.info(toDisplay);
// Display additional info if it is not the full message
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('');
}
}
// Happy happy, joy joy
console.info('🤝 All good!');
}
});
// Modify the audit command to only include production
let auditCommand = BASE_COMMAND;
if (options && options.production) {
auditCommand += " --production";
}
// stderr
audit.stderr.on('data', data => {
console.info(data);
});
audit(auditCommand, auditLevel, options.full);
});
program.parse(process.argv);
{
"name": "better-npm-audit",
"version": "1.1.1",
"version": "1.2.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.",

@@ -28,2 +28,3 @@ # Better NPM Audit

#### Ignore certain vulnerabilities
For skipping certain advisories, you can use `-i` or verbose `--ignore` flags

@@ -35,3 +36,4 @@

To avoid waterfall logging on your console, there is a character limit set to the output. To view the full audit logs, you can use `-f` or verbose `--full` flags
#### Display full report
To avoid waterfall logging on your console screen, there is a character limit set to the output. To view the full audit logs, you can use `-f` or verbose `--full` flags

@@ -42,2 +44,14 @@ ```

#### Minimum audit level (`--audit-level`)
Fail an audit only if the results include a vulnerability with a level of moderate or higher:
```
node node_modules/better-npm-audit audit -l critical
```
#### Production mode (`--production`)
Skip checking `devDependencies`
```
node node_modules/better-npm-audit audit -p
```
## Examples

@@ -147,1 +161,4 @@

```
## Special thanks
Thank you [@IPWright83](https://github.com/IPWright83) for his solutions in improving the vulnerability validation for us to have the minimum-audit-level and production-mode flags.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc