Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a303089e64 | |||
| b1437e1651 | |||
| ecde6dfe0c | |||
| 589abb6963 | |||
| 2ad6658f49 | |||
| 84d06b4744 | |||
| f07debf5c6 |
@@ -255,10 +255,11 @@ check_attack_pattern() {
|
||||
}
|
||||
|
||||
# Get all matching patterns across all categories
|
||||
# Usage: detect_all_attacks "$request_line"
|
||||
# Usage: detect_all_attack_signatures "$request_line"
|
||||
# Returns: max_severity|match_count|matches (space-separated)
|
||||
# Each match format: severity|category|pattern_name|description
|
||||
detect_all_attacks() {
|
||||
# Note: Renamed to avoid conflict with legacy detect_all_attacks in attack-patterns.sh
|
||||
detect_all_attack_signatures() {
|
||||
local request="$1"
|
||||
local matches=()
|
||||
local max_severity=0
|
||||
|
||||
@@ -43,7 +43,7 @@ Referer: $referer
|
||||
User-Agent: $user_agent"
|
||||
|
||||
# Detect attacks using signature database
|
||||
local attack_result=$(detect_all_attacks "$full_request" 2>/dev/null)
|
||||
local attack_result=$(detect_all_attack_signatures "$full_request" 2>/dev/null)
|
||||
|
||||
if [ -n "$attack_result" ]; then
|
||||
# Parse result: max_severity||match_count||matches...
|
||||
|
||||
@@ -1723,15 +1723,21 @@ monitor_apache_logs() {
|
||||
# Update IP intelligence with ET attack info
|
||||
update_ip_intelligence "$ip" "$url|ET:$et_attack_types|$et_signatures" "attack" "HTTP"
|
||||
|
||||
# Boost IP threat score based on ET detection
|
||||
# Replace IP threat score with ET detection score
|
||||
# Note: We use ET score instead of adding it to avoid double-counting
|
||||
# (update_ip_intelligence already detected the same attack via legacy patterns)
|
||||
local current_intel=$(get_ip_intelligence "$ip")
|
||||
IFS='|' read -r curr_score curr_hits curr_bot curr_attacks curr_ban curr_rep <<< "$current_intel"
|
||||
|
||||
# Add ET attack score to IP's total score
|
||||
local new_score=$((curr_score + et_attack_score))
|
||||
# Use ET score if it's higher than current score
|
||||
local new_score="$et_attack_score"
|
||||
if [ "$curr_score" -gt "$et_attack_score" ]; then
|
||||
# Keep higher score (e.g., from AbuseIPDB reputation boost)
|
||||
new_score="$curr_score"
|
||||
fi
|
||||
[ "$new_score" -gt 100 ] && new_score=100
|
||||
|
||||
# Update IP data with boosted score
|
||||
# Update IP data with ET-based score
|
||||
IP_DATA[$ip]="$new_score|$curr_hits|$curr_bot|$curr_attacks|$curr_ban|$curr_rep"
|
||||
|
||||
# Check rate anomaly
|
||||
@@ -1783,7 +1789,20 @@ monitor_apache_logs() {
|
||||
|
||||
# Show ET detection if found
|
||||
if [ "$et_attack_score" -gt 0 ]; then
|
||||
log_line+=" | 🛡️ET:$et_attack_types"
|
||||
# Show primary attack type (cleaner than full list)
|
||||
local primary_type=$(echo "$et_attack_types" | grep -oE 'SQLI|XSS|CMD|TRAVERSAL|WEBSHELL|RCE|UPLOAD|CVE' | head -1)
|
||||
if [ -z "$primary_type" ]; then
|
||||
primary_type=$(echo "$et_attack_types" | cut -d',' -f1)
|
||||
fi
|
||||
log_line+=" | 🛡️ET:$primary_type"
|
||||
|
||||
# Show signature names (the key improvement!)
|
||||
if [ -n "$et_signatures" ]; then
|
||||
# Limit to first 3 signatures to keep display clean
|
||||
local sig_display=$(echo "$et_signatures" | tr ',' '\n' | head -3 | tr '\n' ',' | sed 's/,$//')
|
||||
log_line+=" | Sigs:$sig_display"
|
||||
fi
|
||||
|
||||
# Show rate info if elevated
|
||||
if [ "$et_rate_score" -gt 0 ]; then
|
||||
log_line+=" | 🌊Rate:+$et_rate_score"
|
||||
|
||||
@@ -26,6 +26,9 @@ source "$SCRIPT_DIR/lib/http-attack-analyzer.sh" 2>/dev/null || {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Try to source IP reputation library (optional)
|
||||
source "$SCRIPT_DIR/lib/ip-reputation.sh" 2>/dev/null
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
@@ -148,13 +151,20 @@ MEDIUM_ATTACKS=0
|
||||
declare -A ATTACK_TYPES
|
||||
declare -A TOP_ATTACKERS
|
||||
declare -A SIGNATURE_HITS
|
||||
declare -A IP_ATTACK_DETAILS # Store detailed attack info per IP
|
||||
declare -A IP_ATTACK_COUNT # Count attacks per IP
|
||||
declare -A IP_SAMPLE_URLS # Sample URLs per IP
|
||||
|
||||
# Progress indicator
|
||||
show_progress() {
|
||||
count=$1
|
||||
total=$2
|
||||
percent=$((count * 100 / total))
|
||||
count=$1
|
||||
total=$2
|
||||
if [ "$total" = "unknown" ] || [ "$total" -eq 0 ] 2>/dev/null; then
|
||||
echo -ne "\r${BLUE}[*]${NC} Processing: $count lines... "
|
||||
else
|
||||
percent=$((count * 100 / total))
|
||||
echo -ne "\r${BLUE}[*]${NC} Processing: $count/$total lines ($percent%) "
|
||||
fi
|
||||
}
|
||||
|
||||
# Start analysis
|
||||
@@ -231,74 +241,153 @@ uri="${temp#*||}"
|
||||
ATTACK_TYPES["$type"]=$((${ATTACK_TYPES[$type]:-0} + 1))
|
||||
done
|
||||
|
||||
# Track top attackers
|
||||
# Track top attackers (cumulative score)
|
||||
TOP_ATTACKERS["$ip"]=$((${TOP_ATTACKERS[$ip]:-0} + threat_score))
|
||||
|
||||
# Track attack count per IP
|
||||
IP_ATTACK_COUNT["$ip"]=$((${IP_ATTACK_COUNT[$ip]:-0} + 1))
|
||||
|
||||
# Store attack type details per IP
|
||||
current_types="${IP_ATTACK_DETAILS[$ip]}"
|
||||
if [ -z "$current_types" ]; then
|
||||
IP_ATTACK_DETAILS["$ip"]="$attack_types"
|
||||
else
|
||||
IP_ATTACK_DETAILS["$ip"]="$current_types,$attack_types"
|
||||
fi
|
||||
|
||||
# Store sample URL (keep first 3)
|
||||
current_urls="${IP_SAMPLE_URLS[$ip]}"
|
||||
if [ -z "$current_urls" ]; then
|
||||
# First URL
|
||||
IP_SAMPLE_URLS["$ip"]="${uri:0:100}"
|
||||
else
|
||||
# Count existing URLs by counting delimiters + 1
|
||||
url_count=$(echo "$current_urls" | grep -o "||" | wc -l)
|
||||
url_count=$((url_count + 1))
|
||||
if [ "$url_count" -lt 3 ]; then
|
||||
IP_SAMPLE_URLS["$ip"]="$current_urls||${uri:0:100}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Track signatures
|
||||
IFS=',' read -ra sigs <<< "$signatures"
|
||||
for sig in "${sigs[@]}"; do
|
||||
SIGNATURE_HITS["$sig"]=$((${SIGNATURE_HITS[$sig]:-0} + 1))
|
||||
done
|
||||
|
||||
# Log if verbose or critical
|
||||
if [ "$VERBOSE" -eq 1 ] || [ "$threat_score" -ge 85 ]; then
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
echo "[Score: $threat_score] $ip → $attack_types" >> "$OUTPUT_FILE"
|
||||
echo " URI: ${uri:0:150}" >> "$OUTPUT_FILE"
|
||||
echo " Signatures: $signatures" >> "$OUTPUT_FILE"
|
||||
fi
|
||||
fi
|
||||
done < <($CAT_CMD "$log_file" 2>/dev/null)
|
||||
|
||||
echo " → Found $file_attacks attacks" >> "$OUTPUT_FILE"
|
||||
echo " → Found $file_attacks attacks"
|
||||
done
|
||||
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
echo ""
|
||||
echo "================================================================================
|
||||
" >> "$OUTPUT_FILE"
|
||||
echo "SUMMARY STATISTICS" >> "$OUTPUT_FILE"
|
||||
"
|
||||
echo "ATTACKING IPs - DETAILED BREAKDOWN"
|
||||
echo "================================================================================
|
||||
" >> "$OUTPUT_FILE"
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
echo "Total lines processed: $TOTAL_LINES" >> "$OUTPUT_FILE"
|
||||
echo "Total attacks detected: $TOTAL_ATTACKS" >> "$OUTPUT_FILE"
|
||||
echo " - Critical (≥85): $CRITICAL_ATTACKS" >> "$OUTPUT_FILE"
|
||||
echo " - High (70-84): $HIGH_ATTACKS" >> "$OUTPUT_FILE"
|
||||
echo " - Medium (50-69): $MEDIUM_ATTACKS" >> "$OUTPUT_FILE"
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
"
|
||||
echo ""
|
||||
|
||||
# Sort IPs by cumulative threat score and display
|
||||
# Create sorted list first to avoid subshell issues
|
||||
sorted_ips=$(for ip in "${!TOP_ATTACKERS[@]}"; do
|
||||
echo "${TOP_ATTACKERS[$ip]}:$ip"
|
||||
done | sort -t: -k1 -nr | head -50)
|
||||
|
||||
ip_count=0
|
||||
while IFS=: read -r cumulative_score ip; do
|
||||
ip_count=$((ip_count + 1))
|
||||
|
||||
attack_count="${IP_ATTACK_COUNT[$ip]:-0}"
|
||||
all_attack_types="${IP_ATTACK_DETAILS[$ip]}"
|
||||
sample_urls="${IP_SAMPLE_URLS[$ip]}"
|
||||
|
||||
# Count occurrences of each attack type
|
||||
declare -A type_counts
|
||||
IFS=',' read -ra attacks <<< "$all_attack_types"
|
||||
for attack in "${attacks[@]}"; do
|
||||
[ -n "$attack" ] && type_counts["$attack"]=$((${type_counts[$attack]:-0} + 1))
|
||||
done
|
||||
|
||||
# Format attack summary
|
||||
attack_summary=""
|
||||
for type in "${!type_counts[@]}"; do
|
||||
if [ -z "$attack_summary" ]; then
|
||||
attack_summary="$type(${type_counts[$type]})"
|
||||
else
|
||||
attack_summary="$attack_summary, $type(${type_counts[$type]})"
|
||||
fi
|
||||
done
|
||||
unset type_counts
|
||||
|
||||
# Determine threat level
|
||||
avg_score=$((cumulative_score / attack_count))
|
||||
if [ "$avg_score" -ge 85 ]; then
|
||||
level="CRITICAL"
|
||||
elif [ "$avg_score" -ge 70 ]; then
|
||||
level="HIGH"
|
||||
else
|
||||
level="MEDIUM"
|
||||
fi
|
||||
|
||||
# Print IP summary
|
||||
echo "[$ip_count] $ip"
|
||||
printf " Attacks: %d | Avg Score: %d | Threat Level: %s\n" "$attack_count" "$avg_score" "$level"
|
||||
echo " Attack Types: $attack_summary"
|
||||
|
||||
# Get reputation (if available)
|
||||
if type get_threat_intelligence &>/dev/null; then
|
||||
threat_intel=$(get_threat_intelligence "$ip" 2>/dev/null)
|
||||
if [ -n "$threat_intel" ]; then
|
||||
IFS='|' read -r abuse_conf abuse_rpts country isp geo timing whitelisted <<< "$threat_intel"
|
||||
if [ "${abuse_conf:-0}" -gt 0 ]; then
|
||||
printf " Reputation: AbuseIPDB %d%% confidence (%d reports) | %s\n" "${abuse_conf:-0}" "${abuse_rpts:-0}" "${country:-Unknown}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Show sample URLs
|
||||
if [ -n "$sample_urls" ]; then
|
||||
echo " Sample Targets:"
|
||||
IFS='||' read -ra urls <<< "$sample_urls"
|
||||
for url in "${urls[@]}"; do
|
||||
echo " - $url"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done <<< "$sorted_ips"
|
||||
|
||||
echo "================================================================================
|
||||
"
|
||||
echo "SUMMARY STATISTICS"
|
||||
echo "================================================================================
|
||||
"
|
||||
echo ""
|
||||
echo "Total lines processed: $TOTAL_LINES"
|
||||
echo "Total attacks detected: $TOTAL_ATTACKS"
|
||||
echo "Unique attacking IPs: ${#TOP_ATTACKERS[@]}"
|
||||
echo ""
|
||||
echo "Attack Severity:"
|
||||
echo " - Critical (≥85): $CRITICAL_ATTACKS"
|
||||
echo " - High (70-84): $HIGH_ATTACKS"
|
||||
echo " - Medium (50-69): $MEDIUM_ATTACKS"
|
||||
echo ""
|
||||
|
||||
# Top Attack Types
|
||||
echo "Top Attack Types:" >> "$OUTPUT_FILE"
|
||||
echo "Top Attack Types:"
|
||||
for type in "${!ATTACK_TYPES[@]}"; do
|
||||
echo "$type:${ATTACK_TYPES[$type]}"
|
||||
done | sort -t: -k2 -nr | head -15 | while IFS=: read -r type count; do
|
||||
printf " %-20s %5d attacks\n" "$type" "$count" >> "$OUTPUT_FILE"
|
||||
done | sort -t: -k2 -nr | head -10 | while IFS=: read -r type count; do
|
||||
printf " %-20s %5d attacks\n" "$type" "$count"
|
||||
done
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
|
||||
# Top Attackers
|
||||
echo "Top 20 Attacking IPs (by cumulative threat score):" >> "$OUTPUT_FILE"
|
||||
for ip in "${!TOP_ATTACKERS[@]}"; do
|
||||
echo "$ip:${TOP_ATTACKERS[$ip]}"
|
||||
done | sort -t: -k2 -nr | head -20 | while IFS=: read -r ip score; do
|
||||
printf " %-15s Score: %5d\n" "$ip" "$score" >> "$OUTPUT_FILE"
|
||||
done
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
|
||||
# Top Signatures
|
||||
echo "Top 20 Triggered Signatures:" >> "$OUTPUT_FILE"
|
||||
for sig in "${!SIGNATURE_HITS[@]}"; do
|
||||
echo "$sig:${SIGNATURE_HITS[$sig]}"
|
||||
done | sort -t: -k2 -nr | head -20 | while IFS=: read -r sig count; do
|
||||
printf " %-30s %5d hits\n" "$sig" "$count" >> "$OUTPUT_FILE"
|
||||
done
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
echo ""
|
||||
|
||||
echo "================================================================================
|
||||
" >> "$OUTPUT_FILE"
|
||||
echo "END OF REPORT" >> "$OUTPUT_FILE"
|
||||
"
|
||||
echo "END OF REPORT"
|
||||
echo "================================================================================
|
||||
" >> "$OUTPUT_FILE"
|
||||
"
|
||||
|
||||
} > "$OUTPUT_FILE"
|
||||
|
||||
|
||||
+83
-30
@@ -58,7 +58,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 1: grep -F with regex anchors (CRITICAL - causes wrong results)
|
||||
#==============================================================================
|
||||
echo "[1/30] Checking: grep -F with regex anchors..."
|
||||
echo "[1/31] Checking: grep -F with regex anchors..."
|
||||
{
|
||||
echo "## CHECK 1: grep -F with regex anchors"
|
||||
echo "Severity: CRITICAL"
|
||||
@@ -79,7 +79,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 2: SCRIPT_DIR collisions (HIGH - causes path errors)
|
||||
#==============================================================================
|
||||
echo "[2/30] Checking: SCRIPT_DIR variable collisions..."
|
||||
echo "[2/31] Checking: SCRIPT_DIR variable collisions..."
|
||||
{
|
||||
echo "## CHECK 2: SCRIPT_DIR variable collisions"
|
||||
echo "Severity: HIGH"
|
||||
@@ -99,7 +99,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 3: SYS_* variable resets (CRITICAL - breaks system detection)
|
||||
#==============================================================================
|
||||
echo "[3/30] Checking: SYS_* variable resets..."
|
||||
echo "[3/31] Checking: SYS_* variable resets..."
|
||||
{
|
||||
echo "## CHECK 3: SYS_* variable resets without protection"
|
||||
echo "Severity: CRITICAL"
|
||||
@@ -120,7 +120,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 4: Missing function exports (HIGH - functions unavailable)
|
||||
#==============================================================================
|
||||
echo "[4/30] Checking: Missing function exports..."
|
||||
echo "[4/31] Checking: Missing function exports..."
|
||||
{
|
||||
echo "## CHECK 4: Missing function exports in libraries"
|
||||
echo "Severity: HIGH"
|
||||
@@ -145,7 +145,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 5: Integer comparisons without empty checks (HIGH - causes errors)
|
||||
#==============================================================================
|
||||
echo "[5/30] Checking: Unsafe integer comparisons (top 10)..."
|
||||
echo "[5/31] Checking: Unsafe integer comparisons (top 10)..."
|
||||
{
|
||||
echo "## CHECK 5: Integer comparisons without empty checks"
|
||||
echo "Severity: HIGH"
|
||||
@@ -170,7 +170,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 6: Missing common-functions.sh (HIGH - command not found)
|
||||
#==============================================================================
|
||||
echo "[6/30] Checking: Missing common-functions.sh..."
|
||||
echo "[6/31] Checking: Missing common-functions.sh..."
|
||||
{
|
||||
echo "## CHECK 6: Missing common-functions.sh sourcing"
|
||||
echo "Severity: HIGH"
|
||||
@@ -190,7 +190,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 7: exit in libraries (HIGH - terminates parent script)
|
||||
#==============================================================================
|
||||
echo "[7/30] Checking: exit in library files..."
|
||||
echo "[7/31] Checking: exit in library files..."
|
||||
{
|
||||
echo "## CHECK 7: exit in sourced libraries"
|
||||
echo "Severity: HIGH"
|
||||
@@ -215,7 +215,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 8: bc command usage (LOW - external dependency)
|
||||
#==============================================================================
|
||||
echo "[8/30] Checking: bc command usage..."
|
||||
echo "[8/31] Checking: bc command usage..."
|
||||
{
|
||||
echo "## CHECK 8: bc command usage"
|
||||
echo "Severity: LOW"
|
||||
@@ -238,7 +238,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 9: Hardcoded /var/cpanel paths (MEDIUM - breaks multi-panel)
|
||||
#==============================================================================
|
||||
echo "[9/30] Checking: Hardcoded /var/cpanel paths..."
|
||||
echo "[9/31] Checking: Hardcoded /var/cpanel paths..."
|
||||
{
|
||||
echo "## CHECK 9: Hardcoded /var/cpanel paths"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -264,7 +264,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 10: Undefined color variables (LOW - cosmetic issue)
|
||||
#==============================================================================
|
||||
echo "[10/30] Checking: Undefined color variables..."
|
||||
echo "[10/31] Checking: Undefined color variables..."
|
||||
{
|
||||
echo "## CHECK 10: Undefined color variables"
|
||||
echo "Severity: LOW"
|
||||
@@ -289,7 +289,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 11: Bash syntax validation (CRITICAL - prevents execution)
|
||||
#==============================================================================
|
||||
echo "[11/30] Checking: Bash syntax errors..."
|
||||
echo "[11/31] Checking: Bash syntax errors..."
|
||||
{
|
||||
echo "## CHECK 11: Bash syntax validation"
|
||||
echo "Severity: CRITICAL"
|
||||
@@ -310,7 +310,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 12: Dangerous rm commands (CRITICAL - data loss risk)
|
||||
#==============================================================================
|
||||
echo "[12/30] Checking: Dangerous rm commands..."
|
||||
echo "[12/31] Checking: Dangerous rm commands..."
|
||||
{
|
||||
echo "## CHECK 12: Dangerous rm commands"
|
||||
echo "Severity: CRITICAL"
|
||||
@@ -339,7 +339,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 13: Unquoted variable expansions (HIGH - word splitting/globbing risks)
|
||||
#==============================================================================
|
||||
echo "[13/30] Checking: Unquoted variables in dangerous contexts..."
|
||||
echo "[13/31] Checking: Unquoted variables in dangerous contexts..."
|
||||
{
|
||||
echo "## CHECK 13: Unquoted variable expansions"
|
||||
echo "Severity: HIGH"
|
||||
@@ -363,7 +363,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 14: Command injection via eval (CRITICAL - arbitrary code execution)
|
||||
#==============================================================================
|
||||
echo "[14/30] Checking: Command injection risks..."
|
||||
echo "[14/31] Checking: Command injection risks..."
|
||||
{
|
||||
echo "## CHECK 14: Command injection via eval"
|
||||
echo "Severity: CRITICAL"
|
||||
@@ -384,7 +384,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 15: Temp file security (MEDIUM - race conditions/predictable names)
|
||||
#==============================================================================
|
||||
echo "[15/30] Checking: Temp file security..."
|
||||
echo "[15/31] Checking: Temp file security..."
|
||||
{
|
||||
echo "## CHECK 15: Insecure temp file creation"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -407,7 +407,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 16: TODO/FIXME/HACK markers (LOW - technical debt tracking)
|
||||
#==============================================================================
|
||||
echo "[16/30] Checking: Technical debt markers..."
|
||||
echo "[16/31] Checking: Technical debt markers..."
|
||||
{
|
||||
echo "## CHECK 16: TODO/FIXME/HACK comments"
|
||||
echo "Severity: LOW"
|
||||
@@ -431,7 +431,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 17: Duplicate function definitions (MEDIUM - causes conflicts)
|
||||
#==============================================================================
|
||||
echo "[17/30] Checking: Duplicate function definitions..."
|
||||
echo "[17/31] Checking: Duplicate function definitions..."
|
||||
{
|
||||
echo "## CHECK 17: Duplicate function definitions"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -457,7 +457,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 18: Missing input validation (HIGH - security/reliability risk)
|
||||
#==============================================================================
|
||||
echo "[18/30] Checking: Missing input validation..."
|
||||
echo "[18/31] Checking: Missing input validation..."
|
||||
{
|
||||
echo "## CHECK 18: Functions without parameter validation"
|
||||
echo "Severity: HIGH"
|
||||
@@ -555,7 +555,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 19: Long functions (MEDIUM - maintainability issue)
|
||||
#==============================================================================
|
||||
echo "[19/30] Checking: Overly long functions..."
|
||||
echo "[19/31] Checking: Overly long functions..."
|
||||
{
|
||||
echo "## CHECK 19: Long functions (>100 lines)"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -600,7 +600,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 20: ShellCheck integration (if available)
|
||||
#==============================================================================
|
||||
echo "[20/30] Checking: ShellCheck warnings (if available)..."
|
||||
echo "[20/31] Checking: ShellCheck warnings (if available)..."
|
||||
{
|
||||
echo "## CHECK 20: ShellCheck static analysis"
|
||||
echo "Severity: VARIES"
|
||||
@@ -636,7 +636,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 21: Using [ ] instead of [[ ]] (MEDIUM - less safe)
|
||||
#==============================================================================
|
||||
echo "[21/30] Checking: Single bracket conditionals..."
|
||||
echo "[21/31] Checking: Single bracket conditionals..."
|
||||
{
|
||||
echo "## CHECK 21: Using [ ] instead of [[ ]]"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -664,7 +664,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 22: Looping over ls output (HIGH - fatally flawed pattern)
|
||||
#==============================================================================
|
||||
echo "[22/30] Checking: Loops over ls output..."
|
||||
echo "[22/31] Checking: Loops over ls output..."
|
||||
{
|
||||
echo "## CHECK 22: Looping over ls output"
|
||||
echo "Severity: HIGH"
|
||||
@@ -684,7 +684,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 23: Missing set -euo pipefail (MEDIUM - silent failures)
|
||||
#==============================================================================
|
||||
echo "[23/30] Checking: Missing error handling flags..."
|
||||
echo "[23/31] Checking: Missing error handling flags..."
|
||||
{
|
||||
echo "## CHECK 23: Missing set -euo pipefail"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -717,7 +717,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 24: Unused variables (LOW - dead code)
|
||||
#==============================================================================
|
||||
echo "[24/30] Checking: Unused variables..."
|
||||
echo "[24/31] Checking: Unused variables..."
|
||||
{
|
||||
echo "## CHECK 24: Unused variables"
|
||||
echo "Severity: LOW"
|
||||
@@ -748,7 +748,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 25: Backticks instead of $() (LOW - deprecated syntax)
|
||||
#==============================================================================
|
||||
echo "[25/30] Checking: Deprecated backticks..."
|
||||
echo "[25/31] Checking: Deprecated backticks..."
|
||||
{
|
||||
echo "## CHECK 25: Using backticks instead of \$()"
|
||||
echo "Severity: LOW"
|
||||
@@ -768,7 +768,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 26: Missing or wrong shebang (HIGH - execution issues)
|
||||
#==============================================================================
|
||||
echo "[26/30] Checking: Shebang issues..."
|
||||
echo "[26/31] Checking: Shebang issues..."
|
||||
{
|
||||
echo "## CHECK 26: Missing or incorrect shebang"
|
||||
echo "Severity: HIGH"
|
||||
@@ -801,7 +801,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 27: Not checking command exit status (MEDIUM - silent failures)
|
||||
#==============================================================================
|
||||
echo "[27/30] Checking: Unchecked critical commands..."
|
||||
echo "[27/31] Checking: Unchecked critical commands..."
|
||||
{
|
||||
echo "## CHECK 27: Critical commands without exit status checks"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -831,7 +831,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 28: Incorrect string/number comparison (HIGH - type confusion)
|
||||
#==============================================================================
|
||||
echo "[28/30] Checking: Type confusion in comparisons..."
|
||||
echo "[28/31] Checking: Type confusion in comparisons..."
|
||||
{
|
||||
echo "## CHECK 28: Using wrong comparison operators"
|
||||
echo "Severity: HIGH"
|
||||
@@ -856,7 +856,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 29: Unsafe array iteration (MEDIUM - word splitting)
|
||||
#==============================================================================
|
||||
echo "[29/30] Checking: Unsafe array expansions..."
|
||||
echo "[29/31] Checking: Unsafe array expansions..."
|
||||
{
|
||||
echo "## CHECK 29: Array iteration without quotes"
|
||||
echo "Severity: MEDIUM"
|
||||
@@ -882,7 +882,7 @@ echo ""
|
||||
#==============================================================================
|
||||
# CHECK 30: Hardcoded credentials or secrets (CRITICAL - security)
|
||||
#==============================================================================
|
||||
echo "[30/30] Checking: Hardcoded credentials..."
|
||||
echo "[30/31] Checking: Hardcoded credentials..."
|
||||
{
|
||||
echo "## CHECK 30: Hardcoded passwords/API keys"
|
||||
echo "Severity: CRITICAL"
|
||||
@@ -901,6 +901,59 @@ done < <(grep -rniE '(password|passwd|api_key|apikey|secret|token)=' "$TOOLKIT_P
|
||||
echo ""
|
||||
} >> "$REPORT"
|
||||
|
||||
#==============================================================================
|
||||
# CHECK 31: local keyword outside functions (CRITICAL - script fails)
|
||||
#==============================================================================
|
||||
echo "[31/31] Checking: 'local' outside functions..."
|
||||
{
|
||||
echo "## CHECK 31: 'local' keyword outside function context"
|
||||
echo "Severity: CRITICAL"
|
||||
echo "Issue: 'local' can only be used inside functions, causes runtime error"
|
||||
echo ""
|
||||
|
||||
while read -r file; do
|
||||
# Read entire file and track function boundaries
|
||||
in_function=0
|
||||
brace_depth=0
|
||||
line_num=0
|
||||
|
||||
while IFS= read -r line_content; do
|
||||
line_num=$((line_num + 1))
|
||||
|
||||
# Skip comments
|
||||
if echo "$line_content" | grep -q '^\s*#'; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Detect function start
|
||||
if echo "$line_content" | grep -qE '^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*\(\)'; then
|
||||
in_function=1
|
||||
brace_depth=0
|
||||
fi
|
||||
|
||||
# Track braces
|
||||
open_braces=$(echo "$line_content" | grep -o '{' | wc -l)
|
||||
close_braces=$(echo "$line_content" | grep -o '}' | wc -l)
|
||||
brace_depth=$((brace_depth + open_braces - close_braces))
|
||||
|
||||
# If we were in a function and braces are now balanced back to 0, we've exited
|
||||
if [ "$in_function" -eq 1 ] && [ "$brace_depth" -le 0 ]; then
|
||||
in_function=0
|
||||
fi
|
||||
|
||||
# Check for 'local' keyword outside function
|
||||
if [ "$in_function" -eq 0 ]; then
|
||||
if echo "$line_content" | grep -qE '^\s*local\s+[a-zA-Z_]'; then
|
||||
echo "CRITICAL|$file|$line_num|'local' keyword outside function (runtime error)"
|
||||
count_issue "CRITICAL"
|
||||
fi
|
||||
fi
|
||||
done < "$file"
|
||||
done < <(find "$TOOLKIT_PATH" -name "*.sh" -type f 2>/dev/null)
|
||||
|
||||
echo ""
|
||||
} >> "$REPORT"
|
||||
|
||||
#==============================================================================
|
||||
# PERFORMANCE CHECKS (INFO level - not counted as issues)
|
||||
#==============================================================================
|
||||
|
||||
Reference in New Issue
Block a user