mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-03-06 12:20:45 +01:00
security fixes
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from django.shortcuts import render,redirect
|
||||
from loginSystem.models import Administrator
|
||||
from loginSystem.views import loadLoginPage
|
||||
@@ -326,6 +327,23 @@ def downloadFile(request):
|
||||
if fileToDownload.find('..') > -1 or fileToDownload.find(homePath) == -1:
|
||||
return HttpResponse("Unauthorized access.")
|
||||
|
||||
# SECURITY: Check for symlink attacks - resolve the real path and verify it stays within homePath
|
||||
try:
|
||||
realPath = os.path.realpath(fileToDownload)
|
||||
|
||||
# Verify the resolved path is still within the user's home directory
|
||||
if not realPath.startswith(homePath + '/') and realPath != homePath:
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f"Symlink attack blocked: {fileToDownload} -> {realPath} (outside {homePath})")
|
||||
return HttpResponse("Unauthorized access: Symlink points outside allowed directory.")
|
||||
|
||||
# Verify it's a regular file
|
||||
if not os.path.isfile(realPath):
|
||||
return HttpResponse("Unauthorized access: Not a valid file.")
|
||||
|
||||
except OSError as e:
|
||||
return HttpResponse("Unauthorized access: Cannot verify file path.")
|
||||
|
||||
response = HttpResponse(content_type='application/force-download')
|
||||
response['Content-Disposition'] = 'attachment; filename=%s' % (fileToDownload.split('/')[-1])
|
||||
response['X-LiteSpeed-Location'] = '%s' % (fileToDownload)
|
||||
@@ -351,6 +369,37 @@ def RootDownloadFile(request):
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
# SECURITY: Prevent path traversal attacks
|
||||
if fileToDownload.find('..') > -1:
|
||||
return HttpResponse("Unauthorized access: Path traversal detected.")
|
||||
|
||||
# SECURITY: Check for symlink attacks - resolve the real path and verify it's safe
|
||||
try:
|
||||
# Get the real path (resolves symlinks)
|
||||
realPath = os.path.realpath(fileToDownload)
|
||||
|
||||
# SECURITY: Prevent access to sensitive system files
|
||||
sensitive_paths = ['/etc/shadow', '/etc/passwd', '/etc/sudoers', '/root/.ssh',
|
||||
'/var/log', '/proc', '/sys', '/dev']
|
||||
for sensitive in sensitive_paths:
|
||||
if realPath.startswith(sensitive):
|
||||
return HttpResponse("Unauthorized access: Access to system files denied.")
|
||||
|
||||
# SECURITY: Verify the file exists and is a regular file (not a directory or device)
|
||||
if not os.path.isfile(realPath):
|
||||
return HttpResponse("Unauthorized access: Not a valid file.")
|
||||
|
||||
# SECURITY: Check if the original path differs from real path (symlink detection)
|
||||
# Allow the download only if the real path is within allowed directories
|
||||
# For admin, we'll be more permissive but still block sensitive system files
|
||||
if fileToDownload != realPath:
|
||||
# This is a symlink - log it and verify destination is safe
|
||||
logging.CyberCPLogFileWriter.writeToFile(
|
||||
f"Symlink download detected: {fileToDownload} -> {realPath}")
|
||||
|
||||
except OSError as e:
|
||||
return HttpResponse("Unauthorized access: Cannot verify file path.")
|
||||
|
||||
response = HttpResponse(content_type='application/force-download')
|
||||
response['Content-Disposition'] = 'attachment; filename=%s' % (fileToDownload.split('/')[-1])
|
||||
response['X-LiteSpeed-Location'] = '%s' % (fileToDownload)
|
||||
|
||||
Reference in New Issue
Block a user