Bisheng 中的两个关键路径穿越漏洞
作者: Ro1ME创建于 2026年4月20日更新于 2026年4月20日
Location: src/backend/bisheng/core/cache/utils.py:290-349
Entry Point: src/backend/bisheng/api/v1/workstation.py:177 (knowledgeUpload endpoint)
CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
CVSS 3.1: 9.1 (Critical)
Vulnerable Code
@create_cache_folder
def save_download_file(file_input: Union[bytes, BinaryIO], folder_name: str, filename: str) -> str:
"""
Synchronous I/O intensive tasks:
Write data stream to a temporary file
Simultaneously calculate SHA256
Rename a file based on the hash
"""
# Convert to stream objects
if isinstance(file_input, bytes):
src_stream = BytesIO(file_input)
else:
src_stream = file_input
if hasattr(src_stream, 'seek'):
src_stream.seek(0)
# Prepare a temporary file
cache_path = Path(CACHE_DIR)
folder_path = cache_path / folder_name
# Create the folder if it doesn't exist
if not folder_path.exists():
folder_path.mkdir(exist_ok=True)
temp_filename = f"tmp_{uuid4().hex}"
temp_file_path = folder_path / temp_filename
sha256_hash = hashlib.sha256()
try:
# Write to temporary file and calculate SHA256 simultaneously
with open(temp_file_path, 'wb') as dst_file:
chunk_size = 65536 # 64KB
while True:
chunk = src_stream.read(chunk_size)
if not chunk:
break
sha256_hash.update(chunk)
dst_file.write(chunk)
# calculate final hash
file_hash = sha256_hash.hexdigest()
# Logic for handling filename length limits
safe_filename = filename
if len(filename) > 60:
safe_filename = filename[-60:] # VULNERABILITY: Takes last 60 chars, preserves path traversal
final_file_name = f'{file_hash}_{safe_filename}' # VULNERABILITY: No path validation
final_file_path = folder_path / final_file_name # Path traversal possible here
# Rename (Move) Temporary File to Final Path
if final_file_path.exists():
os.remove(temp_file_path)
return str(final_file_path)
shutil.move(str(temp_file_path), str(final_file_path)) # VULNERABILITY: Moves to traversed path
return str(final_file_path)内容来源: dataelement/bisheng