返回 MoneyPrinterTurbo
file_security.py
根目录 / app / utils / file_security.py
1 import os
2
3
4 def resolve_path_within_directory(
5 base_dir: str,
6 unsafe_path: str,
7 *,
8 require_file: bool = True,
9 ) -> str:
10 # 用户传入的路径可能是文件名、相对路径、绝对路径,也可能夹带 `../`。
11 # 这里统一解析成真实路径,并用 commonpath 判断它是否仍在允许目录内。
12 # 这样比简单判断字符串前缀可靠,可以覆盖符号链接、重复分隔符、相对路径
13 # 等场景,适用于上传目录、素材目录、任务产物目录这类白名单目录。
14 if not unsafe_path:
15 raise ValueError("empty path is not allowed")
16
17 base_dir_real = os.path.realpath(base_dir)
18 candidate_path = unsafe_path
19 if not os.path.isabs(candidate_path):
20 candidate_path = os.path.join(base_dir_real, candidate_path)
21
22 resolved_path = os.path.realpath(candidate_path)
23 try:
24 common_path = os.path.commonpath([base_dir_real, resolved_path])
25 except ValueError as exc:
26 # Windows 下不同盘符会触发 ValueError,这类路径一定不属于允许目录。
27 raise ValueError("path is outside the allowed directory") from exc
28
29 if common_path != base_dir_real:
30 raise ValueError("path is outside the allowed directory")
31
32 if require_file and not os.path.isfile(resolved_path):
33 raise ValueError("file does not exist")
34
35 return resolved_path
36
36 lines PYTHON