skills/aakash-dhar/claude-skills/vulnerability-report

vulnerability-report

SKILL.md

Vulnerability Report Skill

When generating vulnerability reports, scan all project dependencies for known CVEs, categorize findings by severity, and produce three separate reports — one for each severity tier. Each report is a standalone document with full context, remediation steps, and priority guidance.

IMPORTANT: Always save THREE markdown files to the project-decisions/ directory:

  1. YYYY-MM-DD-vulnerabilities-high.md — Critical and High severity (CVSS ≥ 7.0)
  2. YYYY-MM-DD-vulnerabilities-medium.md — Medium severity (CVSS 4.0–6.9)
  3. YYYY-MM-DD-vulnerabilities-low.md — Low and Informational (CVSS < 4.0)

0. Output Setup

mkdir -p project-decisions

# Files will be saved as:
# project-decisions/YYYY-MM-DD-vulnerabilities-high.md
# project-decisions/YYYY-MM-DD-vulnerabilities-medium.md
# project-decisions/YYYY-MM-DD-vulnerabilities-low.md

1. Dependency Discovery

Detect Package Ecosystem

# Detect all package managers in use
echo "=== Package Ecosystems Detected ==="

# Node.js / JavaScript / TypeScript
ls package.json package-lock.json yarn.lock pnpm-lock.yaml bun.lockb 2>/dev/null && echo "→ Node.js detected"

# Python
ls requirements.txt Pipfile pyproject.toml poetry.lock setup.py setup.cfg 2>/dev/null && echo "→ Python detected"

# Go
ls go.mod go.sum 2>/dev/null && echo "→ Go detected"

# Ruby
ls Gemfile Gemfile.lock 2>/dev/null && echo "→ Ruby detected"

# PHP
ls composer.json composer.lock 2>/dev/null && echo "→ PHP detected"

# Rust
ls Cargo.toml Cargo.lock 2>/dev/null && echo "→ Rust detected"

# Java
ls pom.xml build.gradle build.gradle.kts 2>/dev/null && echo "→ Java detected"

# .NET
ls *.csproj *.sln packages.config 2>/dev/null && echo "→ .NET detected"

# Docker (base image vulnerabilities)
ls Dockerfile Dockerfile.* docker-compose.yml 2>/dev/null && echo "→ Docker detected"

Inventory Dependencies

# Node.js — count direct and transitive
echo "=== Node.js Dependencies ==="
echo "Direct dependencies: $(cat package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('dependencies',{})))" 2>/dev/null || echo "N/A")"
echo "Dev dependencies: $(cat package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('devDependencies',{})))" 2>/dev/null || echo "N/A")"
echo "Total installed: $(ls node_modules/ 2>/dev/null | wc -l || echo "N/A")"

# Python
echo "=== Python Dependencies ==="
pip list --format=columns 2>/dev/null | wc -l || echo "N/A"
cat requirements.txt 2>/dev/null | grep -v "^#\|^$" | wc -l || echo "N/A"

# Go
echo "=== Go Dependencies ==="
cat go.sum 2>/dev/null | awk '{print $1}' | sort -u | wc -l || echo "N/A"

# Ruby
echo "=== Ruby Dependencies ==="
cat Gemfile.lock 2>/dev/null | grep "    [a-z]" | wc -l || echo "N/A"

# PHP
echo "=== PHP Dependencies ==="
cat composer.lock 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('packages',[])))" 2>/dev/null || echo "N/A"

2. Vulnerability Scanning

Node.js / npm

# Full npm audit with JSON output
npm audit --json 2>/dev/null > /tmp/npm-audit-output.json

# Parse audit results
cat /tmp/npm-audit-output.json | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    
    # npm v7+ format
    if 'vulnerabilities' in data:
        vulns = data['vulnerabilities']
        for name, info in sorted(vulns.items(), key=lambda x: {'critical':0,'high':1,'moderate':2,'low':3,'info':4}.get(x[1].get('severity','info'), 5)):
            severity = info.get('severity', 'unknown')
            via = info.get('via', [])
            fix = info.get('fixAvailable', False)
            range_affected = info.get('range', 'unknown')
            
            # Get CVE details from via
            cves = []
            if isinstance(via, list):
                for v in via:
                    if isinstance(v, dict):
                        cves.append({
                            'title': v.get('title', 'N/A'),
                            'url': v.get('url', ''),
                            'severity': v.get('severity', severity),
                            'cwe': v.get('cwe', []),
                            'cvss': v.get('cvss', {}).get('score', 'N/A'),
                            'range': v.get('range', range_affected)
                        })
            
            print(f'PACKAGE: {name}')
            print(f'  Severity: {severity.upper()}')
            print(f'  Affected: {range_affected}')
            print(f'  Fix Available: {fix}')
            for cve in cves:
                print(f'  CVE Title: {cve[\"title\"]}')
                print(f'  CVSS Score: {cve[\"cvss\"]}')
                print(f'  URL: {cve[\"url\"]}')
                print(f'  CWE: {cve[\"cwe\"]}')
            print()
    
    # Summary
    metadata = data.get('metadata', {}).get('vulnerabilities', {})
    print('=== SUMMARY ===')
    print(f'Critical: {metadata.get(\"critical\", 0)}')
    print(f'High: {metadata.get(\"high\", 0)}')
    print(f'Moderate: {metadata.get(\"moderate\", 0)}')
    print(f'Low: {metadata.get(\"low\", 0)}')
    print(f'Info: {metadata.get(\"info\", 0)}')
    print(f'Total: {metadata.get(\"total\", 0)}')
except Exception as e:
    print(f'Error parsing: {e}', file=sys.stderr)
" 2>/dev/null

# Also check with npm audit fix --dry-run to see what's auto-fixable
npm audit fix --dry-run 2>/dev/null | tail -20

Node.js / yarn

# Yarn audit
yarn audit --json 2>/dev/null | head -100

Node.js / pnpm

# pnpm audit
pnpm audit --json 2>/dev/null | head -100

Python / pip

# pip-audit (preferred)
pip install pip-audit --break-system-packages 2>/dev/null
pip-audit --format=json 2>/dev/null > /tmp/pip-audit-output.json
cat /tmp/pip-audit-output.json | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    for vuln in data:
        name = vuln.get('name', 'unknown')
        version = vuln.get('version', 'unknown')
        vulns = vuln.get('vulns', [])
        for v in vulns:
            print(f'PACKAGE: {name}=={version}')
            print(f'  ID: {v.get(\"id\", \"N/A\")}')
            print(f'  Fix Versions: {v.get(\"fix_versions\", [])}')
            print(f'  Description: {v.get(\"description\", \"N/A\")[:200]}')
            print()
except Exception as e:
    print(f'Error: {e}', file=sys.stderr)
" 2>/dev/null

# Safety check (alternative)
pip install safety --break-system-packages 2>/dev/null
safety check --json 2>/dev/null | head -100

Go

# govulncheck
go install golang.org/x/vuln/cmd/govulncheck@latest 2>/dev/null
govulncheck ./... 2>/dev/null

Ruby

# bundler-audit
gem install bundler-audit 2>/dev/null
bundle-audit check --update 2>/dev/null

PHP

# Composer audit
composer audit --format=json 2>/dev/null | head -100

Docker Base Images

# Check Dockerfile base images
echo "=== Docker Base Images ==="
grep "^FROM" Dockerfile Dockerfile.* 2>/dev/null

# Check if base images are pinned
grep "^FROM" Dockerfile 2>/dev/null | while read line; do
  image=$(echo "$line" | awk '{print $2}')
  echo "$image" | grep -q ":" || echo "⚠️ UNPINNED: $image (using :latest implicitly)"
  echo "$image" | grep -q ":latest" && echo "⚠️ UNPINNED: $image (using :latest explicitly)"
  echo "$image" | grep -qE ":[0-9]" && echo "✅ PINNED: $image"
  echo "$image" | grep -qE "@sha256:" && echo "✅ DIGEST PINNED: $image"
done

Lockfile Integrity

# Check lockfiles exist and are committed
echo "=== Lockfile Status ==="
for lockfile in package-lock.json yarn.lock pnpm-lock.yaml Pipfile.lock poetry.lock Gemfile.lock composer.lock Cargo.lock go.sum; do
  if [ -f "$lockfile" ]; then
    if git ls-files --error-unmatch "$lockfile" >/dev/null 2>&1; then
      echo "✅ $lockfile — committed"
    else
      echo "⚠️ $lockfile — exists but NOT committed to git"
    fi
  fi
done

# Check for unpinned versions in package.json
echo ""
echo "=== Unpinned Versions ==="
cat package.json 2>/dev/null | python3 -c "
import sys, json
data = json.load(sys.stdin)
for section in ['dependencies', 'devDependencies']:
    deps = data.get(section, {})
    for name, version in deps.items():
        if version.startswith('^') or version.startswith('~') or version == '*' or version == 'latest':
            print(f'  {section}/{name}: {version}')
" 2>/dev/null

3. Vulnerability Classification

Severity Mapping

Map each finding to a consistent severity:

Source Critical High Medium Low
npm audit critical high moderate low
pip-audit/safety CVSS ≥ 9.0 CVSS 7.0-8.9 CVSS 4.0-6.9 CVSS < 4.0
bundler-audit critical high medium low
govulncheck Map from CVSS Map from CVSS Map from CVSS Map from CVSS
Composer critical high medium low
CVSS v3.1 9.0-10.0 7.0-8.9 4.0-6.9 0.1-3.9

Enrichment Per Vulnerability

