From ef740adba41a3e90fa6afc53becea3d26de5ce18 Mon Sep 17 00:00:00 2001 From: cschantz Date: Wed, 28 Jan 2026 23:26:46 -0500 Subject: [PATCH] FIX: Critical syntax error in bot-analyzer.sh (apostrophes in AWK comments) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Bash script had CRITICAL syntax error at line 554 - AWK script was wrapped in single quotes '...' - Comments inside AWK code contained apostrophes (it's, doesn't, etc.) - In bash, apostrophe inside single-quoted string terminates the quote early - This caused: bash -n to fail with "syntax error near unexpected token 'ua_lower,'" Fix: Changed all contractions in AWK comments to avoid apostrophes - "it's" → "it is" - This preserves readability while maintaining bash syntax validity Result: - CRITICAL error eliminated - bash -n now passes cleanly - QA scan: CRITICAL=0 (was 1), exit code 361 (was 362) Files changed: - modules/security/bot-analyzer.sh (3 apostrophes removed from comments) Root cause: When adding browser detection improvements in previous commit (8f27baa), I used contractions in comments without realizing they break AWK single-quote strings in bash. --- modules/security/bot-analyzer.sh | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/modules/security/bot-analyzer.sh b/modules/security/bot-analyzer.sh index 4063138..20151cb 100755 --- a/modules/security/bot-analyzer.sh +++ b/modules/security/bot-analyzer.sh @@ -543,35 +543,31 @@ classify_bots() { } } } else if (match(ua_lower, /bot|crawler|spider|scraper|curl|wget|python-requests|python-urllib|java\/|scan|check|monitor/)) { - # FIXED: Check for bot keywords FIRST, then verify it's not a legitimate browser + # FIXED: Check for bot keywords FIRST, then verify it is not a legitimate browser # This prevents bots from bypassing detection by including browser strings - # FIRST: Check if it's actually a legitimate browser with complete UA signature + # FIRST: Check if it is actually a legitimate browser with complete UA signature # Real browsers have: Mozilla/5.0 + platform + rendering engine + browser version is_real_browser = 0 # Chrome/Chromium-based: Must have Chrome/ AND (AppleWebKit OR Mobile) if (match(ua_lower, /chrome\/[0-9]/) && (match(ua_lower, /applewebkit/) || match(ua_lower, /mobile/))) { is_real_browser = 1 - } - # Firefox: Must have Firefox/ AND Gecko/ - else if (match(ua_lower, /firefox\/[0-9]/) && match(ua_lower, /gecko\//)) { + } else if (match(ua_lower, /firefox\/[0-9]/) && match(ua_lower, /gecko\//)) { + # Firefox: Must have Firefox/ AND Gecko/ is_real_browser = 1 - } - # Safari: Must have Safari/ AND Version/ AND AppleWebKit (not Chrome) - else if (match(ua_lower, /safari\/[0-9]/) && match(ua_lower, /version\//) && match(ua_lower, /applewebkit/) && !match(ua_lower, /chrome/)) { + } else if (match(ua_lower, /safari\/[0-9]/) && match(ua_lower, /version\//) && match(ua_lower, /applewebkit/) && !match(ua_lower, /chrome/)) { + # Safari: Must have Safari/ AND Version/ AND AppleWebKit (not Chrome) is_real_browser = 1 - } - # Edge: Must have Edg/ or Edge/ - else if (match(ua_lower, /edg\/[0-9]|edge\/[0-9]/)) { + } else if (match(ua_lower, /edg\/[0-9]|edge\/[0-9]/)) { + # Edge: Must have Edg/ or Edge/ is_real_browser = 1 - } - # Mobile browsers: Samsung, UC, Opera Mobile - else if (match(ua_lower, /samsungbrowser\/[0-9]|ucbrowser\/[0-9]|opr\/[0-9]/)) { + } else if (match(ua_lower, /samsungbrowser\/[0-9]|ucbrowser\/[0-9]|opr\/[0-9]/)) { + # Mobile browsers: Samsung, UC, Opera Mobile is_real_browser = 1 } - # If it's a real browser, skip bot classification + # If it is a real browser, skip bot classification if (is_real_browser == 1) { next }