From 819d83475843ca4224d1c9efbc649e8b9c07770d Mon Sep 17 00:00:00 2001 From: cschantz Date: Tue, 11 Nov 2025 21:32:11 -0500 Subject: [PATCH] Fix critical docroot parsing bug in malware scanner The docroot extraction from /etc/userdatadomains was completely broken, causing scans to target invalid paths like "main" instead of actual document roots like /home/user/public_html. Problem: - Used `cut -d= -f5` which treats EVERY = as delimiter - File format uses == as delimiter: user==owner==main==domain==docroot==... - This caused field 5 to be "main" instead of the docroot path - Result: Scanners scanned zero files and completed in seconds Solution: - Use `awk -F'==' '{print $5}'` to properly parse == delimited fields - Extract field after colon, then split by == - Added -d check to ensure docroot exists before adding - Fixed both detect_control_panel() and get_user_docroots() Impact: - Malware scans now actually scan real document roots - Full server scans will take appropriate time (not 10 seconds!) - Users will see actual file counts and scan progress --- modules/security/malware-scanner.sh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/security/malware-scanner.sh b/modules/security/malware-scanner.sh index 29085ae..b565b2f 100755 --- a/modules/security/malware-scanner.sh +++ b/modules/security/malware-scanner.sh @@ -288,9 +288,12 @@ detect_control_panel() { CONTROL_PANEL="cpanel" export PATH=/usr/local/cpanel/3rdparty/bin/:$PATH - while IFS= read -r docroot; do - [ -n "$docroot" ] && docroot_array+=("$docroot") - done < <(cut -d= -f5 /etc/userdatadomains | sed 's/==/=/g' | sort -u) + while IFS= read -r line; do + # Format: domain: user==owner==main==domain==docroot==... + # Extract docroot (field 5, 0-indexed field 4) + docroot=$(echo "$line" | awk -F'==' '{print $5}') + [ -n "$docroot" ] && [ -d "$docroot" ] && docroot_array+=("$docroot") + done < <(cut -d: -f2- /etc/userdatadomains | sort -u) # Detect Plesk elif [ -f "/usr/local/psa/version" ]; then @@ -364,9 +367,10 @@ get_user_docroots() { local user_docroots=() if [ "$CONTROL_PANEL" = "cpanel" ]; then - while IFS= read -r docroot; do - [ -n "$docroot" ] && user_docroots+=("$docroot") - done < <(grep "^${username}:" /etc/userdatadomains | cut -d= -f5 | sed 's/==/=/g' | sort -u) + while IFS= read -r line; do + docroot=$(echo "$line" | awk -F'==' '{print $5}') + [ -n "$docroot" ] && [ -d "$docroot" ] && user_docroots+=("$docroot") + done < <(grep ":.*${username}==" /etc/userdatadomains | cut -d: -f2- | sort -u) else echo -e "${RED}User-specific scanning only supported on cPanel${NC}" return 1