agentsclimarketplace

Vulnerability csv reporting

Skill cxcscmu/SkillLearnBench/skills/b4-skill-creator-claude-sonnet-4-6/dependency-vulnerability-check/vulnerability-csv-reporting

Generate structured CSV security audit reports from Trivy or other vulnerability scanner JSON output. Use this skill whenever the user asks to write vulnerability results to a CSV file, create a security audit report, or export CVE findings with fields like Package, Version, CVE_ID, Severity, CVSS_Score, Fixed_Version, Title, Url.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill vulnerability-csv-reporting

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

4.1 KB, 947 tokens by cl100k_base, as published. Nobody here has run it

Vulnerability CSV Reporting

Convert vulnerability scan JSON output into a well-structured CSV report using Python's csv.DictWriter for reliable quoting and escaping.

CSV Schema

Standard security audit columns:

ColumnSource in Trivy JSONNotes
PackagePkgNamee.g. "lodash"
VersionInstalledVersione.g. "4.17.20"
CVE_IDVulnerabilityIDe.g. "CVE-2021-23337"
SeveritySeverityHIGH or CRITICAL
CVSS_ScoreCVSS.nvd.V3Score (with fallback)float or "N/A"
Fixed_VersionFixedVersionversion string or "N/A" if missing
TitleTitle (fallback: Description[:80])Short description of the vuln
UrlReferences[0]First reference URL or "N/A"

Complete Python script

import csv
import json

FIELDNAMES = ["Package", "Version", "CVE_ID", "Severity", "CVSS_Score",
              "Fixed_Version", "Title", "Url"]

def extract_cvss_score(vuln):
    cvss = vuln.get("CVSS", {})
    for source in ["nvd", "ghsa", "redhat"]:
        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"

def vuln_to_row(vuln):
    title = vuln.get("Title") or vuln.get("Description", "")[:120]
    refs = vuln.get("References") or []
    url = refs[0] if refs else "N/A"
    return {
        "Package":       vuln.get("PkgName", "N/A"),
        "Version":       vuln.get("InstalledVersion", "N/A"),
        "CVE_ID":        vuln.get("VulnerabilityID", "N/A"),
        "Severity":      vuln.get("Severity", "N/A"),
        "CVSS_Score":    extract_cvss_score(vuln),
        "Fixed_Version": vuln.get("FixedVersion") or "N/A",
        "Title":         title,
        "Url":           url,
    }

def write_csv(results_path, output_path, severities=("HIGH", "CRITICAL")):
    with open(results_path) as f:
        data = json.load(f)

    rows = []
    for result in data.get("Results", []):
        for vuln in result.get("Vulnerabilities") or []:
            if vuln.get("Severity") in severities:
                rows.append(vuln_to_row(vuln))

    with open(output_path, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
        writer.writeheader()
        writer.writerows(rows)

    print(f"Wrote {len(rows)} vulnerabilities to {output_path}")

write_csv("/root/trivy-results.json", "/root/security_audit.csv")

Key patterns

  • Use csv.DictWriter — it handles quoting/escaping automatically
  • FixedVersion is often absent; always use .get("FixedVersion") or "N/A"
  • References may be None or empty list; guard with or []
  • Title can be empty; fall back to truncated Description
  • Filter severity before writing — don't include LOW/MEDIUM

Deduplication (optional)

If the same CVE appears in multiple result targets, deduplicate on (CVE_ID, Package, Version):

seen = set()
for vuln in vulns:
    key = (vuln["VulnerabilityID"], vuln["PkgName"], vuln["InstalledVersion"])
    if key not in seen:
        seen.add(key)
        rows.append(vuln_to_row(vuln))

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.