Fix OWASP CRS UI toggle state issues and improve installation reliability

This commit resolves issues where the OWASP CRS toggle in ModSecurity settings
would appear to flip back to OFF even when installation succeeded, and improves
detection of manually installed OWASP CRS rules.

Issues Fixed:
1. Toggle not updating immediately after installation/uninstallation
2. Manual OWASP installations to rules.conf not detected by toggle
3. Silent installation failures without detailed error logging

Changes:

firewall/static/firewall/firewall.js:
- Update toggle state immediately after successful installation (getOWASPAndComodoStatus(true))
- Update toggle state after failed installation to show correct OFF state
- Provides instant visual feedback instead of requiring page refresh

firewall/firewallManager.py (getOWASPAndComodoStatus):
- Expand detection logic to check both httpd_config.conf AND rules.conf
- Detect manual OWASP installations (Include/modsecurity_rules_file with owasp/crs-setup)
- Case-insensitive pattern matching for better compatibility

plogical/modSec.py (setupOWASPRules):
- Add specific error logging for each installation step failure
- Log detailed messages: directory creation, download, extraction, configuration
- Helps diagnose: network issues, missing tools (wget/unzip), permission problems

Impact:
- Toggle correctly reflects OWASP CRS state after enable/disable operations
- Manual installations following external tutorials now detected correctly
- Installation failures are logged with specific error messages for debugging
- Improves UX by eliminating perception that "toggle keeps flipping back"

Fixes: OWASP CRS toggle UI bug
Related: Community thread https://community.cyberpanel.net/t/4-mod-security-rules-packages/133/8
Related: Ticket #GTPDPO7EV
This commit is contained in:
usmannasir
2025-11-24 01:53:36 +05:00
parent 836a6e26a7
commit ae020ece7b
3 changed files with 28 additions and 1 deletions

View File

@@ -1020,6 +1020,22 @@ class FirewallManager:
if owaspInstalled == 1 and comodoInstalled == 1:
break
# Also check rules.conf for manual OWASP installations
if owaspInstalled == 0:
rulesConfPath = os.path.join(virtualHostUtilities.Server_root, "conf/modsec/rules.conf")
if os.path.exists(rulesConfPath):
try:
command = "sudo cat " + rulesConfPath
rulesConfig = ProcessUtilities.outputExecutioner(command).splitlines()
for items in rulesConfig:
# Check for OWASP includes in rules.conf (case-insensitive)
if ('owasp' in items.lower() or 'crs-setup' in items.lower()) and \
('include' in items.lower() or 'modsecurity_rules_file' in items.lower()):
owaspInstalled = 1
break
except:
pass
final_dic = {
'modSecInstalled': 1,
'owaspInstalled': owaspInstalled,

View File

@@ -1366,7 +1366,8 @@ app.controller('modSecRulesPack', function ($scope, $http, $timeout, $window) {
$scope.installationFailed = true;
$scope.installationSuccess = false;
getOWASPAndComodoStatus(false);
// Update toggle state immediately to reflect installation result
getOWASPAndComodoStatus(true);
} else {
$scope.modsecLoading = true;
@@ -1379,6 +1380,9 @@ app.controller('modSecRulesPack', function ($scope, $http, $timeout, $window) {
$scope.installationSuccess = true;
$scope.errorMessage = response.data.error_message;
// Update toggle to reflect failed installation (will show OFF)
getOWASPAndComodoStatus(true);
}
}

View File

@@ -405,6 +405,7 @@ modsecurity_rules_file /usr/local/lsws/conf/modsec/rules.conf
command = 'mkdir -p /usr/local/lsws/conf/modsec'
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to create modsec directory [setupOWASPRules]")
return 0
if os.path.exists(pathToOWASFolderNew):
@@ -420,30 +421,35 @@ modsecurity_rules_file /usr/local/lsws/conf/modsec/rules.conf
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to download OWASP CRS from GitHub. Check internet connection. [setupOWASPRules]")
return 0
command = "unzip -o /usr/local/lsws/conf/modsec/owasp.zip -d /usr/local/lsws/conf/modsec/"
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to extract OWASP CRS zip file. Ensure unzip is installed. [setupOWASPRules]")
return 0
command = 'mv /usr/local/lsws/conf/modsec/coreruleset-3.3.2 /usr/local/lsws/conf/modsec/owasp-modsecurity-crs-3.0-master'
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to rename OWASP CRS directory. File may already exist. [setupOWASPRules]")
return 0
command = 'mv %s/crs-setup.conf.example %s/crs-setup.conf' % (pathToOWASFolderNew, pathToOWASFolderNew)
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to setup crs-setup.conf configuration file. [setupOWASPRules]")
return 0
command = 'mv %s/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example %s/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf' % (pathToOWASFolderNew, pathToOWASFolderNew)
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to setup REQUEST-900 exclusion rules. [setupOWASPRules]")
return 0
command = 'mv %s/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example %s/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf' % (
@@ -451,6 +457,7 @@ modsecurity_rules_file /usr/local/lsws/conf/modsec/rules.conf
result = subprocess.call(shlex.split(command))
if result != 0:
logging.CyberCPLogFileWriter.writeToFile("Failed to setup RESPONSE-999 exclusion rules. [setupOWASPRules]")
return 0
content = """include {pathToOWASFolderNew}/crs-setup.conf