task_manager: 文件名清洗不删路径分隔符 (加密名 URL-safe base64, 路径安全由客户端兜底); 测试 9 项
This commit is contained in:
+7
-3
@@ -27,10 +27,14 @@ class TaskManager:
|
||||
self.db = db
|
||||
|
||||
def create(self, init_json: dict[str, Any]) -> str:
|
||||
"""POST /init: 建任务, 返回 transfer_id (输入清洗: 文件名/卷数上限)"""
|
||||
# 文件名字段清洗: 长度上限 + 去路径分隔符/控制字符
|
||||
"""POST /init: 建任务, 返回 transfer_id (输入清洗: 文件名/卷数上限)
|
||||
|
||||
文件名只做可打印字符过滤 + 长度截断。不删 / \\ 等路径分隔符:
|
||||
加密文件名是 URL-safe base64 (可能含 - _), 路径安全由客户端 _safe_name
|
||||
和存储目录 (transfer_id) 保证。
|
||||
"""
|
||||
raw = str(init_json.get("file_name", "unnamed"))
|
||||
clean = "".join(c for c in raw if c.isprintable() and c not in "/\\\x00")[:255]
|
||||
clean = "".join(c for c in raw if c.isprintable())[:255]
|
||||
init_json["file_name"] = clean or "unnamed"
|
||||
# 卷数上限: 防超大清单放大 (1MB init / 120B 每卷 spec ≈ 8000)
|
||||
chunks = init_json.get("chunks") or []
|
||||
|
||||
+3
-3
@@ -132,7 +132,7 @@ class ServerPipelineTest(unittest.TestCase):
|
||||
self.assertEqual(st["status"], "done")
|
||||
|
||||
def test_init_sanitizes_file_name(self):
|
||||
# 恶意文件名: 路径分隔符/控制字符清洗, 长度截断
|
||||
# 恶意文件名: 控制字符删除 + 长度截断 (路径分隔符保留, 由客户端 _safe_name 兜底)
|
||||
init_json, chunk_files, _ = _prepare(
|
||||
self.client_kr, os.urandom(64 << 10)
|
||||
)
|
||||
@@ -147,9 +147,9 @@ class ServerPipelineTest(unittest.TestCase):
|
||||
"SELECT file_name FROM files WHERE file_id = ?", (file_id,)
|
||||
).fetchone()
|
||||
name = row["file_name"]
|
||||
self.assertNotIn("/", name)
|
||||
self.assertNotIn("\\", name)
|
||||
self.assertNotIn("\x00", name) # 控制字符被删
|
||||
self.assertLessEqual(len(name), 255)
|
||||
self.assertIn("..", name) # 路径段保留 (加密名含 - _ 不受影响, 明文名由下载端消毒)
|
||||
|
||||
def test_init_oversized_json_rejected(self):
|
||||
# init json 超大 -> 413
|
||||
|
||||
Reference in New Issue
Block a user