Loading...
Real-time vulnerability scanning for dependencies with automated CVE detection, severity assessment, and patch recommendations
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/dependency-security-scanner.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/usr/bin/env bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Configuration\nSECURITY_REPORT=\".claude/reports/security-scan-$(date +%Y%m%d).txt\"\nSEVERITY_THRESHOLD=${SEVERITY_THRESHOLD:-medium}\n\nmkdir -p \"$(dirname \"$SECURITY_REPORT\")\"\n\n# Function to check if file is a dependency manifest\nis_dependency_file() {\n local file=$1\n \n case \"$(basename \"$file\")\" in\n package.json|package-lock.json|yarn.lock|pnpm-lock.yaml)\n echo \"npm\"\n return 0\n ;;\n requirements.txt|Pipfile|Pipfile.lock|poetry.lock)\n echo \"pip\"\n return 0\n ;;\n Cargo.toml|Cargo.lock)\n echo \"cargo\"\n return 0\n ;;\n go.mod|go.sum)\n echo \"go\"\n return 0\n ;;\n Gemfile|Gemfile.lock)\n echo \"bundler\"\n return 0\n ;;\n composer.json|composer.lock)\n echo \"composer\"\n return 0\n ;;\n *)\n return 1\n ;;\n esac\n}\n\n# Function to run npm audit\nscan_npm_dependencies() {\n echo \"📦 Scanning npm dependencies for vulnerabilities...\" >&2\n \n if ! command -v npm &> /dev/null; then\n echo \"⚠️ npm not found - install Node.js for security scanning\" >&2\n return\n fi\n \n echo \"\" >> \"$SECURITY_REPORT\"\n echo \"NPM Audit Report - $(date)\" >> \"$SECURITY_REPORT\"\n echo \"================================\" >> \"$SECURITY_REPORT\"\n \n # Run npm audit\n AUDIT_OUTPUT=$(npm audit --json 2>/dev/null)\n \n if [ -n \"$AUDIT_OUTPUT\" ]; then\n # Parse vulnerabilities\n CRITICAL=$(echo \"$AUDIT_OUTPUT\" | jq -r '.metadata.vulnerabilities.critical // 0')\n HIGH=$(echo \"$AUDIT_OUTPUT\" | jq -r '.metadata.vulnerabilities.high // 0')\n MODERATE=$(echo \"$AUDIT_OUTPUT\" | jq -r '.metadata.vulnerabilities.moderate // 0')\n LOW=$(echo \"$AUDIT_OUTPUT\" | jq -r '.metadata.vulnerabilities.low // 0')\n \n echo \"Critical: $CRITICAL | High: $HIGH | Moderate: $MODERATE | Low: $LOW\" >> \"$SECURITY_REPORT\"\n \n # Alert on critical/high vulnerabilities\n if [ \"$CRITICAL\" -gt 0 ] || [ \"$HIGH\" -gt 0 ]; then\n echo \"\" >&2\n echo \"🚨 SECURITY ALERT: Critical or High severity vulnerabilities detected!\" >&2\n echo \" Critical: $CRITICAL vulnerabilities\" >&2\n echo \" High: $HIGH vulnerabilities\" >&2\n echo \"\" >&2\n echo \"🔧 Run 'npm audit fix' to automatically fix vulnerabilities\" >&2\n echo \"🔧 Run 'npm audit fix --force' for breaking changes\" >&2\n fi\n \n # Get fixable vulnerabilities\n FIXABLE=$(echo \"$AUDIT_OUTPUT\" | jq -r '.metadata.vulnerabilities.info // 0')\n if [ \"$FIXABLE\" -gt 0 ]; then\n echo \"💡 $FIXABLE vulnerabilities can be fixed automatically\" >&2\n fi\n else\n echo \"✅ No vulnerabilities detected\" >> \"$SECURITY_REPORT\"\n fi\n}\n\n# Function to scan Python dependencies\nscan_pip_dependencies() {\n echo \"🐍 Scanning Python dependencies for vulnerabilities...\" >&2\n \n if command -v safety &> /dev/null; then\n echo \"\" >> \"$SECURITY_REPORT\"\n echo \"Python Safety Report - $(date)\" >> \"$SECURITY_REPORT\"\n echo \"=================================\" >> \"$SECURITY_REPORT\"\n \n safety check --json 2>/dev/null | \\\n jq -r '.[] | \"\\(.package): \\(.vulnerability)\"' 2>/dev/null >> \"$SECURITY_REPORT\" || \\\n echo \"✅ No vulnerabilities detected\" >> \"$SECURITY_REPORT\"\n elif command -v pip-audit &> /dev/null; then\n echo \"Running pip-audit...\" >&2\n pip-audit --format json 2>/dev/null >> \"$SECURITY_REPORT\" || \\\n echo \"💡 Install pip-audit: pip install pip-audit\" >&2\n else\n echo \"💡 Install safety or pip-audit for Python security scanning\" >&2\n fi\n}\n\n# Function to scan Rust dependencies\nscan_cargo_dependencies() {\n echo \"🦀 Scanning Rust dependencies for vulnerabilities...\" >&2\n \n if command -v cargo &> /dev/null; then\n if cargo audit --version &> /dev/null; then\n echo \"\" >> \"$SECURITY_REPORT\"\n echo \"Cargo Audit Report - $(date)\" >> \"$SECURITY_REPORT\"\n echo \"==============================\" >> \"$SECURITY_REPORT\"\n \n cargo audit --json 2>/dev/null >> \"$SECURITY_REPORT\" || \\\n echo \"✅ No vulnerabilities detected\" >> \"$SECURITY_REPORT\"\n else\n echo \"💡 Install cargo-audit: cargo install cargo-audit\" >&2\n fi\n fi\n}\n\n# Function to scan Go dependencies\nscan_go_dependencies() {\n echo \"🐹 Scanning Go dependencies for vulnerabilities...\" >&2\n \n if command -v govulncheck &> /dev/null; then\n echo \"\" >> \"$SECURITY_REPORT\"\n echo \"Go Vulnerability Check - $(date)\" >> \"$SECURITY_REPORT\"\n echo \"==================================\" >> \"$SECURITY_REPORT\"\n \n govulncheck ./... 2>/dev/null >> \"$SECURITY_REPORT\" || \\\n echo \"✅ No vulnerabilities detected\" >> \"$SECURITY_REPORT\"\n else\n echo \"💡 Install govulncheck: go install golang.org/x/vuln/cmd/govulncheck@latest\" >&2\n fi\n}\n\n# Main execution\nDEP_TYPE=$(is_dependency_file \"$FILE_PATH\")\n\nif [ -n \"$DEP_TYPE\" ]; then\n echo \"🔐 Security scan triggered: $FILE_PATH\" >&2\n echo \"📋 Dependency type: $DEP_TYPE\" >&2\n \n # Run appropriate scanner\n case \"$DEP_TYPE\" in\n npm)\n scan_npm_dependencies\n ;;\n pip)\n scan_pip_dependencies\n ;;\n cargo)\n scan_cargo_dependencies\n ;;\n go)\n scan_go_dependencies\n ;;\n *)\n echo \"💡 Security scanning available for: npm, pip, cargo, go\" >&2\n ;;\n esac\n \n # General security tips\n echo \"\" >&2\n echo \"🛡️ Dependency Security Best Practices:\" >&2\n echo \" • Keep dependencies updated regularly\" >&2\n echo \" • Review security advisories before updates\" >&2\n echo \" • Use lock files to ensure reproducible builds\" >&2\n echo \" • Minimize dependency count to reduce attack surface\" >&2\n echo \" • Enable automated security alerts in your repo\" >&2\n \n if [ -s \"$SECURITY_REPORT\" ]; then\n echo \"\" >&2\n echo \"📄 Security report: $SECURITY_REPORT\" >&2\n fi\nfi\n\nexit 0"
}
.claude/hooks/
~/.claude/hooks/
{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/dependency-security-scanner.sh",
"matchers": [
"write",
"edit"
]
}
}
}
#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Configuration
SECURITY_REPORT=".claude/reports/security-scan-$(date +%Y%m%d).txt"
SEVERITY_THRESHOLD=${SEVERITY_THRESHOLD:-medium}
mkdir -p "$(dirname "$SECURITY_REPORT")"
# Function to check if file is a dependency manifest
is_dependency_file() {
local file=$1
case "$(basename "$file")" in
package.json|package-lock.json|yarn.lock|pnpm-lock.yaml)
echo "npm"
return 0
;;
requirements.txt|Pipfile|Pipfile.lock|poetry.lock)
echo "pip"
return 0
;;
Cargo.toml|Cargo.lock)
echo "cargo"
return 0
;;
go.mod|go.sum)
echo "go"
return 0
;;
Gemfile|Gemfile.lock)
echo "bundler"
return 0
;;
composer.json|composer.lock)
echo "composer"
return 0
;;
*)
return 1
;;
esac
}
# Function to run npm audit
scan_npm_dependencies() {
echo "📦 Scanning npm dependencies for vulnerabilities..." >&2
if ! command -v npm &> /dev/null; then
echo "⚠️ npm not found - install Node.js for security scanning" >&2
return
fi
echo "" >> "$SECURITY_REPORT"
echo "NPM Audit Report - $(date)" >> "$SECURITY_REPORT"
echo "================================" >> "$SECURITY_REPORT"
# Run npm audit
AUDIT_OUTPUT=$(npm audit --json 2>/dev/null)
if [ -n "$AUDIT_OUTPUT" ]; then
# Parse vulnerabilities
CRITICAL=$(echo "$AUDIT_OUTPUT" | jq -r '.metadata.vulnerabilities.critical // 0')
HIGH=$(echo "$AUDIT_OUTPUT" | jq -r '.metadata.vulnerabilities.high // 0')
MODERATE=$(echo "$AUDIT_OUTPUT" | jq -r '.metadata.vulnerabilities.moderate // 0')
LOW=$(echo "$AUDIT_OUTPUT" | jq -r '.metadata.vulnerabilities.low // 0')
echo "Critical: $CRITICAL | High: $HIGH | Moderate: $MODERATE | Low: $LOW" >> "$SECURITY_REPORT"
# Alert on critical/high vulnerabilities
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "" >&2
echo "🚨 SECURITY ALERT: Critical or High severity vulnerabilities detected!" >&2
echo " Critical: $CRITICAL vulnerabilities" >&2
echo " High: $HIGH vulnerabilities" >&2
echo "" >&2
echo "🔧 Run 'npm audit fix' to automatically fix vulnerabilities" >&2
echo "🔧 Run 'npm audit fix --force' for breaking changes" >&2
fi
# Get fixable vulnerabilities
FIXABLE=$(echo "$AUDIT_OUTPUT" | jq -r '.metadata.vulnerabilities.info // 0')
if [ "$FIXABLE" -gt 0 ]; then
echo "💡 $FIXABLE vulnerabilities can be fixed automatically" >&2
fi
else
echo "✅ No vulnerabilities detected" >> "$SECURITY_REPORT"
fi
}
# Function to scan Python dependencies
scan_pip_dependencies() {
echo "🐍 Scanning Python dependencies for vulnerabilities..." >&2
if command -v safety &> /dev/null; then
echo "" >> "$SECURITY_REPORT"
echo "Python Safety Report - $(date)" >> "$SECURITY_REPORT"
echo "=================================" >> "$SECURITY_REPORT"
safety check --json 2>/dev/null | \
jq -r '.[] | "\(.package): \(.vulnerability)"' 2>/dev/null >> "$SECURITY_REPORT" || \
echo "✅ No vulnerabilities detected" >> "$SECURITY_REPORT"
elif command -v pip-audit &> /dev/null; then
echo "Running pip-audit..." >&2
pip-audit --format json 2>/dev/null >> "$SECURITY_REPORT" || \
echo "💡 Install pip-audit: pip install pip-audit" >&2
else
echo "💡 Install safety or pip-audit for Python security scanning" >&2
fi
}
# Function to scan Rust dependencies
scan_cargo_dependencies() {
echo "🦀 Scanning Rust dependencies for vulnerabilities..." >&2
if command -v cargo &> /dev/null; then
if cargo audit --version &> /dev/null; then
echo "" >> "$SECURITY_REPORT"
echo "Cargo Audit Report - $(date)" >> "$SECURITY_REPORT"
echo "==============================" >> "$SECURITY_REPORT"
cargo audit --json 2>/dev/null >> "$SECURITY_REPORT" || \
echo "✅ No vulnerabilities detected" >> "$SECURITY_REPORT"
else
echo "💡 Install cargo-audit: cargo install cargo-audit" >&2
fi
fi
}
# Function to scan Go dependencies
scan_go_dependencies() {
echo "🐹 Scanning Go dependencies for vulnerabilities..." >&2
if command -v govulncheck &> /dev/null; then
echo "" >> "$SECURITY_REPORT"
echo "Go Vulnerability Check - $(date)" >> "$SECURITY_REPORT"
echo "==================================" >> "$SECURITY_REPORT"
govulncheck ./... 2>/dev/null >> "$SECURITY_REPORT" || \
echo "✅ No vulnerabilities detected" >> "$SECURITY_REPORT"
else
echo "💡 Install govulncheck: go install golang.org/x/vuln/cmd/govulncheck@latest" >&2
fi
}
# Main execution
DEP_TYPE=$(is_dependency_file "$FILE_PATH")
if [ -n "$DEP_TYPE" ]; then
echo "🔐 Security scan triggered: $FILE_PATH" >&2
echo "📋 Dependency type: $DEP_TYPE" >&2
# Run appropriate scanner
case "$DEP_TYPE" in
npm)
scan_npm_dependencies
;;
pip)
scan_pip_dependencies
;;
cargo)
scan_cargo_dependencies
;;
go)
scan_go_dependencies
;;
*)
echo "💡 Security scanning available for: npm, pip, cargo, go" >&2
;;
esac
# General security tips
echo "" >&2
echo "🛡️ Dependency Security Best Practices:" >&2
echo " • Keep dependencies updated regularly" >&2
echo " • Review security advisories before updates" >&2
echo " • Use lock files to ensure reproducible builds" >&2
echo " • Minimize dependency count to reduce attack surface" >&2
echo " • Enable automated security alerts in your repo" >&2
if [ -s "$SECURITY_REPORT" ]; then
echo "" >&2
echo "📄 Security report: $SECURITY_REPORT" >&2
fi
fi
exit 0
PostToolUse hook triggers but npm audit shows empty results
Ensure package-lock.json exists (run npm install first). Check npm version supports audit (npm 6+). Verify network connectivity for CVE database access. Try npm audit --registry=https://registry.npmjs.org.
Critical vulnerabilities reported but npm audit fix fails
Breaking changes require --force flag but review impact first. Check if vulnerability is in transitive dependency requiring upstream fix. Pin vulnerable package version with resolutions in package.json. Consider alternative packages.
Python safety check reports vulnerabilities in dev packages
Separate dev and prod requirements: safety check -r requirements.txt. Use --ignore to suppress false positives. Check if vulnerability affects your usage context. Update to patched versions in requirements.txt.
Security scan creates duplicate reports on each save
Hook runs on every write/edit matcher trigger. Implement debouncing with timestamp check. Use daily report files to prevent spam. Add file hash check to skip scans if content unchanged.
Cargo audit fails with index update errors in CI
Pre-download advisory database: cargo audit fetch in CI setup. Use offline mode if network restricted. Cache advisory-db directory between runs. Check firewall rules for https://github.com/rustsec access.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters