mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-04-28 03:30:23 +00:00
fix(api): block path traversal in download_work_dir_file (CVE-2026-4307)
Reject download requests whose resolved path escapes the runtime base directory before file metadata lookup or streaming. This keeps valid in-base absolute paths working in both Docker and development setups while preventing arbitrary file reads via /download_work_dir_file (CVE-2026-4307). Reported by Edward-x (@YLChen-007). Thanks again. Refs: - https://nvd.nist.gov/vuln/detail/CVE-2026-4307 - https://gist.github.com/YLChen-007/1819c843ad26aaaaecdc768a789df022 - https://vuldb.com/vuln/351337/cti
This commit is contained in:
parent
071194281c
commit
0e3e8a159a
1 changed files with 26 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ import base64
|
|||
from io import BytesIO
|
||||
import mimetypes
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Response
|
||||
from helpers.api import ApiHandler, Input, Output, Request
|
||||
|
|
@ -85,6 +86,24 @@ def make_disposition(download_name: str) -> str:
|
|||
return f'attachment; filename="{ascii_fallback}"; filename*=UTF-8\'\'{utf8_name}'
|
||||
|
||||
|
||||
def resolve_download_path(path: str) -> str:
|
||||
"""Resolve a requested download path and keep it within the runtime base dir."""
|
||||
base_dir = Path(files.get_base_dir()).resolve()
|
||||
candidate = Path(path)
|
||||
|
||||
if candidate.is_absolute():
|
||||
resolved = candidate.resolve()
|
||||
else:
|
||||
resolved = (base_dir / candidate).resolve()
|
||||
|
||||
try:
|
||||
resolved.relative_to(base_dir)
|
||||
except ValueError as exc:
|
||||
raise ValueError("Invalid file path") from exc
|
||||
|
||||
return str(resolved)
|
||||
|
||||
|
||||
class DownloadFile(ApiHandler):
|
||||
|
||||
@classmethod
|
||||
|
|
@ -98,6 +117,13 @@ class DownloadFile(ApiHandler):
|
|||
if not file_path.startswith("/"):
|
||||
file_path = f"/{file_path}"
|
||||
|
||||
try:
|
||||
file_path = await runtime.call_development_function(
|
||||
resolve_download_path, file_path
|
||||
)
|
||||
except ValueError as exc:
|
||||
return Response(str(exc), status=400)
|
||||
|
||||
file = await runtime.call_development_function(
|
||||
file_info.get_file_info, file_path
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue