| name | cvss-score-extraction |
| description | Extract CVSS (Common Vulnerability Scoring System) scores from Trivy vulnerability JSON output with proper fallback handling across multiple score sources (NVD, GHSA, RedHat). Use this skill whenever processing vulnerability scan results that require numeric severity scores, building security reports, or mapping CVEs to CVSS scores.
|
CVSS Score Extraction
Trivy embeds CVSS scores from multiple sources. Each source may provide V2 and/or V3
scores. Priority order for extraction: NVD → GHSA → RedHat → first available.
Trivy CVSS JSON structure
"CVSS": {
"nvd": {
"V2Score": 6.5,
"V3Score": 8.1,
"V2Vector": "AV:N/AC:L/Au:S/C:C/I:N/A:N",
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
},
"ghsa": {
"V3Score": 7.5,
"V3Vector": "CVSS:3.1/..."
},
"redhat": {
"V3Score": 7.0
}
}
Python extraction function with fallback
def extract_cvss_score(vuln: dict) -> str:
"""
Extract best available CVSS score from a Trivy vulnerability dict.
Prefers V3 over V2. Priority: NVD > GHSA > RedHat > any available.
Returns score as string, or "N/A" if none found.
"""
cvss = vuln.get("CVSS", {})
priority_sources = ["nvd", "ghsa", "redhat"]
for source in priority_sources:
scores = cvss.get(source, {})
if scores.get("V3Score") is not None:
return str(scores["V3Score"])
if scores.get("V2Score") is not None:
return str(scores["V2Score"])
for source, scores in cvss.items():
for key in ["V3Score", "V2Score"]:
if scores.get(key) is not None:
return str(scores[key])
return "N/A"
Edge cases
- Missing CVSS key entirely: Return "N/A"
- Score is 0.0: This is a valid score (informational), include it — don't treat as missing
- Multiple V3 scores differ across sources: Use highest-priority source (NVD first)
- Only V2 available: Use it with a note if needed; for CSV output just use the value
Integration example
score = extract_cvss_score(vuln)
row = {
"CVE_ID": vuln.get("VulnerabilityID", "N/A"),
"CVSS_Score": score,
...
}