Files
desk-moloni/scripts/security_audit.sh
Emanuel Almeida c19f6fd9ee fix(perfexcrm module): align version to 3.0.1, unify entrypoint, and harden routes/views
- Bump DESK_MOLONI version to 3.0.1 across module
- Normalize hooks to after_client_* and instantiate PerfexHooks safely
- Fix OAuthController view path and API client class name
- Add missing admin views for webhook config/logs; adjust view loading
- Harden client portal routes and admin routes mapping
- Make Dashboard/Logs/Queue tolerant to optional model methods
- Align log details query with existing schema; avoid broken joins

This makes the module operational in Perfex (admin + client), reduces 404s,
and avoids fatal errors due to inconsistent tables/methods.
2025-09-11 17:38:45 +01:00

449 lines
16 KiB
Bash

#!/bin/bash
# Desk-Moloni v3.0 Security Audit Script
# Author: Descomplicar.pt
# Version: 3.0.0
# License: Commercial
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULE_DIR="$(dirname "$SCRIPT_DIR")"
REPORT_FILE="/tmp/desk-moloni-security-audit-$(date +%Y%m%d-%H%M%S).txt"
CRITICAL_ISSUES=0
HIGH_ISSUES=0
MEDIUM_ISSUES=0
LOW_ISSUES=0
# Functions
log() {
echo -e "${GREEN}[AUDIT]${NC} $1" | tee -a "$REPORT_FILE"
}
critical() {
echo -e "${RED}[CRITICAL]${NC} $1" | tee -a "$REPORT_FILE"
((CRITICAL_ISSUES++))
}
high() {
echo -e "${RED}[HIGH]${NC} $1" | tee -a "$REPORT_FILE"
((HIGH_ISSUES++))
}
medium() {
echo -e "${YELLOW}[MEDIUM]${NC} $1" | tee -a "$REPORT_FILE"
((MEDIUM_ISSUES++))
}
low() {
echo -e "${BLUE}[LOW]${NC} $1" | tee -a "$REPORT_FILE"
((LOW_ISSUES++))
}
pass() {
echo -e "${GREEN}[PASS]${NC} $1" | tee -a "$REPORT_FILE"
}
# Security audit banner
echo "========================================================================"
echo " DESK-MOLONI v3.0 SECURITY AUDIT"
echo "========================================================================"
echo "Report File: $REPORT_FILE"
echo "Audit Date: $(date)"
echo ""
log "Starting comprehensive security audit..."
# 1. File Permissions Audit
echo ""
log "=== FILE PERMISSIONS AUDIT ==="
# Check file permissions
WRITABLE_FILES=$(find "$MODULE_DIR" -type f -perm /o+w 2>/dev/null | wc -l)
if [[ $WRITABLE_FILES -gt 0 ]]; then
high "Found $WRITABLE_FILES world-writable files"
find "$MODULE_DIR" -type f -perm /o+w | head -10 | while read file; do
echo " - $file" | tee -a "$REPORT_FILE"
done
else
pass "No world-writable files found"
fi
# Check directory permissions
WRITABLE_DIRS=$(find "$MODULE_DIR" -type d -perm /o+w 2>/dev/null | grep -v "/uploads/" | wc -l)
if [[ $WRITABLE_DIRS -gt 0 ]]; then
medium "Found $WRITABLE_DIRS world-writable directories (excluding uploads)"
find "$MODULE_DIR" -type d -perm /o+w | grep -v "/uploads/" | head -5 | while read dir; do
echo " - $dir" | tee -a "$REPORT_FILE"
done
else
pass "Directory permissions are secure"
fi
# Check for executable PHP files in web-accessible locations
EXECUTABLE_PHP=$(find "$MODULE_DIR" -name "*.php" -path "*/assets/*" -o -name "*.php" -path "*/uploads/*" 2>/dev/null | wc -l)
if [[ $EXECUTABLE_PHP -gt 0 ]]; then
critical "Found PHP files in web-accessible directories"
find "$MODULE_DIR" -name "*.php" -path "*/assets/*" -o -name "*.php" -path "*/uploads/*" | while read file; do
echo " - $file" | tee -a "$REPORT_FILE"
done
else
pass "No PHP files in web-accessible directories"
fi
# 2. Configuration Security Audit
echo ""
log "=== CONFIGURATION SECURITY AUDIT ==="
# Check for hardcoded credentials
HARDCODED_CREDS=$(grep -r -i -E "(password|secret|key|token)" "$MODULE_DIR" --include="*.php" | grep -v "// " | grep -v "/\*" | grep -E "=['\"][^'\"]*['\"]" | wc -l)
if [[ $HARDCODED_CREDS -gt 0 ]]; then
high "Potential hardcoded credentials found"
grep -r -i -E "(password|secret|key|token)" "$MODULE_DIR" --include="*.php" | grep -v "// " | grep -v "/\*" | grep -E "=['\"][^'\"]*['\"]" | head -5 | while read line; do
echo " - $(echo $line | cut -d: -f1)" | tee -a "$REPORT_FILE"
done
else
pass "No hardcoded credentials detected"
fi
# Check encryption configuration
if [[ -f "$MODULE_DIR/libraries/Encryption.php" ]]; then
ENCRYPTION_CONFIG=$(grep -E "(AES-256|GCM)" "$MODULE_DIR/libraries/Encryption.php" | wc -l)
if [[ $ENCRYPTION_CONFIG -gt 0 ]]; then
pass "Strong encryption algorithm configured (AES-256-GCM)"
else
critical "Weak or no encryption algorithm configured"
fi
else
critical "Encryption library not found"
fi
# Check for debug mode in production
DEBUG_ENABLED=$(grep -r "debug.*true" "$MODULE_DIR/config/" 2>/dev/null | wc -l)
if [[ $DEBUG_ENABLED -gt 0 ]]; then
high "Debug mode appears to be enabled"
grep -r "debug.*true" "$MODULE_DIR/config/" | while read line; do
echo " - $line" | tee -a "$REPORT_FILE"
done
else
pass "Debug mode is disabled"
fi
# 3. Database Security Audit
echo ""
log "=== DATABASE SECURITY AUDIT ==="
# Check if database credentials are in environment variables
if [[ -f "$MODULE_DIR/../../.env" ]]; then
DB_IN_ENV=$(grep -E "DB_|DATABASE_" "$MODULE_DIR/../../.env" | wc -l)
if [[ $DB_IN_ENV -gt 0 ]]; then
pass "Database credentials found in environment file"
else
medium "Database credentials may not be in environment file"
fi
else
medium "Environment file (.env) not found"
fi
# Check for SQL injection patterns
SQL_PATTERNS=$(grep -r -E "\\\$.*\.(SELECT|INSERT|UPDATE|DELETE)" "$MODULE_DIR" --include="*.php" | grep -v "prepare" | wc -l)
if [[ $SQL_PATTERNS -gt 0 ]]; then
critical "Potential SQL injection vulnerabilities found"
grep -r -E "\\\$.*\.(SELECT|INSERT|UPDATE|DELETE)" "$MODULE_DIR" --include="*.php" | grep -v "prepare" | head -3 | while read line; do
echo " - $(echo $line | cut -d: -f1)" | tee -a "$REPORT_FILE"
done
else
pass "No obvious SQL injection patterns detected"
fi
# Check for encrypted storage configuration
ENCRYPTED_STORAGE=$(grep -r "encrypt" "$MODULE_DIR/config/" 2>/dev/null | wc -l)
if [[ $ENCRYPTED_STORAGE -gt 0 ]]; then
pass "Encryption configuration found"
else
medium "No encryption configuration detected"
fi
# 4. API Security Audit
echo ""
log "=== API SECURITY AUDIT ==="
# Check for OAuth 2.0 implementation
OAUTH_IMPL=$(find "$MODULE_DIR" -name "*.php" -exec grep -l "oauth\|OAuth" {} \; | wc -l)
if [[ $OAUTH_IMPL -gt 0 ]]; then
pass "OAuth implementation found"
# Check for PKCE implementation
PKCE_IMPL=$(grep -r "code_challenge\|code_verifier" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $PKCE_IMPL -gt 0 ]]; then
pass "PKCE (Proof Key for Code Exchange) implemented"
else
medium "PKCE not detected - consider implementing for enhanced security"
fi
else
critical "No OAuth implementation found"
fi
# Check for rate limiting
RATE_LIMIT=$(grep -r "rate.limit\|throttle" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $RATE_LIMIT -gt 0 ]]; then
pass "Rate limiting implementation found"
else
medium "No rate limiting detected"
fi
# Check for API key exposure
API_KEYS=$(grep -r -i "api.key\|client.secret" "$MODULE_DIR" --include="*.php" | grep -v "getenv\|env(" | wc -l)
if [[ $API_KEYS -gt 0 ]]; then
high "Potential API key exposure found"
grep -r -i "api.key\|client.secret" "$MODULE_DIR" --include="*.php" | grep -v "getenv\|env(" | head -3 | while read line; do
echo " - $(echo $line | cut -d: -f1)" | tee -a "$REPORT_FILE"
done
else
pass "No exposed API keys detected"
fi
# 5. Input Validation Audit
echo ""
log "=== INPUT VALIDATION AUDIT ==="
# Check for input sanitization
SANITIZATION=$(grep -r "filter_var\|htmlspecialchars\|strip_tags" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $SANITIZATION -gt 0 ]]; then
pass "Input sanitization functions found"
else
high "Limited input sanitization detected"
fi
# Check for CSRF protection
CSRF_PROTECTION=$(grep -r "csrf\|token" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $CSRF_PROTECTION -gt 0 ]]; then
pass "CSRF protection implementation found"
else
high "No CSRF protection detected"
fi
# Check for XSS protection
XSS_PROTECTION=$(grep -r "htmlentities\|htmlspecialchars" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $XSS_PROTECTION -gt 0 ]]; then
pass "XSS protection functions found"
else
medium "Limited XSS protection detected"
fi
# 6. Session Security Audit
echo ""
log "=== SESSION SECURITY AUDIT ==="
# Check for secure session configuration
SESSION_CONFIG=$(grep -r "session_" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $SESSION_CONFIG -gt 0 ]]; then
pass "Session configuration found"
# Check for secure session settings
SECURE_SESSION=$(grep -r "session_set_cookie_params.*secure\|httponly" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $SECURE_SESSION -gt 0 ]]; then
pass "Secure session settings detected"
else
medium "Consider implementing secure session cookie settings"
fi
else
low "No session configuration detected"
fi
# 7. Error Handling Audit
echo ""
log "=== ERROR HANDLING AUDIT ==="
# Check for error suppression
ERROR_SUPPRESSION=$(grep -r "@.*(" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $ERROR_SUPPRESSION -gt 0 ]]; then
medium "Error suppression found - may hide security issues"
grep -r "@.*(" "$MODULE_DIR" --include="*.php" | head -3 | while read line; do
echo " - $(echo $line | cut -d: -f1)" | tee -a "$REPORT_FILE"
done
else
pass "No error suppression detected"
fi
# Check for proper error logging
ERROR_LOGGING=$(grep -r "error_log\|log_message" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $ERROR_LOGGING -gt 0 ]]; then
pass "Error logging implementation found"
else
medium "Limited error logging detected"
fi
# 8. File Upload Security Audit
echo ""
log "=== FILE UPLOAD SECURITY AUDIT ==="
# Check for file upload functionality
FILE_UPLOAD=$(grep -r "move_uploaded_file\|upload" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $FILE_UPLOAD -gt 0 ]]; then
medium "File upload functionality detected"
# Check for file type validation
FILE_VALIDATION=$(grep -r "mime\|extension\|pathinfo" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $FILE_VALIDATION -gt 0 ]]; then
pass "File validation implementation found"
else
critical "No file validation detected for uploads"
fi
# Check for file size limits
SIZE_LIMITS=$(grep -r "filesize\|MAX_FILE_SIZE" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $SIZE_LIMITS -gt 0 ]]; then
pass "File size validation found"
else
medium "No file size limits detected"
fi
else
pass "No file upload functionality detected"
fi
# 9. Logging and Monitoring Audit
echo ""
log "=== LOGGING AND MONITORING AUDIT ==="
# Check for audit logging
AUDIT_LOGGING=$(find "$MODULE_DIR" -name "*log*" -type f | wc -l)
if [[ $AUDIT_LOGGING -gt 0 ]]; then
pass "Logging files found"
else
medium "No log files detected"
fi
# Check for security event logging
SECURITY_LOGGING=$(grep -r "SECURITY\|AUTH\|LOGIN" "$MODULE_DIR" --include="*.php" | wc -l)
if [[ $SECURITY_LOGGING -gt 0 ]]; then
pass "Security event logging found"
else
medium "Limited security event logging"
fi
# 10. Dependency Security Audit
echo ""
log "=== DEPENDENCY SECURITY AUDIT ==="
# Check for composer.json
if [[ -f "$MODULE_DIR/composer.json" ]]; then
pass "Composer dependencies file found"
# Check for security-related packages
SECURITY_PACKAGES=$(grep -E "(security|auth|encrypt)" "$MODULE_DIR/composer.json" | wc -l)
if [[ $SECURITY_PACKAGES -gt 0 ]]; then
pass "Security-related packages detected"
else
low "Consider adding security-focused packages"
fi
else
medium "No composer.json found - manual dependency management"
fi
# Check for outdated dependencies (if composer is available)
if command -v composer > /dev/null 2>&1 && [[ -f "$MODULE_DIR/composer.json" ]]; then
cd "$MODULE_DIR"
OUTDATED=$(composer outdated --direct 2>/dev/null | wc -l)
if [[ $OUTDATED -gt 0 ]]; then
medium "$OUTDATED outdated dependencies detected"
else
pass "Dependencies are up to date"
fi
fi
# Generate Security Score
echo ""
log "=== SECURITY AUDIT SUMMARY ==="
TOTAL_ISSUES=$((CRITICAL_ISSUES + HIGH_ISSUES + MEDIUM_ISSUES + LOW_ISSUES))
TOTAL_CHECKS=50 # Approximate number of security checks
if [[ $CRITICAL_ISSUES -gt 0 ]]; then
SECURITY_GRADE="F"
SECURITY_SCORE=0
elif [[ $HIGH_ISSUES -gt 3 ]]; then
SECURITY_GRADE="D"
SECURITY_SCORE=25
elif [[ $HIGH_ISSUES -gt 0 || $MEDIUM_ISSUES -gt 5 ]]; then
SECURITY_GRADE="C"
SECURITY_SCORE=50
elif [[ $MEDIUM_ISSUES -gt 2 || $LOW_ISSUES -gt 5 ]]; then
SECURITY_GRADE="B"
SECURITY_SCORE=75
else
SECURITY_GRADE="A"
SECURITY_SCORE=90
fi
echo "┌─────────────────────────────────────────────────────────────────────────────┐" | tee -a "$REPORT_FILE"
echo "│ SECURITY AUDIT REPORT │" | tee -a "$REPORT_FILE"
echo "├─────────────────────────────────────────────────────────────────────────────┤" | tee -a "$REPORT_FILE"
echo "│ Module: Desk-Moloni v3.0 │" | tee -a "$REPORT_FILE"
echo "│ Audit Date: $(date)" | tee -a "$REPORT_FILE"
echo "│ Report File: $REPORT_FILE" | tee -a "$REPORT_FILE"
echo "├─────────────────────────────────────────────────────────────────────────────┤" | tee -a "$REPORT_FILE"
printf "│ Security Grade: %-10s │ Security Score: %-10s │ Total Issues: %-6s │\n" "$SECURITY_GRADE" "${SECURITY_SCORE}%" "$TOTAL_ISSUES" | tee -a "$REPORT_FILE"
echo "├─────────────────────────────────────────────────────────────────────────────┤" | tee -a "$REPORT_FILE"
printf "│ Critical Issues: %-5s │ High Issues: %-5s │ Medium Issues: %-5s │\n" "$CRITICAL_ISSUES" "$HIGH_ISSUES" "$MEDIUM_ISSUES" | tee -a "$REPORT_FILE"
printf "│ Low Issues: %-10s │ Total Checks: %-8s │ Pass Rate: %-6s │\n" "$LOW_ISSUES" "$TOTAL_CHECKS" "$(((TOTAL_CHECKS - TOTAL_ISSUES) * 100 / TOTAL_CHECKS))%" | tee -a "$REPORT_FILE"
echo "└─────────────────────────────────────────────────────────────────────────────┘" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
# Recommendations
echo "SECURITY RECOMMENDATIONS:" | tee -a "$REPORT_FILE"
echo "=========================" | tee -a "$REPORT_FILE"
if [[ $CRITICAL_ISSUES -gt 0 ]]; then
echo "🚨 CRITICAL: Address all critical issues immediately before production deployment" | tee -a "$REPORT_FILE"
fi
if [[ $HIGH_ISSUES -gt 0 ]]; then
echo "⚠️ HIGH: Resolve high-priority security issues within 24 hours" | tee -a "$REPORT_FILE"
fi
if [[ $MEDIUM_ISSUES -gt 0 ]]; then
echo "📋 MEDIUM: Address medium-priority issues within 1 week" | tee -a "$REPORT_FILE"
fi
if [[ $SECURITY_GRADE == "A" ]]; then
echo "✅ EXCELLENT: Security posture is excellent. Continue regular audits." | tee -a "$REPORT_FILE"
elif [[ $SECURITY_GRADE == "B" ]]; then
echo "✅ GOOD: Security posture is good. Address remaining issues." | tee -a "$REPORT_FILE"
elif [[ $SECURITY_GRADE == "C" ]]; then
echo "⚠️ FAIR: Security needs improvement. Priority fixes required." | tee -a "$REPORT_FILE"
else
echo "🚨 POOR: Security posture requires immediate attention." | tee -a "$REPORT_FILE"
fi
echo "" | tee -a "$REPORT_FILE"
echo "Next Steps:" | tee -a "$REPORT_FILE"
echo "1. Review and address all critical and high-priority issues" | tee -a "$REPORT_FILE"
echo "2. Implement additional security measures as recommended" | tee -a "$REPORT_FILE"
echo "3. Schedule regular security audits (monthly recommended)" | tee -a "$REPORT_FILE"
echo "4. Consider professional penetration testing" | tee -a "$REPORT_FILE"
echo "5. Keep dependencies updated and monitor for vulnerabilities" | tee -a "$REPORT_FILE"
echo ""
echo "========================================================================"
echo "Security audit completed. Report saved to: $REPORT_FILE"
echo "Security Grade: $SECURITY_GRADE | Score: ${SECURITY_SCORE}% | Issues: $TOTAL_ISSUES"
echo "========================================================================"
# Exit with error code if critical issues found
if [[ $CRITICAL_ISSUES -gt 0 ]]; then
exit 1
elif [[ $HIGH_ISSUES -gt 0 ]]; then
exit 2
else
exit 0
fi