Query MITRE, OSV.dev, and Go vulnerability database to produce a structured report of affected packages, ecosystems, and vulnerable version ranges for a CVE.
57
66%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Fix and improve this skill with Tessl
tessl review fix ./ocp-admin/skills/cve-recon/SKILL.mdUse this skill when the user asks you to look up, describe, explain, or get details about a specific CVE — its affected packages, ecosystem, version ranges, or severity. Input is a CVE ID taken from conversation context.
The user may specify an optional output format flag:
--format markdown — (default) Markdown report--format json — machine-readable JSON object--format csv — single-row CSV with a header rowRecord the resolved value as OUTPUT_FORMAT (default: markdown).
Confirm you have a CVE ID in the format CVE-YYYY-NNNNN (e.g., CVE-2023-38039).
If the CVE ID is missing or does not match the format, ask the user to provide it. Do not proceed.
Resolve scripts directory — the helper scripts are inside the skill's scripts/ subfolder:
SCRIPTS_DIR="scripts"
test -f "$SCRIPTS_DIR/fetch_cve_metadata.py" || { echo "Error: Scripts directory not found at $SCRIPTS_DIR"; exit 1; }Do not hallucinate data — rely strictly on script outputs. If a script produces an unexpected error, report it verbatim and stop.
Run the fetch_cve_metadata.py script to query all sources in one call:
python $SCRIPTS_DIR/fetch_cve_metadata.py [CVE-ID]The script automatically queries MITRE CVE API, OSV.dev, and (if a GO-* alias is found) the Go vulnerability database. It returns merged JSON with:
cve_id — the CVE identifierdescription — English CVE description from MITREaffected[] — all affected packages, each with:
ecosystem — Go, PyPI, npm, rpm, etc.package — package/module nameversions — object with introduced and/or fixed boundariessource — which database provided this entry (mitre, osv, go_vuln_db)vendor — vendor name (from MITRE entries)go_id — Go vulnerability ID (from go_vuln_db entries only)aliases[] — cross-references (GO-, GHSA-, etc.)errors[] — any API failures (non-fatal; the script continues with available data)Error handling:
affected is empty and errors contains "not found (404)": stop and report "CVE not found"affected is empty but no 404 error: report "No affected package data available"Always produce a report. Use N/A for any field that could not be determined.
If OUTPUT_FORMAT is markdown:
## CVE Reconnaissance Report
- **CVE ID:** [CVE-ID]
- **Description:** [English description from MITRE cna.descriptions; supplemented by OSV summary if MITRE description is sparse]
### Data Sources
| Source | Status | Record ID |
|---|---|---|
| MITRE CVE | [Fetched \| Error] | [CVE-ID] |
| OSV.dev | [Fetched \| Not found \| Error] | [OSV record ID or N/A] |
| Go vuln DB | [Fetched \| Not applicable \| Not found] | [GO-YYYY-NNNN or N/A] |
**Cross-references (from OSV aliases):** [comma-separated list of aliases: GO-YYYY-NNNN, GHSA-*, etc. | None found]
### Affected Packages
[For each affected entry — merged from MITRE and OSV, deduplicated by package name + ecosystem:]
#### [vendor] / [product]
| Field | Value |
|---|---|
| Package name | [packageName] |
| Ecosystem | [Go \| RPM \| PyPI \| npm \| Rust \| PHP \| Maven \| NuGet \| Unknown] |
| Collection URL | [collectionURL or N/A] |
| Source(s) | [MITRE \| OSV.dev \| MITRE + OSV.dev] |
**Vulnerable version ranges (MITRE):**
| Version | Status | Upper bound | Bound type | Version type |
|---|---|---|---|---|
| [version] | [affected\|unaffected] | [lessThan / lessThanOrEqual value or —] | [< \| <=] | [semver\|rpm\|custom] |
Default status for unlisted versions: [defaultStatus]
[If OSV provided version ranges for this package:]
**Vulnerable version ranges (OSV.dev):**
| Introduced | Fixed |
|---|---|
| [version or "0"] | [version or "not yet fixed"] |
[If version ranges differ between MITRE and OSV: "Note: MITRE and OSV.dev report different version boundaries for this package. The union of both ranges is treated as the vulnerable range."]
[If Go vuln DB entry was found (GO-* alias detected in OSV):]
**Go vulnerability database enrichment:**
- **Go vuln ID:** [GO-YYYY-NNNN]
- **Authoritative module path:** [affected[].package.name]
- **Vulnerable ranges (Go vuln DB):**
| Introduced | Fixed |
|---|---|
| [version or "0"] | [version or "not yet fixed"] |
- **Affected packages within module:**
[List from ecosystem_specific.imports[].path, or N/A if absent]
- **Affected symbols:**
[List from ecosystem_specific.imports[].symbols[], or "All exported symbols" if absent]
- **Go vuln DB last modified:** [modified timestamp]
### CVSS
| Source | Version | Score | Severity |
|---|---|---|---|
| MITRE | [3.1 \| 3.0] | [baseScore] | [baseSeverity] |
| OSV.dev | [version or —] | [score or —] | [severity or —] |
[If scores differ: "Note: MITRE and OSV.dev report different CVSS scores. The higher score ([X]) is highlighted."]
[If no CVSS data from either source: "No CVSS data available from MITRE or OSV.dev."]
### References
[Numbered list of deduplicated URLs from both MITRE cna.references[].url and OSV references[].url, with source noted in parentheses: (MITRE), (OSV), or (both)]Missing values rule — applies to both JSON and CSV:
"" — never use null.null.If OUTPUT_FORMAT is json:
{
"cve_id": "[CVE-ID]",
"description": "[English description]",
"sources": {
"mitre": {"status": "fetched | error", "record_id": "[CVE-ID]"},
"osv": {"status": "fetched | not_found | error", "record_id": "[OSV ID or empty string]", "aliases": ["GO-YYYY-NNNN", "GHSA-*"]},
"go_vuln_db": {"status": "fetched | not_applicable | not_found", "record_id": "GO-YYYY-NNNN | empty"}
},
"cvss": {
"mitre": {"version": "3.1 | 3.0 | empty", "score": 7.5, "severity": "High | empty"},
"osv": {"version": "3.1 | 3.0 | empty", "score": 7.5, "severity": "High | empty"}
},
"affected": [
{
"vendor": "[vendor]",
"product": "[product]",
"package_name": "[packageName]",
"ecosystem": "Go | RPM | PyPI | npm | Rust | PHP | Maven | NuGet | Unknown",
"collection_url": "[url or empty string]",
"source": "mitre | osv | both",
"default_status": "affected | unaffected",
"versions_mitre": [
{
"version": "[version]",
"status": "affected | unaffected",
"less_than": "[version or empty string]",
"less_than_or_equal": "[version or empty string]",
"version_type": "semver | rpm | custom"
}
],
"versions_osv": [
{"introduced": "[ver]", "fixed": "[ver or empty string]"}
],
"go_enrichment": {
"go_vuln_id": "GO-YYYY-NNNN | empty",
"module_path": "[authoritative module path or empty string]",
"ranges": [{"introduced": "[ver]", "fixed": "[ver or empty string]"}],
"affected_packages": ["[pkg/path]"],
"affected_symbols": ["[Symbol]"],
"last_modified": "[timestamp or empty string]"
}
}
],
"references": [
{"url": "[url]", "source": "mitre | osv | both"}
]
}If OUTPUT_FORMAT is csv:
One header row followed by one data row per affected package entry:
cve_id,description,cvss_score_mitre,cvss_severity_mitre,cvss_score_osv,cvss_severity_osv,vendor,product,package_name,ecosystem,collection_url,source,vulnerable_versions_mitre,vulnerable_versions_osv,go_vuln_id,go_module_path,go_fixed_versions,osv_aliases
[values — version ranges as semicolon-separated strings; description truncated to 200 chars; osv_aliases as space-separated list]fetch_cve_metadata — queries MITRE CVE API, OSV.dev, and Go vuln DB in a single callcontainer-cve-validator — full CVE validation pipeline (uses this as Step 1)coreos-cve-validator — CoreOS CVE validation (uses this as Step 2)e46c4fa
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.