From 56789a2c98e5eec16e1d1d18b3c90b846ab0b771 Mon Sep 17 00:00:00 2001 From: warren618 Date: Mon, 23 Mar 2026 02:50:12 +0800 Subject: [PATCH] fix(security): sanitize user-supplied IDs to prevent path traversal simulation_id, project_id, report_id, and platform parameters from API requests are used directly in os.path.join() to construct file paths. An attacker can use values like "../../etc" to read/write files or create directories outside the intended data directory. Added validation: reject any ID that differs from its os.path.basename(), which catches path separators and traversal sequences. --- backend/app/models/project.py | 5 ++++- backend/app/services/report_agent.py | 5 ++++- backend/app/services/simulation_manager.py | 10 ++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/backend/app/models/project.py b/backend/app/models/project.py index 08978937..0ae91210 100644 --- a/backend/app/models/project.py +++ b/backend/app/models/project.py @@ -112,7 +112,10 @@ class ProjectManager: @classmethod def _get_project_dir(cls, project_id: str) -> str: """获取项目目录路径""" - return os.path.join(cls.PROJECTS_DIR, project_id) + safe_id = os.path.basename(project_id) + if not safe_id or safe_id != project_id: + raise ValueError(f"Invalid project_id: {project_id}") + return os.path.join(cls.PROJECTS_DIR, safe_id) @classmethod def _get_project_meta_path(cls, project_id: str) -> str: diff --git a/backend/app/services/report_agent.py b/backend/app/services/report_agent.py index 02ca5bdc..52aa0aa8 100644 --- a/backend/app/services/report_agent.py +++ b/backend/app/services/report_agent.py @@ -1909,7 +1909,10 @@ class ReportManager: @classmethod def _get_report_folder(cls, report_id: str) -> str: """获取报告文件夹路径""" - return os.path.join(cls.REPORTS_DIR, report_id) + safe_id = os.path.basename(report_id) + if not safe_id or safe_id != report_id: + raise ValueError(f"Invalid report_id: {report_id}") + return os.path.join(cls.REPORTS_DIR, safe_id) @classmethod def _ensure_report_folder(cls, report_id: str) -> str: diff --git a/backend/app/services/simulation_manager.py b/backend/app/services/simulation_manager.py index 96c496fd..b7b3bc08 100644 --- a/backend/app/services/simulation_manager.py +++ b/backend/app/services/simulation_manager.py @@ -137,7 +137,10 @@ class SimulationManager: def _get_simulation_dir(self, simulation_id: str) -> str: """获取模拟数据目录""" - sim_dir = os.path.join(self.SIMULATION_DATA_DIR, simulation_id) + safe_id = os.path.basename(simulation_id) + if not safe_id or safe_id != simulation_id: + raise ValueError(f"Invalid simulation_id: {simulation_id}") + sim_dir = os.path.join(self.SIMULATION_DATA_DIR, safe_id) os.makedirs(sim_dir, exist_ok=True) return sim_dir @@ -484,7 +487,10 @@ class SimulationManager: raise ValueError(f"模拟不存在: {simulation_id}") sim_dir = self._get_simulation_dir(simulation_id) - profile_path = os.path.join(sim_dir, f"{platform}_profiles.json") + safe_platform = os.path.basename(platform) + if not safe_platform or safe_platform != platform: + raise ValueError(f"Invalid platform: {platform}") + profile_path = os.path.join(sim_dir, f"{safe_platform}_profiles.json") if not os.path.exists(profile_path): return []