For each vulnerability found, gather:

- Package name and installed version
- Vulnerability ID (CVE, GHSA, OSV)
- CVSS score and vector
- CWE classification
- Severity (Critical/High/Medium/Low)
- Description of the vulnerability
- Affected version range
- Fixed version (if available)
- Is it a direct or transitive dependency?
- Is the vulnerable code reachable from our code?
- Exploit availability (PoC exists? actively exploited?)
- Fix available? (auto-fixable with npm audit fix?)
- Remediation steps

Reachability Analysis

# Check if vulnerable package is directly imported (higher risk)
# vs only a transitive dependency (lower risk)
for pkg in [list-of-vulnerable-packages]; do
  echo "=== $pkg ==="
  
  # Direct dependency?
  cat package.json 2>/dev/null | grep "\"$pkg\"" && echo "  → DIRECT dependency"
  
  # Imported in source code?
  grep -rn "import.*$pkg\|require.*$pkg\|from '$pkg'\|from \"$pkg\"" --include="*.ts" --include="*.js" --include="*.py" src/ app/ 2>/dev/null && echo "  → DIRECTLY USED in source code"
  
  # Only transitive?
  npm ls "$pkg" 2>/dev/null | head -5
done

4. Report Generation

Generate THREE separate reports, one for each severity tier:

Report 1: Critical & High Vulnerabilities

File: project-decisions/YYYY-MM-DD-vulnerabilities-high.md

Audience: Security team, engineering leads, management — requires immediate action

# 🔴 Vulnerability Report: Critical & High Severity

**Project:** [Project Name]
**Scan Date:** YYYY-MM-DD
**Scanned By:** [Name / Automated]
**Ecosystems Scanned:** [npm, pip, Go, Ruby, PHP, Docker]
**Action Required:** 🔴 IMMEDIATE — Fix within 48 hours

---

## Executive Summary

| Metric | Value |
|--------|-------|
| **Critical vulnerabilities** | X |
| **High vulnerabilities** | X |
| **Total in this report** | X |
| **Auto-fixable** | X (Y%) |
| **Requires manual fix** | X (Y%) |
| **No fix available** | X (Y%) |
| **Direct dependencies affected** | X |
| **Transitive dependencies affected** | X |

### Risk Assessment

**Overall Risk: [🔴 Critical / 🟠 High]**

[2-3 sentences: what's the worst case if these aren't fixed? 
Are any actively exploited? Is sensitive data at risk?]

---

## Quick Fix Commands

Run these immediately to fix auto-fixable vulnerabilities:
```bash
# Node.js — auto-fix what's possible
npm audit fix

# If breaking changes are acceptable
npm audit fix --force

# Python — upgrade to fixed versions
pip install --upgrade [package1] [package2] --break-system-packages

# Ruby
bundle update [gem1] [gem2]

# PHP
composer update [package1] [package2]
```

**After running fixes, re-scan:**
```bash
npm audit
pip-audit
```

---

## Detailed Findings

### VULN-001: [Package Name] — [Vulnerability Title]

| Field | Value |
|-------|-------|
| **Package** | `[package-name]` |
| **Installed Version** | `X.Y.Z` |
| **Severity** | 🔴 Critical |
| **CVSS Score** | X.X |
| **CVSS Vector** | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| **CVE** | [CVE-YYYY-XXXXX](https://nvd.nist.gov/vuln/detail/CVE-YYYY-XXXXX) |
| **CWE** | [CWE-XXX](https://cwe.mitre.org/data/definitions/XXX.html) — [Name] |
| **GHSA** | [GHSA-xxxx-xxxx-xxxx](https://github.com/advisories/GHSA-xxxx-xxxx-xxxx) |
| **Dependency Type** | Direct / Transitive |
| **Reachable** | Yes — imported in `src/services/auth.ts` / No — transitive only |
| **Exploit Available** | Yes — PoC published / No known exploit |
| **Actively Exploited** | Yes — in the wild / No |
| **Affected Versions** | `>= X.Y.Z, < A.B.C` |
| **Fixed Version** | `A.B.C` |
| **Fix Available** | ✅ Yes — upgrade to `A.B.C` / ❌ No fix yet |
| **Auto-Fixable** |`npm audit fix` / ❌ Manual intervention required |

**Description:**
[What the vulnerability allows an attacker to do.
How it could be exploited in the context of THIS project.]

**Impact on This Project:**
[Specific to YOUR codebase — is the vulnerable function actually called? 
Is the attack vector reachable? What data is at risk?]

**Dependency Chain:**

your-project └── [direct-dependency]@X.Y.Z └── [vulnerable-package]@A.B.C ← VULNERABLE

Weekly Installs
4
First Seen
6 days ago
Installed on
opencode4
gemini-cli4
antigravity4
claude-code4
github-copilot4
codex4