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 3.2.0-rc.1 to 3.2.0-rc.2

2

package.json
{
"name": "better-npm-audit",
"version": "3.2.0-rc.1",
"version": "3.2.0-rc.2",
"author": "Jee Mok <jee.ict@hotmail.com>",

@@ -5,0 +5,0 @@ "description": "Reshape npm audit into the way the community would like, by the community itself, to encourage more people to do security audits.",

@@ -131,8 +131,32 @@ # Better NPM Audit

## Auto exclusion from maintainers' notes
## Auto trust security model
Module that has `.nsprc` file will be used in the audit process if `--scan-modules` flag is enabled:
If we trust a package author enough to install their package, then we also trust them to create an `.nsprc` file that covers all the (transitive) dependencies of that package, in the context of that package.
So if we are working on a project `A`, and we install a package `B` as a dependency, then we trust the author of `B` to decide whether `B` is affected by a vulnerability in its dependency `C`. I also trust the author of `B` to make decisions about the author of package `C`, so if `C` contains an `.nsprc` file with an exception about a vulnerability in its dependency, `D`, then we trust that exception because the author of `B` trusts it, and we trust him.
More generally, we can imagine a chain like this:
`A` -> `B` -> `C` -> `D` -> `E` -> `F`
where npm audit reports a vulnerability in `F`, but we are trusting the authors of `B`, `C`, `D`, and `E` to say whether that vulnerability is relevant in the context of their packages.
Extending the example above, then, if we have a tree like this:
```
A -> B -> C -> D -> E -> F
|
-> X -> Y -> Z -> F
```
then the author of package `A` (us), still needs to worry about a vulnerability in `F` due to the way it may be used by `X`, `Y`, and `Z`. Again, though, any of the authors of `X`, `Y`, or `Z` can include an `.nsprc` exception for the vulnerability in `F`, and we will trust their judgement (because we are installing `X`'s package, and he trusts `Y`'s code, etc.)
The auto excepted vulnerabilities will be labeled as "auto" in the report table:
<img src="./.README/auto_exclusion.png" alt="Demo of excluding vulnerabilities flagged by the module maintainers" />
You can turn this feature off by using the flag `--scan-modules=false`
Special shout out to [@EdwinTaylor](https://github.com/alertme-edwin) for his effort in making this possible.
> Note: This feature currently only support npm v7

@@ -139,0 +163,0 @@

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.processExceptions = exports.getExceptionsIds = exports.processAuditJson = exports.mapLevelToNumber = void 0;
exports.processExceptions = exports.getExceptionsIds = exports.processAuditJson = exports.checkTrustInDependencies = exports.mapLevelToNumber = exports.mapModuleDependencies = void 0;
var lodash_get_1 = __importDefault(require("lodash.get"));

@@ -15,2 +15,18 @@ var common_1 = require("./common");

/**
* Map out all the dependencies path for a module
* @param {String} path Full dependency path for the reported module
* @return {Array} Array of dependency paths
*/
function mapModuleDependencies(path) {
return path.split('node_modules/').reduce(function (acc, cur) {
// Ends with '/' meaning it is the dependency and not the final module (reported module)
if (!cur.endsWith('/')) {
return acc;
}
// Append with last dependencies path
return acc.concat((acc[acc.length - 1] || '') + "node_modules/" + cur);
}, []);
}
exports.mapModuleDependencies = mapModuleDependencies;
/**
* Converts an audit level to a numeric value

@@ -38,2 +54,51 @@ * @param {String} auditLevel Audit level

/**
* Check if it is fine to except the reported vulnerability by checking the inner dependencies
* @param {Number} vulnerabilityId Reported vulnerability ID
* @param {Array} affectedModulePaths Reported module path
* @return {Object} Return the details if it can be excepted
*/
function checkTrustInDependencies(vulnerabilityId, affectedModulePaths) {
var scannedPaths = [];
var foundPaths = [];
var report = [];
var trust = affectedModulePaths.every(function (affectedModule) {
// Get all the dependencies that is using this reported module
var dependencyPaths = mapModuleDependencies(affectedModule);
// Audit the scanned paths
scannedPaths.push.apply(scannedPaths, dependencyPaths);
// Trust any of the dependency's decision if they say to ignore it
return dependencyPaths.some(function (path) {
var nsprcPath = path + ".nsprc";
// Try retrieving the `.nsprc` file
var nsprcFile = file_1.readFile(nsprcPath);
// File not found
if (typeof nsprcFile === 'boolean') {
return false;
}
// Audit the found paths
foundPaths.push(nsprcPath);
// Process the file to get valid exceptions
var _a = processExceptions(nsprcFile, []), exceptionIds = _a.exceptionIds, fileReport = _a.report;
var exceptionRow = fileReport.find(function (_a) {
var exceptionId = _a[0];
return Number(exceptionId) === vulnerabilityId;
});
// Append the relevant exception into the maintainer report
if (exceptionRow) {
// Include the used path
report.push(exceptionRow.concat(nsprcPath));
}
// Check if the maintainer have explicitly exclude the vulnerability
return exceptionIds.includes(vulnerabilityId);
});
});
return {
scannedPaths: scannedPaths,
foundPaths: foundPaths,
trust: trust,
report: report,
};
}
exports.checkTrustInDependencies = checkTrustInDependencies;
/**
* Analyze the JSON string buffer

@@ -92,2 +157,3 @@ * @param {String} jsonBuffer NPM Audit JSON string buffer

lodash_get_1.default(cur, 'via', []).forEach(function (vul) {
var _a;
// The vulnerability ID is labeled as `source`

@@ -101,29 +167,18 @@ var id = lodash_get_1.default(vul, 'source', '');

var isExceptedByMaintainers = false;
var foundModuleExceptionFileNum = 0;
var scannedDependenciesPaths = [];
var foundDependenciesPaths = [];
// If scan internal modules flag is enabled,
if (options.scanModules && typeof cur !== 'string') {
// Find all the affected modules
isExceptedByMaintainers = cur.nodes.every(function (path) {
// Try checking if the module itself if the maintainer has a `.nsprc` file
var maintainerNsprc = file_1.readFile(path + "/.nsprc");
// File not found
if (typeof maintainerNsprc === 'boolean') {
return false;
}
// Count the found files
foundModuleExceptionFileNum += 1;
// Process the file to get valid exceptions
var _a = processExceptions(maintainerNsprc, []), maintainerExceptionIds = _a.exceptionIds, maintainerReport = _a.report;
var exceptionRow = maintainerReport.find(function (_a) {
var exceptionId = _a[0];
return Number(exceptionId) === id;
});
// Append the relevant exception into the maintainer report
if (exceptionRow) {
// Include the file path
acc.maintainerReport.push(exceptionRow.concat(path + "/.nsprc"));
}
// Check if the maintainer have explicitly exclude the vulnerability
return maintainerExceptionIds.includes(id);
});
// Check inner dependencies if we can except this vulnerability
var _b = checkTrustInDependencies(id, cur.nodes), scannedPaths = _b.scannedPaths, foundPaths = _b.foundPaths, trust = _b.trust, report = _b.report;
isExceptedByMaintainers = trust;
if (scannedPaths.length) {
scannedDependenciesPaths = scannedPaths;
}
if (foundPaths.length) {
foundDependenciesPaths = foundPaths;
}
if (report.length) {
(_a = acc.maintainerReport).push.apply(_a, report);
}
}

@@ -151,3 +206,3 @@ var isExceptedByUs = exceptionIds.includes(id);

if (options.debug) {
securityReportRow.push(lodash_get_1.default(cur, 'nodes', []).join(', '), foundModuleExceptionFileNum + "/" + lodash_get_1.default(cur, 'nodes', []).length);
securityReportRow.push(scannedDependenciesPaths.join(', '), foundDependenciesPaths.length + "/" + scannedDependenciesPaths.length);
}

@@ -154,0 +209,0 @@ acc.report.push(securityReportRow);

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