$npx -y skills add opendatahub-io/ai-helpers --skill cve-scanUse this skill to scan a cloned repository for a specific CVE using version-matched toolchains. Supports Go (govulncheck with GOTOOLCHAIN), Node.js (npm audit), and Python (pip-audit). Writes scan result to autofix-output/cve-scan-result.json.
| 1 | # Skill: CVE Scan |
| 2 | |
| 3 | Scan a cloned repository to determine whether a specific CVE is present as an |
| 4 | unfixed vulnerability. Uses language-appropriate scanning tools with |
| 5 | version-matched toolchains for accurate results. |
| 6 | |
| 7 | ## Step 1: Run the scan script |
| 8 | |
| 9 | Run `scripts/scan.sh` which handles language detection, version-matched |
| 10 | toolchain selection, vulnerability scanning, package version checks, and |
| 11 | base image detection: |
| 12 | |
| 13 | ```bash |
| 14 | bash scripts/scan.sh "${REPO_DIR}" "${CVE_ID}" "${PACKAGE}" "${BUILD_LOCATION:-.}" |
| 15 | ``` |
| 16 | |
| 17 | The script: |
| 18 | - Detects project language from manifest files (go.mod, package.json, requirements.txt) |
| 19 | - For Go: extracts the target Go version from go.mod and runs govulncheck with |
| 20 | `GOTOOLCHAIN` set to that exact version, preventing false negatives from a |
| 21 | newer local toolchain. Falls back to local toolchain if download fails. |
| 22 | - For Node.js: runs `npm audit --json` |
| 23 | - For Python: runs `pip-audit -r requirements.txt` |
| 24 | - If the CVE is not found in the scan, checks package manifests directly |
| 25 | - If the package is not in any manifest, checks Dockerfile base images |
| 26 | - Writes structured result to `autofix-output/cve-scan-result.json` |
| 27 | |
| 28 | ## Step 2: Interpret the scan result |
| 29 | |
| 30 | Read `autofix-output/cve-scan-result.json` and evaluate the `verdict` field. |
| 31 | |
| 32 | | Verdict | Meaning | |
| 33 | |---------|---------| |
| 34 | | `present` | CVE confirmed in scan — fix needed | |
| 35 | | `present_by_version` | Package in manifest at vulnerable version — fix needed | |
| 36 | | `absent` | Not in scan, not in manifests — VEX justification possible | |
| 37 | | `in_base_image` | Package not in app code, found in Dockerfile base image | |
| 38 | | `informational` | Go: module present but vulnerable symbol not called | |
| 39 | | `scan_failed` | Scanner could not run — manual review needed | |
| 40 | |
| 41 | Use judgment to validate the verdict: |
| 42 | - If `present_by_version`: compare the manifest version against the CVE's |
| 43 | affected version range to confirm it is actually vulnerable |
| 44 | - If `in_base_image`: determine whether a newer base image tag is available |
| 45 | using `skopeo list-tags`, or whether the base image team needs to act |
| 46 | - If `scan_failed`: check the `scan_output_summary` for the root cause and |
| 47 | decide whether to retry or skip |
| 48 | |
| 49 | ## Caller contract |
| 50 | |
| 51 | The orchestrator (`jira-autofix-cve-resolve`) reads `autofix-output/cve-scan-result.json` |
| 52 | and routes based on `verdict`: |
| 53 | - `present` / `present_by_version` → invoke `/cve-fix-apply` |
| 54 | - `absent` / `informational` → invoke `/cve-vex-assess` |
| 55 | - `in_base_image` → check for newer base image tag, create PR or document |
| 56 | - `scan_failed` → skip with documentation |
| 57 | |
| 58 | ## Gotchas |
| 59 | |
| 60 | - govulncheck is not installed in all environments; the script falls back to version-based detection when it is unavailable |
| 61 | - GOTOOLCHAIN requires a full patch version (e.g., `go1.25.0`, not `go1.25`); omitting the patch segment causes the download to fail silently |
| 62 | - Exit code 3 from govulncheck means "vulnerabilities found" (a successful scan), not a failure — do not treat it as an error |