security-cve-review
Inventory NuGet packages and Aspire-managed container/infra components, cross-reference them against OSV.dev, and assess which matched vulnerabilities are actually reachable in how this application us
Files1
View on GitHubSKILL.md.claude/skills/security-cve-review/SKILL.md
GitHubInstructions
Contract: specs/008-adversarial-security-review/contracts/skill-commands.md (/security-cve-review) and contracts/osv-dev-api.md.
Requirements satisfied: FR-003, FR-004, FR-007, FR-010, FR-011, SC-005.
1. Read trigger-mode config (FR-011)
Read specs/008-adversarial-security-review/review-config.json and check dependencyReview.trigger. Today the only valid value is "on-demand" — proceed for a manual invocation. If it's ever something else and this isn't a manual request, stop and tell the user.
2. Inventory dependencies (FR-003)
.specify/scripts/bash/security-inventory-dependencies.sh \
--repo-root . \
--out specs/008-adversarial-security-review/findings/.tmp-dependency-components.json
3. Query OSV.dev (FR-003)
.specify/scripts/bash/security-osv-query.sh \
--components specs/008-adversarial-security-review/findings/.tmp-dependency-components.json \
--out specs/008-adversarial-security-review/findings/.tmp-vulnerability-matches.json
If this step exits non-zero (OSV.dev unreachable), stop and report the error to the user — do not proceed to persist a partial or empty result as if the review completed cleanly.
4. Assess relevance (FR-004 — judgment call, this is the Agent-invocation step)
For each entry in .tmp-vulnerability-matches.json, use the Agent tool to assess whether the vulnerable functionality is actually reachable given how this application uses that dependency — read the OSV.dev advisory text (fetch https://api.osv.dev/v1/vulns/<id> if needed for details beyond the id) and cross-reference against the dependency's usedBy projects and, if helpful, a quick grep of how that package's APIs are actually called in those projects. Assign one of: reachable, not-reachable, unknown (use unknown rather than guessing when you genuinely can't tell).
Edge Case §1: if the component's shipsInRuntime is false (dev/build-tooling-only, from the inventory step), still report the match, but explicitly note it's a lower-relevance finding than a shipped runtime dependency — do not omit it.
5. Persist findings
.specify/scripts/bash/security-findings-store.sh \
--findings-dir specs/008-adversarial-security-review/findings \
start-run --capabilities dependency --scope full --trigger manual
Capture RUN_ID, then for each vulnerability match:
.specify/scripts/bash/security-findings-store.sh \
--findings-dir specs/008-adversarial-security-review/findings \
upsert-finding --run-id "$RUN_ID" --source dependency \
--title "<OSV id + package name>" --description "<advisory summary + reachability rationale>" \
--severity "<severity from the OSV match>" \
--evidence "<package>@<version> (<OSV id>)" \
--relevance "<reachable|not-reachable|unknown>"
6. Finalize and report
.specify/scripts/bash/security-findings-store.sh \
--findings-dir specs/008-adversarial-security-review/findings \
finalize-run --run-id "$RUN_ID" --full true
The dependency review always covers the full dependency set (there is no PR-style scoping for FR-003), so --full true is always correct here — a component upgraded to a patched version will correctly auto-resolve its prior finding (Acceptance Scenario 3, US2).
.specify/scripts/bash/security-report-render.sh \
--findings-dir specs/008-adversarial-security-review/findings \
--out specs/008-adversarial-security-review/findings/report.md
.specify/scripts/bash/security-report-render.sh \
--findings-dir specs/008-adversarial-security-review/findings \
--capability dependency --snapshot-date "$(date -u +%Y%m%d)" \
--out "specs/008-adversarial-security-review/findings/$(date -u +%Y%m%d)-cve-review.md"
rm -f specs/008-adversarial-security-review/findings/.tmp-dependency-components.json \
specs/008-adversarial-security-review/findings/.tmp-vulnerability-matches.json
The dated file is a git-tracked, point-in-time snapshot of just this capability's findings for today (re-running later the same day overwrites today's file, a new day gets a new file); report.md remains the always-current cross-capability view.
Show the user the ## Dependency/CVE Review section. Each finding must show its relevance — never present matches as an undifferentiated raw list (SC-005). If zero findings, say so explicitly.
7. Independence check (FR-010)
If asked to demonstrate FR-010, confirm this capability produces a complete, correct report using only findings.json/runs.json entries with source: dependency — no dependency on code or adversarial findings existing.
User Input
$ARGUMENTS