vulnerability-report
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:
YYYY-MM-DD-vulnerabilities-high.md— Critical and High severity (CVSS ≥ 7.0)YYYY-MM-DD-vulnerabilities-medium.md— Medium severity (CVSS 4.0–6.9)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
More from aakash-dhar/claude-skills
security-audit
Scans code for security vulnerabilities including injection attacks, authentication flaws, exposed secrets, insecure dependencies, and data exposure. Use when the user says "security review", "is this secure?", "check for vulnerabilities", "audit this", or before deploying to production.
118pentest-report
Generates a structured penetration testing report based on OWASP standards including OWASP Top 10, ASVS, and WSTG methodology. Scans code for vulnerabilities, maps findings to OWASP categories, assigns CVSS scores, and produces a professional pentest report. Use when the user says "pentest report", "penetration testing", "OWASP audit", "OWASP report", "security assessment", "vulnerability assessment", "application security test", or "OWASP compliance check".
18code-review
Reviews code for bugs, security issues, performance problems, and adherence to best practices. Use when the user asks to "review this code", "check my code", "is this code good?", or before submitting a PR.
4risk-register
Creates and maintains a living project risk register by analyzing the codebase, dependencies, team structure, timeline, and technical decisions. Identifies risks, scores them by likelihood and impact, assigns owners, tracks mitigations, and flags risks that have changed since last assessment. Saves output to project-decisions/ folder. Use when the user says "risk register", "project risks", "what could go wrong", "risk assessment", "identify risks", "update risks", "risk review", "what are our risks", or "flag risks for the project".
4tech-decision
Evaluates technical proposals, "should we do X instead of Y?" questions, tool comparisons, and architecture suggestions. Analyzes feasibility, compares options with structured pros/cons, estimates effort and risk, and provides a clear recommendation. Saves output to project-decisions/ folder. Use when the user says "should we", "what if we", "is it worth", "should we switch to", "compare X vs Y", "evaluate this proposal", "tech decision", or brings up a technical suggestion from a team discussion.
1incident-report
Generates structured incident postmortem reports by analyzing git history, recent deployments, code changes, logs, and error patterns. Produces a blameless postmortem with timeline, root cause analysis, impact assessment, remediation actions, and prevention measures. Saves output to project-decisions/ folder. Use when the user says "incident report", "postmortem", "what went wrong", "outage report", "root cause analysis", "RCA", "write a post-mortem", "incident review", "we had an incident", "production issue", or "site went down".
1