Harden endpoint authorization, filename sanitization, and updater imports
CI Test Suite / Run Component Tests & Pipeline Verification (push) Failing after 1m21s

This commit is contained in:
2026-10-02 22:31:17 +02:00
parent f0c4a82fc3
commit fe9d43cab6
3 changed files with 12 additions and 7 deletions
+9 -6
View File
@@ -1526,7 +1526,7 @@ def download_client_update_package(os: Optional[str] = "windows", os_name: Optio
@app.post("/api/server/client-package/upload") @app.post("/api/server/client-package/upload")
async def upload_client_package( async def upload_client_package(
request: Request, request: Request,
user: str = Depends(get_current_user_optional) auth_user: str = Depends(require_admin_auth)
): ):
""" """
Uploads a new client executable/installer into the server's update distribution repository. Uploads a new client executable/installer into the server's update distribution repository.
@@ -1534,6 +1534,7 @@ async def upload_client_package(
or raw stream with headers 'X-Package-OS', 'X-Package-Filename', 'X-Package-Version'. or raw stream with headers 'X-Package-OS', 'X-Package-Filename', 'X-Package-Version'.
""" """
import base64 import base64
import os as _os
mgr: ServerUpdateManager = SERVER_STATE.get("update_manager") or UPDATE_MANAGER mgr: ServerUpdateManager = SERVER_STATE.get("update_manager") or UPDATE_MANAGER
content_type = request.headers.get("content-type", "") content_type = request.headers.get("content-type", "")
@@ -1546,21 +1547,23 @@ async def upload_client_package(
body = await request.json() body = await request.json()
os_type = body.get("os", "windows") os_type = body.get("os", "windows")
version = body.get("version") version = body.get("version")
filename = body.get("filename") or ("LOGAR_Client_Setup.exe" if os_type == "windows" else "Linux_Client.bin") raw_name = body.get("filename") or ("LOGAR_Client_Setup.exe" if os_type == "windows" else "Linux_Client.bin")
filename = _os.path.basename(str(raw_name))
b64_data = body.get("data_base64", "") b64_data = body.get("data_base64", "")
file_bytes = base64.b64decode(b64_data) file_bytes = base64.b64decode(b64_data)
else: else:
os_type = request.headers.get("X-Package-OS", "windows") os_type = request.headers.get("X-Package-OS", "windows")
version = request.headers.get("X-Package-Version") version = request.headers.get("X-Package-Version")
filename = request.headers.get("X-Package-Filename") or ("LOGAR_Client_Setup.exe" if os_type == "windows" else "Linux_Client.bin") raw_name = request.headers.get("X-Package-Filename") or ("LOGAR_Client_Setup.exe" if os_type == "windows" else "Linux_Client.bin")
filename = _os.path.basename(str(raw_name))
file_bytes = await request.body() file_bytes = await request.body()
if not file_bytes: if not file_bytes:
raise HTTPException(status_code=400, detail="Empty package payload.") raise HTTPException(status_code=400, detail="Empty package payload.")
temp_dir = os.path.join(mgr.update_dir, "temp") temp_dir = _os.path.join(mgr.update_dir, "temp")
os.makedirs(temp_dir, exist_ok=True) _os.makedirs(temp_dir, exist_ok=True)
temp_path = os.path.join(temp_dir, filename) temp_path = _os.path.join(temp_dir, filename)
with open(temp_path, "wb") as f: with open(temp_path, "wb") as f:
f.write(file_bytes) f.write(file_bytes)
+1
View File
@@ -14,6 +14,7 @@ import tempfile
import subprocess import subprocess
import urllib.request import urllib.request
import urllib.error import urllib.error
import urllib.parse
from typing import Dict, Any, Optional, Tuple from typing import Dict, Any, Optional, Tuple
try: try:
+2 -1
View File
@@ -89,7 +89,8 @@ class ServerUpdateManager:
target_dir = os.path.join(self.update_dir, norm_os) target_dir = os.path.join(self.update_dir, norm_os)
os.makedirs(target_dir, exist_ok=True) os.makedirs(target_dir, exist_ok=True)
target_name = filename or os.path.basename(file_path) raw_name = filename or os.path.basename(file_path)
target_name = os.path.basename(raw_name)
dest_path = os.path.join(target_dir, target_name) dest_path = os.path.join(target_dir, target_name)
if os.path.abspath(file_path) != os.path.abspath(dest_path): if os.path.abspath(file_path) != os.path.abspath(dest_path):