Fix issue #1643: Fix downloadFile function to properly parse query parameters

- Changed from incorrect URI splitting to proper request.GET.get() method
- Added proper URL decoding with unquote()
- Fixed both downloadFile and RootDownloadFile functions
- Added path normalization for additional security
- Added file existence validation
- Improved error messages to match reported error format

This fixes the 'Unauthorized access: Not a valid file' error when downloading files from the file manager.
This commit is contained in:
master3395
2026-01-07 23:47:23 +01:00
parent b1627aff0f
commit ea5be31de5

View File

@@ -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)