Skip to content

2.2.17 安全审计复核与 2.2.18 修复记录

日期:2026-09-28。复核基线:2.2.17 / aa1746e。本次工作在独立分支进行,原有 2.3 开发工作区保持原状。

结论

同意报告识别出的主要信任边界缺口,尤其是导入元数据覆盖参数、实验包身份不一致、GPU 输出链接读取、桌面登录令牌和公共导出配额。2.2.18 针对这些问题加固,并加入负向回归测试与正常流程验证。

这次复核有以下修正和限定:

  1. “上传文件不能执行代码”应表述为:在已检查的正常路由、当前解析器和依赖版本中,没有确认匿名上传直接导致代码执行的路径。静态分析及进程内测试不能证明所有输入都安全。
  2. GPU 链需要先控制 VM、GPU 输入通道或容器。它是重要的隔离边界缺口;报告没有证明匿名租户能达到此前提,不能直接称为互联网匿名 RCE。宿主代理仍以 root 运行。
  3. 请求限速表 rate_limit() 在 2.2.17 已经检查 key 是否存在;报告关于它“满后所有网络都被拒绝”的描述不准确。会话预算表 admit() 确实缺少此检查。
  4. 进程内 DAY = 86400,预算按 UTC 天清空;部署模板另有每 12 小时重启的 systemd timer。报告中的 12 小时上限依赖该 timer 正常执行,不能从进程内逻辑单独推出。后续发布检查确认生产 timer 已启用,按 11:59/23:59 UTC 执行。
  5. Virtual PA 的 metadata 接口本身没有重算 CSV;input metadata 和 CSV 导出路径的重复计算与共享锁问题成立。
  6. 分享包脱敏问题可在 Linux 上用 Windows 路径字符串复现;这不等于完成真实 Windows SMB/NTLM 或原生窗口测试。
  7. 清单与内容共同来自同一个包,SHA-256 只能验证它们之间的一致性。真实性仍需要可信来源或独立传递的哈希。

报告中的 12 项 Medium

发现 复核判断 2.2.18 的处理
M1 / GPU-1 成立,前提是容器或 VM 已失陷 最终打包从可信工作目录 fd 逐级打开目录和普通文件,拒绝链接、特殊文件及硬链接;读取字节数、文件数和目录深度受限;移除容器后才收集结果。实时读取也从工作区根 fd 逐级打开 runs 和运行目录。
M2 / GPU-2 成立,VM 提供的工作目录不应是 Python 模块来源 容器使用 -P、PYTHONSAFEPATH、工作目录 /;输入归档限制顶层结构和文件类型;CPU worker 也移除不安全的当前目录导入路径。
M3 / EXE-1/2 成立 LegacySpec 白名单和类型校验;hparams 与 Namespace 分离;CSV 名称、成员链接、输出目录组件均校验;未知训练参数在导入或加载时拒绝。
M4 / ARC-2 成立 内外 manifest 的 ID、数据哈希和 source kind 必须一致;run/config/artifact schema 在导入前校验;私有快照、暂存和失败回滚;解压后再次核对 raw 哈希。
M5 / ARC-3 成立 数据版本和 split version 使用标识符类型;完整导出检查版本路径包含性和链接。
M6 / CON-1 成立 排行榜先检查包哈希、类型、身份,再导入;导入的私有快照再次检查外部记录的哈希及 share 类型;包路径必须是受限 ZIP 文件名。
M7 / ENV-1 成立;运行收到的 Python 文件本身也意味着信任代码 新的 installed CLI 直接读取 ZIP/目录中的数据并检查成员完整性,不插入 bundle 的模块路径。直接脚本要求 safe-path 模式;--use-bundled-source 仍是显式执行第三方代码的选项,只应用于可信来源。
M8 / WIN-1 成立 逐字符串递归脱敏 JSON;Windows 路径同时匹配两种分隔符并忽略大小写。
M9 / WIN-3/4 路径校验缺口成立;NTLM 外传未在 Windows 实测 文件系统访问之前拒绝盘符、UNC、冒号、空段、./..、设备名和尾部点/空格;关键导出和读取点再检查包含性。
M10 / LOC-1 成立,尤其是多用户 Linux 一次性 120 秒 bootstrap;独立 launcher credential 支持重新打开;0600 原子锁文件和私有浏览器重定向文件;SSH/无图形环境默认只输出访问方式。
M11 / WEB-2 主要结论成立,metadata 路径的描述需区分 补齐昂贵 GET 路由;按工作区共用可重入锁;不可变信号的 CSV 导出缓存;每个网络最多一个重负载请求。
M12 / WEB-4 会话表缺陷成立;限速表描述需修正,12 小时上限依赖部署 timer 容量提高到 65,536,仅拒绝尚未记录的新网络;IPv6 按 /48 聚合。有限容量仍可能被分布式攻击耗尽,边缘限流仍有必要。

