feat(parsers): add composer audit, pnpm audit, dotnet vulnerable packages and mix_audit parsers - #15475
Merged
Conversation
composer audit (PHP), pnpm audit (Node), dotnet list package --vulnerable (NuGet) and mix deps.audit (Elixir). Each mirrors the existing npm_audit / yarn_audit / cargo_audit shape: a vendor advisory becomes one finding with the advisory's own severity, the affected package as the component, the fixed version as the mitigation and the advisory URL as the reference. Every severity comes from the tool, spanning Critical to Low across the fixtures - no finding is imported at a level the parser chose. Details worth knowing, each covered by a test: - composer never reports the INSTALLED version, only the affected range, so component_version is deliberately left unset instead of being filled with a range. Its advisories carry a CVE and a GHSA; both are attached, and the GHSA is the fallback because "cve" is frequently null. - pnpm emits the npm v6 "advisories" envelope, not the npm 7+ shape, and has no CVE field at all - the GHSA is the only identifier, and none is inferred. Its "CWE-1321" string is converted to the numeric CWE. - dotnet reports no advisory id, only advisoryurl, so the GHSA is parsed out of it. Both topLevelPackages and transitivePackages are walked, because a vulnerable package is usually pulled in indirectly and only the transitive list names it; transitive findings get a mitigation that names the real options rather than telling the reader to upgrade a package that is not in their project file. - mix deps.audit prints compiler output before the JSON on the first run in a clean checkout, which makes the file unparseable. The docs say to capture a second run and the parser's error message names it. Fixtures are real output from Composer 2.10.2, pnpm 11.18.0, .NET SDK 8.0.423 and Elixir 1.17.3, each run against deliberately vulnerable pins. 49 tests, passing with V3_FEATURE_LOCATIONS both on and off. Only the four parser directories and the two dedupe dicts in settings.dist.py are touched.
blakeaowens
approved these changes
Aug 2, 2026
Maffooch
approved these changes
Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Four package-manager advisory parsers, mirroring the existing
npm_audit/yarn_audit/cargo_auditshape: a vendor advisory becomes one finding carrying the advisory's own severity, theaffected package as the component, the fixed version as the mitigation, and the advisory URL as the
reference.
Composer Audit Scan--format=json --locked)severitypnpm Audit Scanadvisoriesenvelope)severityDotnet Vulnerable Packages Scan--format json)severityMix Audit Scan--format json)severitySeverities are the tool's own and span Critical→Low across the fixtures. Nothing is imported at a
level the parser picked, and there are no Info findings.
Fixtures — real output, each from a deliberately vulnerable set of pins committed as the sample
input. Tool version and exact command are in each docs page.
Per-tool details worth a reviewer's attention, each covered by a test:
component_versionis deliberately left unset rather than filled with a range. Its advisories carryboth a CVE and a GHSA; both are attached, and the GHSA is the fallback because
cveis frequentlynull.npm_auditthannpm_audit_7_plus. Ithas no CVE field at all, so only the GHSA is attached — no CVE is inferred. Its
"CWE-1321"stringis converted to the numeric CWE.
advisoryurl, so the GHSA is parsed out of the URL. BothtopLevelPackagesandtransitivePackagesare walked — a vulnerable package is usually pulledin indirectly and only the transitive list names it. Transitive findings get a mitigation naming the
real options instead of telling the reader to upgrade a package that is not in their project file.
which makes the file unparseable. The docs say to capture a second run, and the parser's error
message names that as the likely cause.
Reproducing the composer fixture needs one non-obvious step, recorded in its docs page: Composer
2.10 refuses to resolve a package affected by a security advisory, so a project pinning vulnerable
versions will not install until
config.policy.advisories.blockis set tofalse.Test results
49 tests across the four parsers, all passing, each file run with
V3_FEATURE_LOCATIONSboth on andoff.
ruff check .is clean repo-wide without any change toruff.toml.Documentation
A page per parser under
docs/content/supported_tools/parsers/file/, each with the exact command,tool version, severity mapping, and the reproduction caveats above.
Deduplication entries added (the only shared file touched):
Composer omits
component_versionfor the reason above.descriptionis excluded everywhere: itcarries the advisory prose, which would rehash if a vendor reworded it.
Nothing dropped. All four tools produce real severities, so none hit the "Info-only, drop it"
condition. Verified absent from current
dev(253 tool dirs) before building.Checklist
dev.dev— feature, not bugfix.ruff.tomlunmodified.