Audit dependencies without modifying application files. Do not call an assessment or CVE MCP tool.
Inputs
workspace-path: Absolute project root.output-path: Required JSON result path supplied by the assessment catalog.scan-scope:direct(default) orall.
1. Detect Ecosystem
- Maven/Gradle project → advisory ecosystem
maven. .sln,.slnx, or project files →nuget.package.json→npm.- If none apply, write
[]tooutput-pathand stop.
2. Collect Dependencies
Prefer project wrappers and structured command output. Never edit manifests or lock files.
Maven/Gradle
- Maven: run
./mvnw dependency:list -DoutputAbsoluteArtifactId=true; add-DexcludeTransitive=truefor direct scope. Fall back tomvn, then staticpom.xmlparsing. - Gradle: run
./gradlew dependencies --configuration runtimeClasspath; fall back togradle, then staticbuild.gradle/build.gradle.ktsparsing. - Coordinate format:
groupId:artifactId:version.
NuGet
- Run
dotnet list package --format json; add--include-transitivefor all scope. - If no solution exists at the root, target each discovered project explicitly.
- Fall back to
PackageReference,Directory.Packages.props, andpackages.configparsing. - Coordinate format:
PackageName@version.
npm
- Run
npm list --json; add--depth=0for direct scope. - Fall back to
package-lock.json,yarn.lock,pnpm-lock.yaml, thenpackage.json. - Coordinate format:
package-name@version.
For each dependency retain its manifest path and 1-based declaration line when directly declared; use line 0 for transitive dependencies.
3. Query GitHub Advisories
Batch coordinates in groups of at most 30. Use gh api when available:
/advisories?ecosystem=<maven|nuget|npm>&affects=<url-encoded-coordinates>&per_page=100
Follow pagination. If gh is unavailable, use the GitHub REST API with GITHUB_TOKEN when present. Never use general web search for vulnerability conclusions.
If one batch fails, record the error and continue remaining batches. A failed query must not silently become a clean scan: return a wrapper with status: partial and the failed batch details instead of [].
4. Normalize Results
- Ignore withdrawn advisories.
- Use
cve_id, falling back toghsa_id. - Deduplicate the same advisory across dependency batches.
- Map severity: critical/high →
mandatory; medium →optional; low/unknown →potential. - Group all affected dependencies for one advisory into one finding.
- Include advisory URL, vulnerable range, first patched version, and manifest evidence.
Output
On a complete scan, write a flat JSON array to output-path; use [] only when every query succeeded and no vulnerability was found:
[
{
"id": "CVE-2024-0001",
"name": "Advisory summary",
"status": "FOUND",
"category": "CVE",
"severity": "mandatory",
"storyPoint": 1,
"evidence": {
"files": ["pom.xml:42"],
"explanation": "Advisory URL, affected coordinates, vulnerable range, and patched version"
}
}
]
When any advisory batch fails, write:
{
"input_name": "CVE dependency assessment",
"analysis_method": "GitHub Security Advisories API",
"status": "partial",
"result": {
"finding": "CVE scan completed with one or more failed advisory batches",
"confidence": "low",
"evidence": ["<failure details>"],
"values": ["<all successfully returned FOUND findings>"]
}
}
Write the output exactly once using a temporary file followed by atomic rename. Return only the output path and concise counts to the parent assessment.