同步纳入的较低等级加固

  • NPZ/NPY 在分配前检查头部、dtype、shape、成员数量和总大小;拒绝非数组成员和 object dtype。
  • 旧数据目录拒绝链接成员;FileRef、实验包和导出复用可移植路径检查。
  • Plotly 标签文本转义,导入图表结构和文本长度受限;i18n 对过长文本跳过模板正则。
  • 比较表、图表 CSV 转义公式文本;排行榜 Markdown 转义用户文本。
  • 补齐桌面 POST 的 CSRF 依赖并检查 API 的 Sec-Fetch-Site;POSIX 新工作区 0700,拒绝不可信所有权/写权限。
  • 去掉 benchmark 的不受限 torch.load 回退,并用 AST 回归扫描相关源码目录。
  • JSON 读取完成后才预留重负载资源;同一网络最多六个在途请求。CSV 上传仍持有受限的上传/重负载槽位并有超时。
  • starlette>=1.3.1、h11>=0.16.0 和文档依赖下限;CI 自动审计 VM/GPU 锁文件,扩大 CODEOWNERS。
  • protected-paths 辅助检查读取可信 base 分支代码,用 API 同时检查重命名前后文件名;独立的当前提交审批才计为通过。原生 ruleset 仍是主要合并控制。
  • 前端验证文件移入仓库内忽略目录;复现源文件按 Git 跟踪列表或已安装发行版 RECORD 选择,排除偶然存在的未跟踪源码。

验证范围与剩余工作

同一组最小复现的前后对照

在 aa1746e 的原 2.2.17 和本分支分别运行相同探针,所有文件都是临时合成文件,未读取真实机密文件或连接线上服务。

探针 2.2.17 2.2.18
spec 改写训练参数 可改写 拒绝,参数保持原值
GPU 打包跟随被替换的运行根目录 可读取外部合成标记 拒绝
Windows 路径字符串泄露 泄露 已脱敏
bootstrap 再次兑换 可重复 拒绝
preprocessing version 中的目录穿越 接受 拒绝
输入 CSV 导出绕过重负载分类 未计入 计入

回归与范围

安全回归涉及路径、元数据、令牌、归档、输出链接、导出缓存和网络预算;正常回归涉及训练、实验导入导出、排行榜、图表重放、虚拟 PA 和安装后的桌面服务。最终测试数量记录在发布验证记录中:普通 Python 回归覆盖 2,285 项,前端 282 项,安装包验证 3 项。另在真实 Chromium 中验证了私有文件登录跳转和一次性令牌。

初次补丁复核限于本地验证。随后的发布暂存检查补充了 Windows/macOS 安装、安全边界用例、离线 VM 和真实 GPU 容器测试,详见发布验证记录。原生 pywebview 窗口尚未实测;以下问题仍需要独立的后续工作或运维证据:

  • rootful GPU agent 的权限进一步拆分、VM worker 独立 UID、GPU 驱动/CDI/内核及镜像 OS 包审计;BindsTo 降低端口失联窗口,不能替代桥接端点认证。
  • Cloudflare 请求体缓冲、WAF、响应头和独立 Studio 源;共享 IPv6 /48 的并发/预算需要结合真实用户规模调节。
  • GitHub 的必需 Code Owner 审阅、tag/environment 保护、PyPI Trusted Publisher 和发布审计门禁的实际状态。
  • Windows 文件 ACL、SMB 行为和原生窗口导航/pywebview 内部 bridge;纯 Python 和字符串测试不能替代平台验证。
  • 旧版 run_in_directory 的进程 cwd、源树内置数据目录中可执行 demodulator、原生发布确认、真实 RF interlock 取消语义;本补丁没有重构这些边界。
  • 用户额外添加的共享导入根目录中,并发写入者仍可能在路径检查后替换文件;普通本地导入尚未全面改成 fd 贯穿读取。静态链接拒绝测试不能证明不存在这种竞态。
  • 完整可复现构建、安装时 RECORD 校验、独立的数据集发布清单、隐私说明和数据保留政策。

参考:Python safe-path 参数(3.11 起提供;CPU worker 对 3.10 使用显式移除启动目录的兼容方式);GitHub pull_request_target 的信任边界。