签入版本

This commit is contained in:
2026-09-12 18:57:19 +08:00
parent d45b61d808
commit 2857e0f2da
295 changed files with 20713 additions and 13125 deletions
+47
View File
@@ -0,0 +1,47 @@
"""
save_file 安全修复测试
=============================================================
验证临时文件迁移的防护与正式路径保留:
- FLASK_FILE_URL 为空时拒绝外链(原 find('')==0 恒真,外链被当本地文件)
- URL 前缀不匹配时拒绝
- 路径穿越(.. 逃逸临时目录)拒绝
- 正式路径(不含 /temp)原样保留:相对路径(如 /images/notice/...)编辑回传
不被清空,带前缀的绝对地址只去前缀,外链绝对地址仍拒绝
"""
from src.common.utils import rich_text
def test_external_url_rejected_when_prefix_empty(monkeypatch):
monkeypatch.setattr(rich_text, 'FLASK_FILE_URL', '')
assert rich_text.save_file('http://evil.com/x.jpg', 'user') == ""
def test_external_url_nonmatching_prefix_rejected(monkeypatch):
monkeypatch.setattr(rich_text, 'FLASK_FILE_URL', 'http://img.site')
assert rich_text.save_file('http://evil.com/x.jpg', 'user') == ""
def test_path_traversal_rejected(monkeypatch):
monkeypatch.setattr(rich_text, 'FLASK_FILE_URL', 'http://img.site')
# realpath 规范化后逃逸临时目录 → 拒绝
assert rich_text.save_file('http://img.site/temp/../../../../../../etc/passwd', 'user') == ""
def test_non_temp_url_returns_stripped_path(monkeypatch):
monkeypatch.setattr(rich_text, 'FLASK_FILE_URL', 'http://img.site')
# 已是正式路径(无 /temp)→ 去掉前缀返回,不迁移
assert rich_text.save_file('http://img.site/user/avatar.jpg', 'user') == "/user/avatar.jpg"
def test_non_temp_relative_path_kept_when_prefix_mismatch(monkeypatch):
monkeypatch.setattr(rich_text, 'FLASK_FILE_URL', 'http://img.site')
# 编辑回传已保存的相对路径(如通知封面),前缀不匹配也应原样保留,不置空
assert rich_text.save_file('/images/notice/20260314/x.png', 'notice') == "/images/notice/20260314/x.png"
def test_non_temp_relative_path_kept_when_prefix_empty(monkeypatch):
monkeypatch.setattr(rich_text, 'FLASK_FILE_URL', '')
# 未配置文件域名时,相对路径同样原样保留
assert rich_text.save_file('/notice/20260314/x.png', 'notice') == "/notice/20260314/x.png"