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.
This commit is contained in:
parent
1536a79334
commit
56789a2c98
|
|
@ -112,7 +112,10 @@ class ProjectManager:
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_project_dir(cls, project_id: str) -> str:
|
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
|
@classmethod
|
||||||
def _get_project_meta_path(cls, project_id: str) -> str:
|
def _get_project_meta_path(cls, project_id: str) -> str:
|
||||||
|
|
|
||||||
|
|
@ -1909,7 +1909,10 @@ class ReportManager:
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_report_folder(cls, report_id: str) -> str:
|
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
|
@classmethod
|
||||||
def _ensure_report_folder(cls, report_id: str) -> str:
|
def _ensure_report_folder(cls, report_id: str) -> str:
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,10 @@ class SimulationManager:
|
||||||
|
|
||||||
def _get_simulation_dir(self, simulation_id: str) -> str:
|
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)
|
os.makedirs(sim_dir, exist_ok=True)
|
||||||
return sim_dir
|
return sim_dir
|
||||||
|
|
||||||
|
|
@ -484,7 +487,10 @@ class SimulationManager:
|
||||||
raise ValueError(f"模拟不存在: {simulation_id}")
|
raise ValueError(f"模拟不存在: {simulation_id}")
|
||||||
|
|
||||||
sim_dir = self._get_simulation_dir(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):
|
if not os.path.exists(profile_path):
|
||||||
return []
|
return []
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue