Skip to main content

Module audit

Module audit 

Source
Expand description

Vulnerability auditing for a parsed package-lock.jsonnpm audit, pure Rust.

The packages a lockfile pins (crate::sbom::components) are checked against one or more advisory sources behind a small AdvisorySource trait, and the hits are distilled into an AuditReport: which installed components are vulnerable, to which advisories, at what severity.

Two sources ship in v1, both keyless and queried by default:

  • npm::NpmRegistrySource — npm’s native bulk-advisory endpoint (also honours a custom mirror).
  • osv::OsvSource — the OSV (osv.dev) database, with structured affected-version ranges.

The seam is deliberately open: a new source is one impl AdvisorySource plus one line where the active sources are assembled (e.g. a future, feature-gated, API-key’d Snyk source).

Everything except the sources’ network calls is pure and unit-tested: dedup_advisories collapses the same vulnerability reported by several sources, and build_report keeps only the advisories whose vulnerable range actually contains the installed version — the guard against the npm endpoint’s range over-broadening — then groups and counts them.

use npm_utils::{audit, package_json::lock::Lockfile, sbom};
let lock = Lockfile::parse(&std::fs::read_to_string("package-lock.json")?)?;
let components = sbom::components(&lock);
let sources: Vec<Box<dyn audit::AdvisorySource>> =
    vec![Box::new(audit::npm::NpmRegistrySource::new("https://registry.npmjs.org"))];
let report = audit::run_audit(&components, &sources);
print!("{}", audit::render_summary(&report));

Modules§

npm
npm’s native bulk-advisory source.
osv
The OSV (osv.dev) advisory source.

Structs§

Advisory
One vulnerability advisory, normalized across sources into a single shape.
AuditReport
The result of an audit: the vulnerable components (sorted by name then version), the per-severity totals across them, the names of any advisory sources that could not be reached, and the dependencies the component loading could not audit — so a caller can tell an incomplete run from a genuinely clean one.
ComponentAdvisories
One vulnerable installed component and the advisories that hit its exact version.
Vulnerabilities
Per-severity advisory counts — the shape of npm’s metadata.vulnerabilities.

Enums§

Severity
A normalized advisory severity. Ordered Low < Moderate < High < Critical so a --audit-level threshold is a simple comparison. npm’s vocabulary (moderate, not medium).

Traits§

AdvisorySource
An advisory database that can be queried for the vulnerabilities affecting a set of components.

Functions§

build_report
Match deduped advisories against the installed components and group the hits into an AuditReport.
dedup_advisories
Collapse advisories that describe the same vulnerability for the same package across sources, joined by any shared GHSA-/CVE- token. The first occurrence wins (sources are concatenated in selection order, npm before osv), and a later duplicate’s aliases / url / cwe / cvss / severity enrich the survivor where it lacks them — so an OSV record’s CVE alias decorates the npm GHSA.
render_json
An npm audit --json-shaped report: a vulnerabilities object keyed by package name (each with its affected installed versions, the max severity, and the advisories under via) plus a metadata.vulnerabilities per-severity count block.
render_summary
A plain-text audit summary: a one-line count header, then each vulnerable name@version with its advisories. found 0 vulnerabilities when clean (mirrors npm audit). Unaudited dependencies are itemized in a note: line above the header and flag the audit INCOMPLETE.
run_audit
Query every source, then dedup across sources and keep only advisories that actually apply to an installed version (build_report). A source that fails is reported to stderr, recorded in the report’s failed_sources, and skipped — a single failing source never sinks the run, but the report is marked incomplete so the caller need not present it as clean. This is run_audit_observed (the crate-internal eventful variant) with a no-op observer.
severity_from_cvss
Map a CVSS base score to a severity bucket (the CVSS v3 qualitative ranges): <= 0 is None, < 4 Low, < 7 Moderate, < 9 High, else Critical. Used when a source gives a numeric score but no severity word.