mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-30 09:42:21 +01:00
fix(upload,sw): sanitize and confine upload paths and align service worker precache token
This commit is contained in:
@@ -30,6 +30,7 @@ from src.upload_handler import (
|
|||||||
UploadCleanupSafetyError,
|
UploadCleanupSafetyError,
|
||||||
count_recent_uploads,
|
count_recent_uploads,
|
||||||
extract_upload_ids,
|
extract_upload_ids,
|
||||||
|
secure_filename,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -454,16 +455,19 @@ def setup_upload_routes(upload_handler):
|
|||||||
original_name = info.get("name", file_id)
|
original_name = info.get("name", file_id)
|
||||||
file_owner = info.get("owner") if info else None
|
file_owner = info.get("owner") if info else None
|
||||||
_verify_upload_access(request, file_owner)
|
_verify_upload_access(request, file_owner)
|
||||||
path = _resolve_upload_path(file_id)
|
path = os.path.normpath(_resolve_upload_path(file_id))
|
||||||
|
upload_root = os.path.normpath(_upload_root())
|
||||||
|
if not (path == upload_root or path.startswith(upload_root + os.sep)) or not _path_inside_upload_dir(path):
|
||||||
|
raise HTTPException(403, "Access denied")
|
||||||
mime = (info or {}).get("mime") or _mt.guess_type(path)[0] or "application/octet-stream"
|
mime = (info or {}).get("mime") or _mt.guess_type(path)[0] or "application/octet-stream"
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
# Downscaled thumbnail for image previews — generated once and cached.
|
# Downscaled thumbnail for image previews — generated once and cached.
|
||||||
# Skip generation during HEAD probe to avoid loading/processing whole image.
|
# Skip generation during HEAD probe to avoid loading/processing whole image.
|
||||||
if thumb and mime.startswith("image/"):
|
if thumb and mime.startswith("image/"):
|
||||||
thumb_dir = os.path.join(_upload_root(), ".thumbs")
|
thumb_dir = os.path.normpath(os.path.join(upload_root, ".thumbs"))
|
||||||
safe_file_id = os.path.basename(file_id)
|
safe_file_id = secure_filename(os.path.basename(file_id))
|
||||||
thumb_path = os.path.join(thumb_dir, safe_file_id + ".jpg")
|
thumb_path = os.path.normpath(os.path.join(thumb_dir, safe_file_id + ".jpg"))
|
||||||
if not _path_inside_upload_dir(thumb_path) or not is_inside(thumb_dir, thumb_path):
|
if not (thumb_path.startswith(thumb_dir + os.sep) and _path_inside_upload_dir(thumb_path)):
|
||||||
raise HTTPException(403, "Access denied")
|
raise HTTPException(403, "Access denied")
|
||||||
if request.method == "HEAD":
|
if request.method == "HEAD":
|
||||||
if (os.path.isfile(thumb_path)
|
if (os.path.isfile(thumb_path)
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ const PRECACHE = [
|
|||||||
'/static/css/00-tokens.css?v=20260929csssplit',
|
'/static/css/00-tokens.css?v=20260929csssplit',
|
||||||
'/static/css/01-agent-chat.css?v=20260929csssplit',
|
'/static/css/01-agent-chat.css?v=20260929csssplit',
|
||||||
'/static/css/02-compare.css?v=20260929csssplit',
|
'/static/css/02-compare.css?v=20260929csssplit',
|
||||||
'/static/css/03-agent-chat.css?v=20261017titlefade1',
|
'/static/css/03-agent-chat.css?v=20260929csssplit',
|
||||||
'/static/css/04-memory.css?v=20260929csssplit',
|
'/static/css/04-memory.css?v=20260929csssplit',
|
||||||
'/static/css/05-documents.css?v=20260929csssplit',
|
'/static/css/05-documents.css?v=20260929csssplit',
|
||||||
'/static/css/06-admin-settings.css?v=20260929csssplit',
|
'/static/css/06-admin-settings.css?v=20260929csssplit',
|
||||||
|
|||||||
Reference in New Issue
Block a user