Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 38 additions & 25 deletions commands/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ async function report (argv, _dir) {
const isNested = pkgName === nestedPkgName && pkgVersion === nestedPkgVersion

// Processing packages from NCM service
let includedCount = 0;
let skippedCount = 0;

for (const { name, version, scores, published } of data) {
let maxSeverity = 0;
let license = {};
Expand Down Expand Up @@ -170,45 +167,37 @@ async function report (argv, _dir) {
}
}

// Modified approach to include ALL packages in the report
// Even packages with null/undefined versions will be included with a default version
let effectiveVersion = version;
if (effectiveVersion === null || effectiveVersion === undefined) {
effectiveVersion = '0.0.0';
// Using default version 0.0.0 for package
}

// Skip nested packages with severity issues
if (isNested && !!maxSeverity) {
skippedCount++;
// Skipping nested package
continue;
}

// Skip packages the NCM service didn't return data for (null version /
// unpublished). Previously these were coerced to '0.0.0' which polluted
// reports with placeholder entries like `jwt @ 0.0.0`.
if (version === null || version === undefined) continue;

// Skip nested packages (the project reporting on itself) with severity issues
if (isNested && !!maxSeverity) continue;

// Check if license has failed, which should upgrade to critical severity
const getLicenseScore = ({ pass }) => pass === false ? 0 : null;
if (license && license.pass === false) {
maxSeverity = 4;
}

// Add the package to our report
pkgScores.push({
name,
version: effectiveVersion, // Use effective version instead of potentially null version
version,
published,
maxSeverity,
failures,
license,
scores
});

includedCount++;
}

// Package processing complete

pkgScores = moduleSort(pkgScores)

// Build name→version map from NCM data for npm audit v7+ version lookup
const versionByName = new Map([...data]
.filter(pkg => pkg.version)
.map(pkg => [pkg.name, pkg.version]))

// Process whitelisted packages
const whitelisted = pkgScores.filter(pkg => whitelist.has(`${pkg.name}@${pkg.version}`))
.map(pkgScore => ({ ...pkgScore, quantitativeScore: score(pkgScore.scores, pkgScore.maxSeverity) }))
Expand Down Expand Up @@ -251,6 +240,7 @@ async function report (argv, _dir) {
try {
const npmAuditJson = JSON.parse(npmAuditData) || {}
if (npmAuditJson.advisories) {
// npm v6 format
for (const advisory of Object.values(npmAuditJson.advisories)) {
const { version } = advisory.findings ? (advisory.findings[0] || {}) : {}
const { module_name: name, severity = 'NONE' } = advisory
Expand All @@ -266,6 +256,29 @@ async function report (argv, _dir) {
auditScore: maxSeverity
})
}
} else if (npmAuditJson.vulnerabilities) {
// npm v7+ format (auditReportVersion: 2). Packages already reported by
// NCM (in pkgScores or whitelisted) are skipped — otherwise every
// transitive vuln would show up twice.
const reportedIds = new Set(
[...pkgScores, ...whitelisted].map(p => `${p.name}@${p.version}`)
)
for (const [name, vuln] of Object.entries(npmAuditJson.vulnerabilities)) {
const version = versionByName.get(name)
if (reportedIds.has(`${name}@${version}`)) continue
const { severity = 'none' } = vuln
const maxSeverity = SEVERITY_RMAP_NPM.indexOf(severity.toUpperCase())
pkgScores.push({
name,
version,
published: true,
maxSeverity,
failures: [],
license: {},
scores: [],
auditScore: maxSeverity
})
}
}
} catch (err) { } // intentional noop

Expand Down
Loading