fix: PR#312安全债务 4个P1修复(路径安全+数量上限) #322
Reference in New Issue
Block a user
Delete Branch "fix/pr312-security-debt-p1"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
PR #312(多轨道混音+字幕渲染+视频拼接)已合并到develop,但审计发现4个P1安全债务,需尽快修复。
修复内容
P1-1 多轨道混音 audio_path 路径安全
_validate_audio_path()路径白名单校验P1-2 混音轨道数量上限
MAX_AUDIO_TRACKS = 8轨道数上限P1-3 视频拼接 video_path 路径安全
_validate_video_path()路径白名单校验P1-4 拼接段数上限
MAX_CONCAT_SEGMENTS = 50段数上限P1-5 字幕文件路径安全
build_subtitle_filter()新增路径安全校验work_dir参数,向后兼容基础设施
path_security.py统一路径安全校验模块测试
降级策略
安全复审结果:⚠️ 有条件通过
4 个 P1 修复进度:2 项已修复 ✅,2 项需修复 ⚠️
✅ 已修复(2项)
P1-2 混音轨道数量上限(8轨)
MAX_AUDIO_TRACKS = 8在mix_multi_track入口校验P1-3 拼接段数上限(50段)
MAX_CONCAT_SEGMENTS = 50在concat_videos入口校验⚠️ 需修复(2项 - 合并前必须解决)
P1-1 audio_path / video_path 路径安全 — 存在绕过漏洞
_validate_audio_path/_validate_video_path/_validate_subtitle_path中,绝对路径以work_dir字符串开头时,同时跳过了safe_resolve_path的 containment 检查(allow_outside=True)和is_in_allowed_dirs检查(因为startswith(work_dir)为真)。绕过方式:
{work_dir}/../../../etc/passwd根因:用原始路径的
startswith判断而非解析后的真实路径 containment 判断。修复建议:对解析后的路径(
Path.resolve()结果)做 containment 判断,而不是对原始路径做字符串前缀匹配。P1-4 字幕文件路径安全 — 默认参数导致安全旁路
build_subtitle_filter(ass_path, work_dir=None)中,work_dir默认为None时取Path(ass_path).parent作为 base_dir。对于绝对路径,安全校验完全失效(路径永远在自己的父目录内)。影响:所有未显式传入
work_dir的调用方均无有效路径安全保障。修复建议:将
work_dir改为必填参数(secure by default),或在work_dir=None时对绝对路径强制走is_in_allowed_dirs检查。📝 新增发现(非阻塞,建议优化)
_validate_*_path函数逻辑几乎完全一致,建议抽取到path_security.py作为通用函数packages/shared/url_security.py(413行)未在 PR 描述中说明,建议确认是否应随本 PR 合入详细报告已上传,修复以上 2 个 P1 绕过漏洞后可通过复审。
二轮复审结果(commit 47bf6bfa)
结论:⚠️ 有条件通过(2个P1绕过漏洞核心已修复,需修复2个测试回归后合并)
P1-1 路径校验 realpath 规范化 ✅ 已修复
三处
_validate_*_path(audio / video / subtitle)均已修复,统一改用resolved_path.relative_to(resolved_work_dir)比较:resolve()规范化{work_dir}/../../../etc/passwd伪前缀遍历已被拦截/etc/hostname等外部文件也被拦截(realpath 解析符号链接)test_*_path_traversal_bypass_startswith)全部通过P1-2 build_subtitle_filter work_dir 必填 ⚠️ 基本修复
已添加运行时校验:
work_dir is None or not str(work_dir).strip()时抛出PathSecurityErrortest_build_filter_work_dir_required单测覆盖三种场景= None:不是严格意义上的必填参数,类型检查器无法发现遗漏(建议移除默认值)test_multi_track_subtitle_concat.py::TestSubtitleFilter下的 2 个测试用例调用build_subtitle_filter时未传work_dir,导致失败回归验证
合并前置条件(必须修复)
TestSubtitleFilter两个旧测试,传入work_dir参数build_subtitle_filter中work_dir的默认值None,改为真正必填修复测试回归后可合并。
三轮复审 ✅ 通过(commit d7b37ce5)
测试适配验证完成:
结论:可合并