Skip to content

Commit

Permalink
Merge pull request #77 from jeemok/beta
Browse files Browse the repository at this point in the history
Add support for non-numeric exception IDs
  • Loading branch information
jeemok authored Mar 19, 2022
2 parents dfe04e0 + c17012f commit d33c8a2
Show file tree
Hide file tree
Showing 17 changed files with 913 additions and 201 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 3.7.1 (March 19, 2022)
- [43380eb](https://github.com/jeemok/better-npm-audit/commit/43380eb54f6699ae121617603f8e3aaba1494321) Fixed unused exceptions handler

## 3.7.0 (March 10, 2022)
- [1871068](https://github.com/jeemok/better-npm-audit/commit/1871068fa3433b5fb4b93590540ccafc59dbfb38) Handles non numeric exception IDs

## 3.6.0 (February 23, 2022)

- [#71](https://github.com/jeemok/better-npm-audit/pull/71) Added new option: ignore by module name
Expand Down
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ The goal of this project is to help to reshape npm audit into the way the commun

![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square) ![npm vulnerability](https://img.shields.io/snyk/vulnerabilities/npm/better-npm-audit?style=flat-square) ![GitHub issues](https://img.shields.io/github/issues/jeemok/better-npm-audit?style=flat-square) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/better-npm-audit?style=flat-square) ![Languages](https://img.shields.io/github/languages/top/jeemok/better-npm-audit?style=flat-square)

## Supports both NPM version 6 and 7
## NPM version 6 and 7, and 8

NPM has upgraded to version 7 in late 2020 and has breaking changes on the `npm audit`. The output of npm audit has significantly changed both in the human-readable and `--json` output styles. We have added handling so it works properly in both npm versions.
NPM has upgraded to version 7 in late 2020 and has breaking changes on the `npm audit`. The output of npm audit has significantly changed both in the human-readable and `--json` output styles. Even more unfortunately, when NPM changed the JSON output in npm v7, they removed many of the other useful identifiers (`cves`, `cwe`, `github_advisory_id`) and the only thing left is the URL. We are trying our best to handle each version and provide consistent functionality to all of them. Related docs on v6 and v7 changes:

| Docs | Link |
| -------------------------- | ------------------------------------------------------------------------------------------ |
Expand Down Expand Up @@ -71,13 +71,13 @@ npm run audit

## Options

| Flag | Short | Description |
| -------------- | ----- | ------------------------------------------------------------------------------ |
| `--exclude` | `-x` | Exceptions or the vulnerabilities ID(s) to exclude
| `--module-ignore` | `-m` | Names of modules to exclude |
| `--level` | `-l` | The minimum audit level to validate; Same as the original `--audit-level` flag |
| `--production` | `-p` | Skip checking the `devDependencies` |
| `--registry` | `-r` | The npm registry url to use |
| Flag | Short | Description |
| ----------------- | ----- | ----------------------------------------------------------------------------------------------------- |
| `--exclude` | `-x` | Exceptions or the vulnerabilities ID(s) to exclude; the ID can be the numeric ID, CVE, CWE or GHSA ID |
| `--module-ignore` | `-m` | Names of modules to exclude |
| `--level` | `-l` | The minimum audit level to validate; Same as the original `--audit-level` flag |
| `--production` | `-p` | Skip checking the `devDependencies` |
| `--registry` | `-r` | The npm registry url to use |

<br />

Expand All @@ -104,8 +104,9 @@ You may add a file `.nsprc` to your project root directory to manage the excepti
"active": false,
"notes": "Ignored since we don't use xxx method"
},
"980": "Ignored since we don't use xxx method",
"Note": "Any non number key will not be accepted"
"CWE-471": "CWE ID is acceptable",
"GHSA-ww39-953v-wcq6": "GHSA ID is acceptable",
"https://npmjs.com/advisories/1213": "Full or partial URL is acceptable too"
}
```

Expand Down Expand Up @@ -133,13 +134,10 @@ You can find the changelog [here](https://github.com/jeemok/better-npm-audit/blo

<br />

## Special mentions
## Contributors

- [@IanWright](https://github.com/IPWright83) for his solutions in improving the vulnerability validation for us to have the minimum-audit-level and production-mode flags.
[Ian Wright](https://github.com/IPWright83), [Edwin Taylor](https://github.com/alertme-edwin), [Maarten Hus](https://github.com/MrHus), [Alex Burkowsky](https://github.com/alexburkowskypolysign), [David M. Lee](https://github.com/leedm777), [Kyle Clark](https://github.com/kyle-clark1824), [Guillermo Pincay](https://github.com/guillermaster), [Grzegorz Pawłowski](https://github.com/GrzesiekP), [CSLTech](https://github.com/CSLTech), [Paul Clarkin](https://github.com/paulclarkin), [mgdodge](https://github.com/mgdodge), [Ricky Sullivan](https://github.com/rickysullivan), [Sam Gregory](https://github.com/samgregory88), [Tristan WAGNER](https://github.com/tristanwagner)

- [@EdwinTaylor](https://github.com/alertme-edwin) for all the bug reports and improvement suggestions.

- [@MrHus](https://github.com/MrHus) for the logging of unused exceptions from the .nsprc file and -ignore flags. Courtesy of 42 BV.

<br />

Expand Down
2 changes: 1 addition & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const program = new Command();
* @param {Array} exceptionIds List of vulnerability IDs to exclude
* @param {Array} modulesToIgnore List of vulnerable modules to ignore in audit results
*/
export function callback(auditCommand: string, auditLevel: AuditLevel, exceptionIds: number[], modulesToIgnore: string[]): void {
export function callback(auditCommand: string, auditLevel: AuditLevel, exceptionIds: string[], modulesToIgnore: string[]): void {
// Increase the default max buffer size (1 MB)
const audit = exec(`${auditCommand} --json`, { maxBuffer: MAX_BUFFER_SIZE });

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "better-npm-audit",
"version": "3.6.0",
"version": "3.7.0",
"author": "Jee Mok <jee.ict@hotmail.com>",
"description": "Reshape into a better npm audit for the community and encourage more people to include security audit into their process.",
"license": "MIT",
Expand All @@ -17,7 +17,7 @@
},
"scripts": {
"preaudit": "npm run build",
"audit": "node lib audit -x 1004946,1006897",
"audit": "node lib audit -x 1064843,1067245",
"test": "mocha -r ts-node/register test/**/*.test.ts",
"lint": "eslint .",
"qc": "npm run test && npm run lint",
Expand Down
41 changes: 10 additions & 31 deletions src/handlers/handleFinish.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { AuditLevel } from 'src/types';
import { printSecurityReport } from '../utils/print';
import { processAuditJson } from '../utils/vulnerability';
import { processAuditJson, handleUnusedExceptions } from '../utils/vulnerability';

/**
* Process and analyze the NPM audit JSON
* @param {String} jsonBuffer NPM audit stringified JSON payload
* @param {Number} auditLevel The level of vulnerabilities we care about
* @param {Array} exceptionIds List of vulnerability IDs to exclude
* @param {Array} modulesToIgnore List of vulnerable modules to ignore in audit results
* @return {undefined}
* @param {String} jsonBuffer NPM audit stringified JSON payload
* @param {Number} auditLevel The level of vulnerabilities we care about
* @param {Array} exceptionIds List of vulnerability IDs to exclude
* @param {Array} exceptionModules List of vulnerable modules to ignore in audit results
*/
export default function handleFinish(jsonBuffer: string, auditLevel: AuditLevel, exceptionIds: number[], modulesToIgnore: string[]): void {
const { unhandledIds, vulnerabilityIds, vulnerabilityModules, report, failed } = processAuditJson(
export default function handleFinish(jsonBuffer: string, auditLevel: AuditLevel, exceptionIds: string[], exceptionModules: string[]): void {
const { unhandledIds, report, failed, unusedExceptionIds, unusedExceptionModules } = processAuditJson(
jsonBuffer,
auditLevel,
exceptionIds,
modulesToIgnore,
exceptionModules,
);

// If unable to process the audit JSON
Expand All @@ -31,28 +30,8 @@ export default function handleFinish(jsonBuffer: string, auditLevel: AuditLevel,
printSecurityReport(report);
}

// Grab any un-filtered vulnerabilities at the appropriate level
const unusedExceptionIds = exceptionIds.filter((id) => !vulnerabilityIds.includes(id));
const unusedIgnoredModules = modulesToIgnore.filter((moduleName) => !vulnerabilityModules.includes(moduleName));

const messages = [
`${unusedExceptionIds.length} of the excluded vulnerabilities did not match any of the found vulnerabilities: ${unusedExceptionIds.join(
', ',
)}.`,
`${unusedExceptionIds.length > 1 ? 'They' : 'It'} can be removed from the .nsprc file or --exclude -x flags.`,
];
// Display the unused exceptionId's
if (unusedExceptionIds.length) {
if (unusedIgnoredModules.length) {
messages.push(
`${unusedIgnoredModules.length} of the ignored modules did not match any of the found vulnerabilites: ${unusedIgnoredModules.join(
', ',
)}.`,
`${unusedIgnoredModules.length > 1 ? 'They' : 'It'} can be removed from the --module-ignore -m flags.`,
);
}
console.warn(messages.join(' '));
}
// Handle unused exceptions
handleUnusedExceptions(unusedExceptionIds, unusedExceptionModules);

// Display the found unhandled vulnerabilities
if (unhandledIds.length) {
Expand Down
10 changes: 6 additions & 4 deletions src/handlers/handleInput.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import get from 'lodash.get';
import { AuditLevel, CommandOptions } from 'src/types';
import { isWholeNumber } from '../utils/common';
import { readFile } from '../utils/file';
import { getExceptionsIds } from '../utils/vulnerability';

Expand All @@ -9,7 +8,7 @@ import { getExceptionsIds } from '../utils/vulnerability';
* @param {Object} options User's command options or flags
* @param {Function} fn The function to handle the inputs
*/
export default function handleInput(options: CommandOptions, fn: (T1: string, T2: AuditLevel, T3: number[], T4: string[]) => void): void {
export default function handleInput(options: CommandOptions, fn: (T1: string, T2: AuditLevel, T3: string[], T4: string[]) => void): void {
// Generate NPM Audit command
const auditCommand: string = [
'npm audit',
Expand All @@ -26,8 +25,11 @@ export default function handleInput(options: CommandOptions, fn: (T1: string, T2

// Get the exceptions
const nsprc = readFile('.nsprc');
const cmdExceptions: number[] = get(options, 'exclude', '').split(',').filter(isWholeNumber).map(Number);
const exceptionIds: number[] = getExceptionsIds(nsprc, cmdExceptions);
const cmdExceptions: string[] = get(options, 'exclude', '')
.split(',')
.map((each) => each.trim())
.filter((each) => each !== '');
const exceptionIds: string[] = getExceptionsIds(nsprc, cmdExceptions);
const cmdModuleIgnore: string[] = get(options, 'moduleIgnore', '').split(',');

fn(auditCommand, auditLevel, exceptionIds, cmdModuleIgnore);
Expand Down
14 changes: 9 additions & 5 deletions src/types/general.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export interface v6Advisories {
}

export interface v6Advisory {
readonly id: string;
readonly id: number;
readonly cves: string[];
readonly cwe: string;
// eslint-disable-next-line camelcase
readonly module_name: string;
readonly title: string;
Expand Down Expand Up @@ -51,14 +53,16 @@ export interface v7VulnerabilityVia {
}

export interface ProcessedResult {
readonly unhandledIds: number[];
readonly vulnerabilityIds: number[];
readonly vulnerabilityModules: string[];
readonly unhandledIds: string[];
readonly vulnerabilityIds: string[]; // Currently unused, but very valuable info so leave it here for now
readonly vulnerabilityModules: string[]; // Currently unused, but very valuable info so leave it here for now
readonly report: string[][];
readonly failed?: boolean;
unusedExceptionIds: string[];
unusedExceptionModules: string[];
}

export interface ProcessedReport {
readonly exceptionIds: number[];
readonly exceptionIds: string[];
readonly report: string[][];
}
1 change: 1 addition & 0 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO: This might be unused
/**
* @param {String | Number | Null | Boolean} value The input number
* @return {Boolean} Returns true if the input is a whole number
Expand Down
Loading

0 comments on commit d33c8a2

Please sign in to comment.