diff --git a/filemanager/views.py b/filemanager/views.py index 864ecc993..6e5b54149 100644 --- a/filemanager/views.py +++ b/filemanager/views.py @@ -306,13 +306,20 @@ def downloadFile(request): try: userID = request.session['userID'] admin = Administrator.objects.get(pk=userID) - from urllib.parse import quote - from django.utils.encoding import iri_to_uri + from urllib.parse import unquote + import os - fileToDownload = request.build_absolute_uri().split('fileToDownload')[1][1:] - fileToDownload = iri_to_uri(fileToDownload) + # Properly get fileToDownload from query parameters + fileToDownload = request.GET.get('fileToDownload') + if not fileToDownload: + return HttpResponse("Unauthorized access: Not a valid file.") + + # URL decode the file path + fileToDownload = unquote(fileToDownload) domainName = request.GET.get('domainName') + if not domainName: + return HttpResponse("Unauthorized access: Domain not specified.") currentACL = ACLManager.loadedACL(userID) @@ -323,8 +330,18 @@ def downloadFile(request): homePath = '/home/%s' % (domainName) - if fileToDownload.find('..') > -1 or fileToDownload.find(homePath) == -1: - return HttpResponse("Unauthorized access.") + # Security checks: prevent directory traversal and ensure file is within domain's home path + if '..' in fileToDownload or not fileToDownload.startswith(homePath): + return HttpResponse("Unauthorized access: Not a valid file.") + + # Normalize path to prevent any path traversal attempts + fileToDownload = os.path.normpath(fileToDownload) + if not fileToDownload.startswith(homePath): + return HttpResponse("Unauthorized access: Not a valid file.") + + # Verify file exists and is a file (not a directory) + if not os.path.exists(fileToDownload) or not os.path.isfile(fileToDownload): + return HttpResponse("Unauthorized access: Not a valid file.") response = HttpResponse(content_type='application/force-download') response['Content-Disposition'] = 'attachment; filename=%s' % (fileToDownload.split('/')[-1]) @@ -338,11 +355,16 @@ def downloadFile(request): def RootDownloadFile(request): try: userID = request.session['userID'] - from urllib.parse import quote - from django.utils.encoding import iri_to_uri + from urllib.parse import unquote + import os - fileToDownload = request.build_absolute_uri().split('fileToDownload')[1][1:] - fileToDownload = iri_to_uri(fileToDownload) + # Properly get fileToDownload from query parameters + fileToDownload = request.GET.get('fileToDownload') + if not fileToDownload: + return HttpResponse("Unauthorized access: Not a valid file.") + + # URL decode the file path + fileToDownload = unquote(fileToDownload) currentACL = ACLManager.loadedACL(userID) @@ -351,6 +373,17 @@ def RootDownloadFile(request): else: return ACLManager.loadError() + # Security checks: prevent directory traversal + if '..' in fileToDownload: + return HttpResponse("Unauthorized access: Not a valid file.") + + # Normalize path to prevent any path traversal attempts + fileToDownload = os.path.normpath(fileToDownload) + + # Verify file exists and is a file (not a directory) + if not os.path.exists(fileToDownload) or not os.path.isfile(fileToDownload): + return HttpResponse("Unauthorized access: Not a valid file.") + response = HttpResponse(content_type='application/force-download') response['Content-Disposition'] = 'attachment; filename=%s' % (fileToDownload.split('/')[-1]) response['X-LiteSpeed-Location'] = '%s' % (fileToDownload) diff --git a/plogical/modSec.py b/plogical/modSec.py index 1e3c38f1f..ef2c36262 100644 --- a/plogical/modSec.py +++ b/plogical/modSec.py @@ -141,22 +141,24 @@ class modSec: writeToFile.writelines("ModSecurity Installed.[200]\n") writeToFile.close() - # Check if custom OLS binary is installed - if so, replace with compatible ModSecurity - custom_ols_marker = "/usr/local/lsws/modules/cyberpanel_ols.so" - if os.path.exists(custom_ols_marker): - writeToFile = open(modSec.installLogPath, 'a') - writeToFile.writelines("Custom OLS detected, installing compatible ModSecurity...\n") - writeToFile.close() + # Always download and install compatible ModSecurity binary to prevent LMDB dependency crashes + # This fixes the "undefined symbol: mdb_env_create" error that causes OpenLiteSpeed to crash + writeToFile = open(modSec.installLogPath, 'a') + writeToFile.writelines("Downloading compatible ModSecurity binary to prevent LMDB dependency issues...\n") + writeToFile.close() - platform = modSec.detectPlatform() - if modSec.downloadCompatibleModSec(platform): - writeToFile = open(modSec.installLogPath, 'a') - writeToFile.writelines("Compatible ModSecurity installed successfully.\n") - writeToFile.close() - else: - writeToFile = open(modSec.installLogPath, 'a') - writeToFile.writelines("WARNING: Could not install compatible ModSecurity. May experience crashes.\n") - writeToFile.close() + platform = modSec.detectPlatform() + if modSec.downloadCompatibleModSec(platform): + writeToFile = open(modSec.installLogPath, 'a') + writeToFile.writelines("Compatible ModSecurity binary installed successfully.\n") + writeToFile.close() + logging.CyberCPLogFileWriter.writeToFile("Compatible ModSecurity binary installed to prevent LMDB dependency crashes [installModSec]") + else: + writeToFile = open(modSec.installLogPath, 'a') + writeToFile.writelines("WARNING: Could not install compatible ModSecurity binary. Using package-manager binary instead.\n") + writeToFile.writelines("WARNING: If you experience crashes (SIGSEGV signal 11), manually download compatible binary.\n") + writeToFile.close() + logging.CyberCPLogFileWriter.writeToFile("WARNING: Could not install compatible ModSecurity binary - may experience LMDB dependency crashes [installModSec]") return 1 except BaseException as msg: