TraceStudio/server/app/core/security.py

87 lines
2.1 KiB
Python
Raw Permalink Normal View History

2026-01-12 21:51:45 +08:00
"""
路径安全检查模块
防止路径遍历攻击和非法访问
"""
from pathlib import Path
from typing import Tuple
def is_safe_path(base_path: Path, target_path: Path) -> bool:
"""
检查目标路径是否在基础路径内
Args:
base_path: 基础路径如用户根目录
target_path: 目标路径
Returns:
是否安全
"""
try:
# 解析为绝对路径
base = base_path.resolve()
target = target_path.resolve()
# 检查target是否在base下
return str(target).startswith(str(base))
except Exception:
return False
def validate_filename(filename: str) -> Tuple[bool, str]:
"""
验证文件名是否合法
Args:
filename: 文件名
Returns:
(是否合法, 错误信息)
"""
# 禁止的字符
forbidden_chars = ['<', '>', ':', '"', '|', '?', '*', '\0']
for char in forbidden_chars:
if char in filename:
return False, f"文件名包含非法字符: {char}"
# 禁止的文件名
forbidden_names = [
'CON', 'PRN', 'AUX', 'NUL',
'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
]
name_without_ext = Path(filename).stem.upper()
if name_without_ext in forbidden_names:
return False, f"文件名不允许: {filename}"
# 检查路径遍历
if '..' in filename or filename.startswith('/') or filename.startswith('\\'):
return False, "文件名包含路径遍历字符"
return True, ""
def sanitize_path(path_str: str) -> str:
"""
清理路径字符串
Args:
path_str: 原始路径字符串
Returns:
清理后的路径
"""
# 移除开头的斜杠
path_str = path_str.lstrip('/')
path_str = path_str.lstrip('\\')
# 标准化路径分隔符
path_str = path_str.replace('\\', '/')
# 移除连续的斜杠
while '//' in path_str:
path_str = path_str.replace('//', '/')
return path_str