All integrations

NPM Audit Integration with DefectDojo

NPM Audit Integration with DefectDojo

npm audit is the dependency security check built into npm, the package manager for Node.js maintained by GitHub. It reads a project's dependency tree from package-lock.json, compares every installed package against the advisories in the npm registry's vulnerability database, and reports affected packages with severities and upgrade paths. Running npm audit --json produces machine-readable output, and DefectDojo imports it through two scan types, one for npm 6 and older reports and one for npm 7 and later.

NPM Audit Integration with DefectDojo

We use NPM Audit with DefectDojo because it is already in every Node.js toolchain we run, and it costs nothing to add to a build. The output on its own is a wall of advisories that resets on every run. Imported into DefectDojo, each advisory becomes a Finding on the right Asset with CVE IDs, CWEs, the vulnerable version range, and the patched version, deduplicated against the last build. When a developer bumps a package, the next reimport closes the Finding, and the history shows how long the exposure lasted.

Why NPM Audit Matters

The average Node.js application pulls in hundreds of transitive packages, most of which nobody on the team picked directly.

  • npm audit ships with npm, so there's nothing to install and no license to buy.
  • It walks the full dependency tree, so vulnerabilities in deeply nested transitive packages are reported along with the path that pulls them in.
  • Advisories include patched version ranges, which turns a finding into a concrete upgrade.
  • On its own, npm audit has no memory. It can't tell you which advisories are new since the last release or which ones the team has already accepted.

Advantages of This Integration

What we gained by sending npm audit results through DefectDojo:

  • Deduplication between builds. For npm 6 reports, DefectDojo hashes each Finding on title, severity, file path, vulnerability IDs, and CWE, so the same advisory in the same dependency path isn't duplicated.
  • CVE and CWE data preserved. CVE identifiers become vulnerability IDs and all reported CWEs are stored, so findings can be filtered and reported by vulnerability class.
  • A real lifecycle. Reimporting into the same Test mitigates advisories that disappeared after an upgrade and reactivates any that return.
  • Severity that matches policy. npm's low, moderate, high, and critical map onto DefectDojo's scale, so the same SLA rules apply as for other scanners.
  • Context for the fix. The mitigation field carries npm's recommendation, and the description lists every vulnerable path (up to 25 per version) so engineers can see why a package is present.

How This Integration Works

DefectDojo has two scan types for npm audit output, because npm changed its report format in version 7.

  • NPM Audit Scan reads npm 6 and older reports, using the advisories subtree. This is the parser documented on this page.
  • NPM Audit v7+ Scan reads reports from npm 7 and later, using the vulnerabilities subtree.

The npm 6 parser refuses newer reports: if the file contains auditReportVersion, it raises an error telling you the format is not supported. DefectDojo's docs explain why. The v7+ format dropped fields this parser depends on, including the advisory overview, recommendation, CVE number, and CWE. A report that contains an error object (for example a failed registry lookup) is also rejected, so a broken audit doesn't import as an empty result.

1. Produce the JSON report.

npm audit --json > npm-audit.json

2. Import it with the scan type that matches your npm version. In the UI, open the Engagement, choose Import Scan Results, select NPM Audit Scan (or NPM Audit v7+ Scan), and upload the file. With the API in Community Edition or DefectDojo Pro:

curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
  -H "Authorization: Token $DD_API_TOKEN" \
  -F "scan_type=NPM Audit Scan" \
  -F "file=@npm-audit.json" \
  -F "product_name=checkout-service" \
  -F "engagement_name=CI" \
  -F "auto_create_context=true"

DefectDojo Pro users can do the same with Universal Importer:

universal-importer import \
  --defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
  --scan-type "NPM Audit Scan" \
  --report-path "./npm-audit.json" \
  --product-name "checkout-service" \
  --engagement-name "CI" \
  --auto-create-context

3. Reimport on every build into the same Test via /api/v2/reimport-scan/.

Data Granularity: What Gets Imported

The table describes the NPM Audit Scan (npm 6) parser.

DefectDojo Field Source in npm audit Report Notes
Title title, module_name, vulnerable_versions Formatted as title - (module, range)
Severity severity low to Low, moderate to Medium, high to High, critical to Critical, anything else to Info
Description Advisory URL, overview, module details Adds vulnerable and patched versions, vulnerable paths, CWE, and access
Mitigation recommendation npm's upgrade guidance
References url Advisory link
Vulnerability IDs cves Every listed CVE
CWE cwe First CWE as primary, all CWEs stored; falls back to 1035 when none
Component Name / Version module_name, first findings[].version Package and the first installed version found
File Path First dependency path 64-character git hashes replaced with censored_by_npm_audit
Finding type Static All npm audit Findings are static
Deduplication Hashcode Title, severity, file path, vulnerability IDs, CWE

Within one report, the parser keeps one Finding per advisory ID and module. For npm 7+ reports, the NPM Audit v7+ Scan type hashes on title, severity, CWE, and vuln ID from tool instead.

Use Cases

In a CI pipeline: Every pull request build runs npm audit --json and reimports the result into the service's Test. A release check queries DefectDojo for new High or Critical Findings, while advisories already risk-accepted with an expiry don't block the build.

Across a monorepo or many services: A platform team with 40 Node.js services imports each one into its own Asset. When a widely used package gets a critical advisory, filtering by vulnerability ID shows every affected service at once.

For legacy projects pinned to npm 6: Older applications that can't move to a newer npm yet still get tracked with the richer npm 6 report format, including CVEs and recommendations.

Operational Tips

  • Pick the scan type by npm version, not by habit. If a CI image upgrades npm, imports with NPM Audit Scan start failing with the auditReportVersion error, which is your cue to switch to NPM Audit v7+ Scan.
  • Don't mix the two scan types in the same Test. Their titles and hash fields differ, so switching formats mid-history produces a set of mitigated Findings and a matching set of new ones.
  • npm replaces dependencies installed from git with a hash that changes on every run. The parser censors those hashes in file paths, which keeps deduplication stable for git-sourced packages.
  • Use minimum_severity=Medium if low-severity advisories in dev-only tooling would bury your team, and tag imports with the branch or release.
  • Risk-accept advisories with no patched version and set an expiration date so they come back for review when a fix is likely.
  • Production and development dependencies are both reported. If dev tooling never ships, check which flag your npm version supports for excluding dev dependencies (current versions use --omit=dev) before import, and document that choice in the Engagement.