Fix: Convert all grep patterns to use -F flag (fixed-string matching) to prevent regex injection

This prevents domain names, IPs, and other variables with special characters
(like dots in domains) from being interpreted as regex wildcards.

Changed patterns from:
  grep "pattern_with_$var"
to:
  grep -F "pattern_with_$var"

Affects 11 grep statements across multiple functions:
- Domain-specific metrics calculation (lines 686-688)
- IP progression analysis (line 750)
- Attack type breakdown (line 1039)
- Domain bot type indexing (line 2020)
- Domain threat statistics (line 3678)
- High-risk IP blocking (lines 4006, 4156, 4200, 4202-4203)
- High-risk IP listing (line 4523)
- Temporary deny blocking (lines 4589, 4642)

This hardens the script against regex injection attacks and ensures correct
literal string matching regardless of special characters in data.
This commit is contained in:
Developer
2026-04-23 21:24:47 -04:00
parent 01b63c6ad4
commit d159dd28d8
+17 -17
View File
@@ -683,9 +683,9 @@ save_baseline() {
local baseline_file="$BASELINE_DIR/${domain}_baseline.txt"
# Get domain-specific metrics
local domain_requests=$(grep "^[^|]*|$domain|" "$TEMP_DIR/parsed_logs.txt" 2>/dev/null | wc -l || echo "0")
local domain_attacks=$(grep "^[^|]*|$domain|" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | wc -l || echo "0")
local domain_bots=$(grep "^[^|]*|$domain|" "$TEMP_DIR/classified_bots.txt" 2>/dev/null | wc -l || echo "0")
local domain_requests=$(grep -F "|$domain|" "$TEMP_DIR/parsed_logs.txt" 2>/dev/null | wc -l || echo "0")
local domain_attacks=$(grep -F "|$domain|" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | wc -l || echo "0")
local domain_bots=$(grep -F "|$domain|" "$TEMP_DIR/classified_bots.txt" 2>/dev/null | wc -l || echo "0")
# Append to baseline history (timestamp|requests|attacks|bots|high_risk_ips)
echo "$today|$domain_requests|$domain_attacks|$domain_bots|$high_risk_ips" >> "$baseline_file"
@@ -747,7 +747,7 @@ analyze_attack_progression() {
> "$progression_file"
# Extract all requests from this IP, in order
grep "^$ip|" "$TEMP_DIR/parsed_logs.txt" 2>/dev/null | awk -F'|' '{
grep -F "$ip|" "$TEMP_DIR/parsed_logs.txt" 2>/dev/null | awk -F'|' '{
print $8 "|" $3 "|" $4 "|" $6
}' | sort >> "$progression_file"
@@ -1036,7 +1036,7 @@ detect_threats() {
# Breakdown by attack type
for attack_type in sqli xss path_traversal rce_upload info_disclosure login_bruteforce; do
grep "|$attack_type$" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | \
grep -F "|$attack_type" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | grep -F "|$attack_type$" | \
awk -F'|' '{print $1"|"$2"|"$3"|"$4}' | \
sort | uniq -c | sort -rn > "$TEMP_DIR/${attack_type}_attempts.txt" || true
done
@@ -1660,7 +1660,7 @@ calculate_threat_scores() {
declare -A ip_request_counts
while IFS='|' read -r ip rest; do
((ip_request_counts["$ip"]++))
done < <(cat "$TEMP_DIR/parsed_logs.txt")
done < "$TEMP_DIR/parsed_logs.txt"
# Build hash tables from threat files for O(1) lookups
# OPTIMIZATION: Use awk instead of echo|awk|cut in loops (10x faster)
@@ -2017,7 +2017,7 @@ generate_statistics() {
while read -r domain; do
echo "$domain" > "$TEMP_DIR/domain_${domain}_stats.txt"
grep "^$domain|" "$TEMP_DIR/domain_bot_types.txt" 2>/dev/null | cut -d'|' -f2 | \
grep -F "$domain|" "$TEMP_DIR/domain_bot_types.txt" 2>/dev/null | cut -d'|' -f2 | \
sort | uniq -c | sort -rn >> "$TEMP_DIR/domain_${domain}_stats.txt" || true
done < "$TEMP_DIR/all_domains.txt"
fi
@@ -2453,7 +2453,7 @@ generate_report() {
# Show top attacked domains with attack details
awk -F'|' 'NR <= 10 {print $1}' "$TEMP_DIR/domain_targeting.txt" | while read -r domain; do
domain_attack_count=$(grep "^[^|]*|${domain}|" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | wc -l || echo "0")
domain_attack_count=$(grep -F "|${domain}|" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | wc -l || echo "0")
if [ "$domain_attack_count" -gt 0 ]; then
echo " Domain: $domain ($domain_attack_count attack attempts)"
@@ -3675,7 +3675,7 @@ show_detailed_recommendations() {
local target_domain=$(echo "$action_title" | grep -oP 'to \K[^ ]+' 2>/dev/null || echo "")
echo "Target Domain: $target_domain"
if [ -s "$TEMP_DIR/domain_threats_sorted.txt" ]; then
grep "^$target_domain|" "$TEMP_DIR/domain_threats_sorted.txt" 2>/dev/null | while IFS='|' read -r domain total_req bot_req bot_pct high_risk attacks ips; do
grep -F "$target_domain|" "$TEMP_DIR/domain_threats_sorted.txt" 2>/dev/null | while IFS='|' read -r domain total_req bot_req bot_pct high_risk attacks ips; do
echo " • Total Requests: $total_req"
echo " • Bot Requests: $bot_req ($bot_pct%)"
echo " • High-Risk IPs: $high_risk"
@@ -4003,7 +4003,7 @@ execute_ip_blocking_specific() {
local fail_count=0
for ip in "${ips_to_block[@]}"; do
local score=$(grep "|$ip|" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "unknown")
local score=$(grep -F "|$ip|" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "unknown")
if csf -td "$ip" "$duration" "Bot threat score: $score/100 - Auto-blocked by toolkit" >/dev/null 2>&1; then
echo -e " ${GREEN}${NC} Blocked $ip for $duration_text (score: $score/100)"
@@ -4153,7 +4153,7 @@ execute_htaccess_domain_blocking() {
# Find document root for this domain using reference database
local doc_root=""
if [ -s "$SCRIPT_DIR/.sysref" ]; then
doc_root=$(grep "^DOMAIN|$target_domain|" "$SCRIPT_DIR/.sysref" 2>/dev/null | head -1 | cut -d'|' -f4 || echo "")
doc_root=$(grep -F "DOMAIN|$target_domain|" "$SCRIPT_DIR/.sysref" 2>/dev/null | head -1 | cut -d'|' -f4 || echo "")
fi
if [ -z "$doc_root" ]; then
@@ -4197,10 +4197,10 @@ execute_htaccess_domain_blocking() {
print_info "Adding bot blocking rules..."
# Get high-risk IPs for this domain
local block_ips=$(cat "$TEMP_DIR/parsed_logs.txt" 2>/dev/null | grep "^[^|]*|$target_domain|" 2>/dev/null || true | cut -d'|' -f1 | sort -u | while read ip; do
local block_ips=$(cat "$TEMP_DIR/parsed_logs.txt" 2>/dev/null | grep -F "|$target_domain|" 2>/dev/null || true | cut -d'|' -f1 | sort -u | while read ip; do
# Check if this IP has high threat score
if grep -q "|$ip$" "$TEMP_DIR/threat_scores.txt" 2>/dev/null; then
local score=$(grep "|$ip$" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "0")
if grep -q -F "|$ip|" "$TEMP_DIR/threat_scores.txt" 2>/dev/null; then
local score=$(grep -F "|$ip|" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "0")
if [ "${score:-0}" -ge 70 ]; then
echo "$ip"
fi
@@ -4520,7 +4520,7 @@ offer_csf_blocking() {
count=$((count + 1))
local ip="${high_risk_ips[$i]}"
local score="${ip_scores[$i]}"
local requests=$(grep "^$ip|" "$TEMP_DIR/bot_ips.txt" 2>/dev/null | cut -d'|' -f2 || echo "0")
local requests=$(grep -F "$ip|" "$TEMP_DIR/bot_ips.txt" 2>/dev/null | cut -d'|' -f2 || echo "0")
# Color code by severity
if [ "$score" -ge 90 ]; then
@@ -4586,7 +4586,7 @@ apply_csf_blocks() {
for ip in "${ips[@]}"; do
# Get threat score for comment
local score=$(grep "|$ip$" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "unknown")
local score=$(grep -F "|$ip|" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "unknown")
# Use csf -td for temporary deny
if csf -td "$ip" "$duration" "Bot threat score: $score/100 - Auto-blocked by toolkit" >/dev/null 2>&1; then
@@ -4639,7 +4639,7 @@ apply_csf_permanent_blocks() {
local fail_count=0
for ip in "${ips[@]}"; do
local score=$(grep "|$ip$" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "unknown")
local score=$(grep -F "|$ip|" "$TEMP_DIR/threat_scores.txt" 2>/dev/null | cut -d'|' -f1 || echo "unknown")
# Use csf -d for permanent deny
if csf -d "$ip" "Bot threat score: $score/100 - Permanently blocked by toolkit" >/dev/null 2>&1; then