| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- """
- 路径验证工具
- """
- import re
- import os
- from fastapi import HTTPException
- def validate_path(path: str, allow_root: bool = False) -> str:
- """
- 验证和清理文件路径,防止路径遍历攻击
-
- Args:
- path: 要验证的路径
- allow_root: 是否允许根路径 "/"
-
- Returns:
- 清理后的路径
-
- Raises:
- HTTPException: 如果路径无效
- """
- if not path:
- raise HTTPException(status_code=400, detail="路径不能为空")
-
- # 移除开头的斜杠(MinIO 规范)
- if path.startswith('/'):
- path = path[1:]
-
- # 检查路径遍历攻击
- if '..' in path or path.startswith('/') or '//' in path:
- raise HTTPException(status_code=400, detail="无效的路径格式,不允许路径遍历")
-
- # 检查危险字符
- dangerous_chars = ['<', '>', '|', '\0', '\r', '\n']
- for char in dangerous_chars:
- if char in path:
- raise HTTPException(status_code=400, detail=f"路径包含非法字符: {char}")
-
- # 检查路径长度
- if len(path) > 1024:
- raise HTTPException(status_code=400, detail="路径长度超过限制")
-
- return path
- def sanitize_filename(filename: str) -> str:
- """
- 清理文件名,移除危险字符
-
- Args:
- filename: 原始文件名
-
- Returns:
- 清理后的文件名
- """
- if not filename:
- raise HTTPException(status_code=400, detail="文件名不能为空")
- filename = os.path.basename(filename)
- # 移除路径分隔符
- filename = filename.replace('/', '').replace('\\', '')
-
- # 移除危险字符
- dangerous_chars = ['<', '>', '|', ':', '"', '?', '*', '\0']
- for char in dangerous_chars:
- filename = filename.replace(char, '_')
-
- # 限制长度
- if len(filename) > 255:
- name, ext = filename.rsplit('.', 1) if '.' in filename else (filename, '')
- filename = name[:250] + ('.' + ext if ext else '')
-
- return filename
|