pnpm Audit Integration with DefectDojo
pnpm Audit Integration with DefectDojo
pnpm audit is the dependency security check built into pnpm, the open source JavaScript package manager. It reads the project's lockfile and checks the installed packages against the npm registry's advisory database, reporting each matching advisory with its severity, vulnerable and patched version ranges, and the dependency paths that pull the package in. Run with --json, it writes a JSON report that DefectDojo imports.
pnpm Audit Integration with DefectDojo
Our frontend and Node.js services moved to pnpm, and with it came pnpm audit as the cheapest possible dependency check: no extra tool, no extra license, already in every developer's path. What it lacked was memory. Each run printed the same advisories again, and nobody could tell which were new. Importing pnpm audit reports into DefectDojo gives each advisory and installed version its own Finding on the service's Asset, deduplicated across runs, with the upgrade target in the mitigation and an SLA counting down.
Why pnpm Audit Matters
JavaScript projects routinely pull in hundreds of transitive packages, and most advisories land in packages nobody added directly.
- It runs against the lockfile, so it reports what is actually resolved, including transitive dependencies.
- It ships with pnpm, which makes it the lowest-friction SCA check for teams already using pnpm.
- Each advisory carries a GitHub advisory ID, a CWE, and the version range that fixes it.
- Dependency paths show whether a fix is a direct upgrade or needs a parent package to move first.
- Run alone, it reports a full list every time, so triage decisions and exceptions are lost between runs.
Advantages of This Integration
What we gained by sending pnpm audit output through DefectDojo:
- One Finding per advisory per installed version. When an advisory matches two copies of a package at different versions, each becomes its own Finding, because each is fixed separately.
- Clean deduplication. DefectDojo hashes on component name, component version, and the advisory ID, so repeat runs on an unchanged lockfile create nothing new.
- Upgrades close findings. Reimporting after a dependency bump mitigates the old version's findings and adds anything the new version still matches.
- Dependency paths in the description. The parser keeps every path pnpm reported, which tells the engineer whether to bump the package directly or a parent.
- Advisory IDs for correlation. The GHSA ID is stored as a vulnerability ID, so the same advisory can be found across every Asset that depends on the package.
- SLAs and ticketing. npm severities map onto DefectDojo's scale, and findings can be assigned, risk-accepted, or pushed to Jira like any other.
How This Integration Works
DefectDojo imports pnpm audit results with the pnpm Audit Scan scan type.
1. Run pnpm audit with JSON output. From the project root, with the lockfile present:
pnpm audit --json > pnpm_audit.json
To limit the report to production dependencies, add --prod. pnpm writes the npm v6 style advisories object, keyed by advisory ID, not the npm 7 and later vulnerabilities shape. That is why pnpm reports have their own scan type rather than using an npm audit parser.
2. Import the file. In the UI, open the Engagement, choose Import Scan Results, select pnpm Audit Scan, and upload the file. Through the API, available in Community Edition and DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=pnpm Audit Scan"
-F "file=@pnpm_audit.json"
-F "product_name=web-frontend"
-F "engagement_name=CI"
-F "auto_create_context=true"
DefectDojo Pro users can run the same import with Universal Importer:
universal-importer import
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/"
--scan-type "pnpm Audit Scan"
--report-path "./pnpm_audit.json"
--product-name "web-frontend"
--engagement-name "CI"
--auto-create-context
3. Reimport on lockfile changes. Send each new report to /api/v2/reimport-scan/ for the same Test so resolved advisories are mitigated and new ones are added.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in pnpm Audit JSON | Notes |
|---|---|---|
| Title | module_name and title |
Formatted as module: advisory title |
| Severity | severity |
critical, high, moderate (Medium), low, info; unrecognized values become Medium |
| Description | title, module, installed version, vulnerable_versions, patched_versions, paths |
Every dependency path pnpm reported is listed |
| Mitigation | patched_versions |
"Upgrade module to patched range", or generic advice if none |
| Component Name | module_name |
The npm package |
| Component Version | findings[].version |
One Finding per installed version |
| CWE | cwe |
"CWE-918" style values converted to the number |
| Vulnerability IDs | github_advisory_id |
The GHSA ID; pnpm reports no CVE, so none is inferred |
| Vuln ID from Tool | github_advisory_id |
Falls back to the numeric advisory id |
| References | url |
The advisory link |
| Finding type | Static | pnpm audit reads the lockfile |
| Deduplication | Hashcode | Component name, component version, vuln ID from tool |
Use Cases
In a CI/CD pipeline: Every merge to main runs pnpm audit --json and reimports the result. A release gate queries DefectDojo for new Critical or High findings on the Asset, while advisories that were already risk-accepted stay out of the way.
In a monorepo: A team with several pnpm workspaces imports each workspace's report into its own Test, so the owning team sees only the advisories in its dependencies.
During a fleet-wide advisory: When a widely used package publishes an advisory, the security team searches DefectDojo by GHSA ID to list every Asset with an affected version and tracks upgrades to completion.
For prioritizing upgrades: Dependency paths in each description let engineers group findings that one parent upgrade will clear, which cuts the number of pull requests needed.
Operational Tips
- Use
--prodwhen you only care about what ships. Development dependencies still matter for build security, so consider a separate Test for a full audit. - pnpm reports do not include CVE IDs. If your SLA or reporting depends on CVEs, correlate through the GHSA ID, which links to the advisory page.
- Expect two Findings when two versions of a package are installed. Close them together by deduplicating versions in the lockfile where possible.
- Set
minimum_severity=Lowon import to drop info advisories if they add noise. - Risk-accept advisories in packages that are never reached at runtime with a note and an expiration date, rather than marking them false positive.
- Keep the scan type exact and consistent.
pnpm Audit Scanis separate from the npm audit scan types, and a reimport updates a Test of one scan type, so switching types partway through starts a separate history.