Loading...
Scans for potential sensitive data exposure and alerts immediately
{
"hookConfig": {
"hooks": {
"notification": {
"script": "./.claude/hooks/sensitive-data-alert-scanner.sh",
"matchers": [
"*"
]
}
}
},
"scriptContent": "#!/bin/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# Only scan for Write and Edit operations\nif [[ \"$TOOL_NAME\" != \"Write\" && \"$TOOL_NAME\" != \"Edit\" ]]; then\n exit 0\nfi\n\necho \"đ Sensitive Data Alert Scanner - Analyzing file for security risks...\"\necho \"đ File: $FILE_PATH\"\n\n# Check if file exists and is readable\nif [ ! -f \"$FILE_PATH\" ]; then\n echo \"â ī¸ File not found: $FILE_PATH\"\n exit 0\nfi\n\n# Skip binary files\nif file \"$FILE_PATH\" | grep -q binary; then\n echo \"âšī¸ Skipping binary file\"\n exit 0\nfi\n\nSECURITY_ISSUES=0\nWARNINGS=0\n\necho \"đ Scanning for sensitive data patterns...\"\n\n# 1. API Keys and Secrets\necho \"đ Checking for API keys and secrets...\"\nAPI_PATTERNS=(\n \"api[_-]?key\\s*[:=]\\s*[\\\"'][^\\\"']{8,}[\\\"']\"\n \"secret[_-]?key\\s*[:=]\\s*[\\\"'][^\\\"']{8,}[\\\"']\"\n \"access[_-]?token\\s*[:=]\\s*[\\\"'][^\\\"']{10,}[\\\"']\"\n \"private[_-]?key\\s*[:=]\\s*[\\\"'][^\\\"']{20,}[\\\"']\"\n \"client[_-]?secret\\s*[:=]\\s*[\\\"'][^\\\"']{8,}[\\\"']\"\n)\n\nfor pattern in \"${API_PATTERNS[@]}\"; do\n if grep -iE \"$pattern\" \"$FILE_PATH\" 2>/dev/null | grep -v -iE \"(\\*\\*\\*|example|placeholder|your[_-]|demo|test|fake|dummy)\"; then\n echo \"đ¨ SECURITY ALERT: Potential API key/secret detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\n fi\ndone\n\n# 2. Password patterns\necho \"đ Checking for password exposure...\"\nPASSWORD_PATTERNS=(\n \"password\\s*[:=]\\s*[\\\"'][^\\\"']{6,}[\\\"']\"\n \"passwd\\s*[:=]\\s*[\\\"'][^\\\"']{6,}[\\\"']\"\n \"pwd\\s*[:=]\\s*[\\\"'][^\\\"']{6,}[\\\"']\"\n)\n\nfor pattern in \"${PASSWORD_PATTERNS[@]}\"; do\n if grep -iE \"$pattern\" \"$FILE_PATH\" 2>/dev/null | grep -v -iE \"(\\*\\*\\*|example|placeholder|your[_-]|demo|test|123456|password)\"; then\n echo \"đ¨ SECURITY ALERT: Potential password detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\n fi\ndone\n\n# 3. Database connection strings\necho \"đī¸ Checking for database credentials...\"\nif grep -iE \"(mysql://|postgresql://|mongodb://|redis://).*:.*@\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"đ¨ SECURITY ALERT: Database connection string with credentials detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\nfi\n\n# 4. JWT tokens\necho \"đĢ Checking for JWT tokens...\"\nif grep -E \"eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"đ¨ SECURITY ALERT: JWT token detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\nfi\n\n# 5. SSH private keys\necho \"đ Checking for SSH private keys...\"\nif grep -q \"BEGIN.*PRIVATE KEY\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"đ¨ SECURITY ALERT: SSH private key detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\nfi\n\n# 6. Email addresses (warning, not critical)\necho \"đ§ Checking for email addresses...\"\nif grep -E \"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\" \"$FILE_PATH\" 2>/dev/null | head -3; then\n echo \"â ī¸ Email addresses detected - ensure this is intentional\"\n WARNINGS=$((WARNINGS + 1))\nfi\n\n# 7. Credit card patterns (basic check)\necho \"đŗ Checking for credit card numbers...\"\nif grep -E \"[0-9]{4}[\\s-]?[0-9]{4}[\\s-]?[0-9]{4}[\\s-]?[0-9]{4}\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"đ¨ SECURITY ALERT: Potential credit card number detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\nfi\n\n# 8. Social Security Numbers (US format)\necho \"đ Checking for SSN patterns...\"\nif grep -E \"[0-9]{3}-[0-9]{2}-[0-9]{4}\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"đ¨ SECURITY ALERT: Potential SSN detected!\"\n SECURITY_ISSUES=$((SECURITY_ISSUES + 1))\nfi\n\n# 9. Phone numbers\necho \"đ Checking for phone numbers...\"\nif grep -E \"\\+?[1-9][0-9]{1,3}[\\s-]?\\(?[0-9]{3}\\)?[\\s-]?[0-9]{3}[\\s-]?[0-9]{4}\" \"$FILE_PATH\" 2>/dev/null; then\n echo \"â ī¸ Phone numbers detected - verify if intentional\"\n WARNINGS=$((WARNINGS + 1))\nfi\n\n# Summary\necho \"\"\necho \"đ Security Scan Results:\"\necho \" âĸ Critical Issues: $SECURITY_ISSUES\"\necho \" âĸ Warnings: $WARNINGS\"\n\nif [ $SECURITY_ISSUES -gt 0 ]; then\n echo \"\"\n echo \"đ¨ CRITICAL SECURITY ALERT!\"\n echo \"đĄī¸ Action Required:\"\n echo \" âĸ Review detected sensitive data immediately\"\n echo \" âĸ Remove or mask sensitive information\"\n echo \" âĸ Use environment variables for secrets\"\n echo \" âĸ Consider using a secrets management service\"\n echo \" âĸ Check if file should be added to .gitignore\"\nfi\n\nif [ $WARNINGS -gt 0 ]; then\n echo \"\"\n echo \"â ī¸ Security Warnings:\"\n echo \" âĸ Review detected information for necessity\"\n echo \" âĸ Consider data privacy implications\"\n echo \" âĸ Verify compliance with data protection regulations\"\nfi\n\necho \"\"\necho \"đĄ Security Best Practices:\"\necho \" âĸ Use environment variables for sensitive data\"\necho \" âĸ Implement proper secrets management\"\necho \" âĸ Add sensitive files to .gitignore\"\necho \" âĸ Regular security audits of codebase\"\necho \" âĸ Use code scanning tools in CI/CD\"\n\necho \"\"\necho \"đ¯ Security scan complete!\"\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"notification": {
"script": "./.claude/hooks/sensitive-data-alert-scanner.sh",
"matchers": [
"*"
]
}
}
}#!/bin/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
# Only scan for Write and Edit operations
if [[ "$TOOL_NAME" != "Write" && "$TOOL_NAME" != "Edit" ]]; then
exit 0
fi
echo "đ Sensitive Data Alert Scanner - Analyzing file for security risks..."
echo "đ File: $FILE_PATH"
# Check if file exists and is readable
if [ ! -f "$FILE_PATH" ]; then
echo "â ī¸ File not found: $FILE_PATH"
exit 0
fi
# Skip binary files
if file "$FILE_PATH" | grep -q binary; then
echo "âšī¸ Skipping binary file"
exit 0
fi
SECURITY_ISSUES=0
WARNINGS=0
echo "đ Scanning for sensitive data patterns..."
# 1. API Keys and Secrets
echo "đ Checking for API keys and secrets..."
API_PATTERNS=(
"api[_-]?key\s*[:=]\s*[\"'][^\"']{8,}[\"']"
"secret[_-]?key\s*[:=]\s*[\"'][^\"']{8,}[\"']"
"access[_-]?token\s*[:=]\s*[\"'][^\"']{10,}[\"']"
"private[_-]?key\s*[:=]\s*[\"'][^\"']{20,}[\"']"
"client[_-]?secret\s*[:=]\s*[\"'][^\"']{8,}[\"']"
)
for pattern in "${API_PATTERNS[@]}"; do
if grep -iE "$pattern" "$FILE_PATH" 2>/dev/null | grep -v -iE "(\*\*\*|example|placeholder|your[_-]|demo|test|fake|dummy)"; then
echo "đ¨ SECURITY ALERT: Potential API key/secret detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
done
# 2. Password patterns
echo "đ Checking for password exposure..."
PASSWORD_PATTERNS=(
"password\s*[:=]\s*[\"'][^\"']{6,}[\"']"
"passwd\s*[:=]\s*[\"'][^\"']{6,}[\"']"
"pwd\s*[:=]\s*[\"'][^\"']{6,}[\"']"
)
for pattern in "${PASSWORD_PATTERNS[@]}"; do
if grep -iE "$pattern" "$FILE_PATH" 2>/dev/null | grep -v -iE "(\*\*\*|example|placeholder|your[_-]|demo|test|123456|password)"; then
echo "đ¨ SECURITY ALERT: Potential password detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
done
# 3. Database connection strings
echo "đī¸ Checking for database credentials..."
if grep -iE "(mysql://|postgresql://|mongodb://|redis://).*:.*@" "$FILE_PATH" 2>/dev/null; then
echo "đ¨ SECURITY ALERT: Database connection string with credentials detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
# 4. JWT tokens
echo "đĢ Checking for JWT tokens..."
if grep -E "eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+" "$FILE_PATH" 2>/dev/null; then
echo "đ¨ SECURITY ALERT: JWT token detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
# 5. SSH private keys
echo "đ Checking for SSH private keys..."
if grep -q "BEGIN.*PRIVATE KEY" "$FILE_PATH" 2>/dev/null; then
echo "đ¨ SECURITY ALERT: SSH private key detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
# 6. Email addresses (warning, not critical)
echo "đ§ Checking for email addresses..."
if grep -E "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}" "$FILE_PATH" 2>/dev/null | head -3; then
echo "â ī¸ Email addresses detected - ensure this is intentional"
WARNINGS=$((WARNINGS + 1))
fi
# 7. Credit card patterns (basic check)
echo "đŗ Checking for credit card numbers..."
if grep -E "[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}" "$FILE_PATH" 2>/dev/null; then
echo "đ¨ SECURITY ALERT: Potential credit card number detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
# 8. Social Security Numbers (US format)
echo "đ Checking for SSN patterns..."
if grep -E "[0-9]{3}-[0-9]{2}-[0-9]{4}" "$FILE_PATH" 2>/dev/null; then
echo "đ¨ SECURITY ALERT: Potential SSN detected!"
SECURITY_ISSUES=$((SECURITY_ISSUES + 1))
fi
# 9. Phone numbers
echo "đ Checking for phone numbers..."
if grep -E "\+?[1-9][0-9]{1,3}[\s-]?\(?[0-9]{3}\)?[\s-]?[0-9]{3}[\s-]?[0-9]{4}" "$FILE_PATH" 2>/dev/null; then
echo "â ī¸ Phone numbers detected - verify if intentional"
WARNINGS=$((WARNINGS + 1))
fi
# Summary
echo ""
echo "đ Security Scan Results:"
echo " âĸ Critical Issues: $SECURITY_ISSUES"
echo " âĸ Warnings: $WARNINGS"
if [ $SECURITY_ISSUES -gt 0 ]; then
echo ""
echo "đ¨ CRITICAL SECURITY ALERT!"
echo "đĄī¸ Action Required:"
echo " âĸ Review detected sensitive data immediately"
echo " âĸ Remove or mask sensitive information"
echo " âĸ Use environment variables for secrets"
echo " âĸ Consider using a secrets management service"
echo " âĸ Check if file should be added to .gitignore"
fi
if [ $WARNINGS -gt 0 ]; then
echo ""
echo "â ī¸ Security Warnings:"
echo " âĸ Review detected information for necessity"
echo " âĸ Consider data privacy implications"
echo " âĸ Verify compliance with data protection regulations"
fi
echo ""
echo "đĄ Security Best Practices:"
echo " âĸ Use environment variables for sensitive data"
echo " âĸ Implement proper secrets management"
echo " âĸ Add sensitive files to .gitignore"
echo " âĸ Regular security audits of codebase"
echo " âĸ Use code scanning tools in CI/CD"
echo ""
echo "đ¯ Security scan complete!"
exit 0False positives on example code and test fixtures with dummy keys
Exclusion patterns filter common placeholders but miss context-specific ones. Add .securityignore file and check: grep -qF "$FILE_PATH" .securityignore && exit 0 to whitelist specific files or patterns.
Notification hook timing runs before file write completes causing empty scans
Notification hooks fire during operation, not after. File may not exist yet. Add retry loop: for i in {1..5}; do [ -f "$FILE_PATH" ] && break; sleep 0.1; done before scanning to ensure file availability.
Notification hook receives different INPUT schema than PostToolUse
Notification hooks fire mid-operation with partial data. Input may lack file_path or use alternative fields. Extend jq filter: '.file_path // .tool_input.file_path // .path // ""' to handle schema variations across hook types.
Grep patterns match commented-out secrets in code documentation
Current regex doesn't exclude comments. Add language-aware filtering: grep -v '^\s*[#/]' for basic comment detection, or use awk to skip comment blocks before pattern matching for comprehensive filtering.
Security scan exits zero even when critical issues detected
Script always exits 0 regardless of SECURITY_ISSUES count. Change final exit: [ $SECURITY_ISSUES -gt 0 ] && exit 1 || exit 0 to fail hook on findings, forcing Claude to acknowledge security alerts before proceeding.
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