问题概述
在对 commit c932f64b81163ebfcc3e100f7abb373151c5e106 做静态检查时,发现当前自更新链路主要依赖 HTTPS 和 GitHub Release,但下载后的安装包没有做哈希或数字签名验证。
这不代表目前已经发现了可由剪贴板内容直接触发的攻击;更准确地说,这是更新链的防御纵深缺口。一旦前端、更新元数据或相关依赖受到影响,后端目前缺少第二道可信校验。
当前行为
-
IPC 命令直接接受前端传入的 download_url 和 file_name:
src-tauri/src/commands/window.rs:364-382
-
下载函数直接请求传入 URL:
- 未限制为本项目 GitHub Release 域名;
- 未校验 SHA-256、Tauri updater signature 或 Authenticode;
- 未核对预期 Content-Length;
file_name 未先取安全 basename,便用于 temp_dir.join(file_name)。
对应位置:
src-tauri/src/updater.rs:220-289
-
安装阶段只检查 canonical path 位于临时目录,且文件名以 -setup.exe 或 -update.exe 结尾,随后直接执行:
src-tauri/src/updater.rs:299-329
-
UPDATER_GITHUB_TOKEN 使用 option_env! 读取:
src-tauri/src/updater.rs:28-29
Release workflow 又把 secrets.UPDATER_TOKEN 注入构建环境:
.github/workflows/release.yml:77-82
如果该 secret 实际配置了 PAT,token 会被编译进公开二进制,存在被提取的可能。仅凭源码无法确认线上构建时该值是否为空。
建议
- 优先改用 Tauri updater,并配置内置公钥验证 updater artifact。
- 或发布独立签名的 SHA-256 manifest,并在执行前验证。
- 后端自行构造/解析官方 Release URL,不接受前端传入任意 URL。
- 对文件名使用
Path::file_name(),拒绝路径分隔符、绝对路径和 ..。
- 下载时限制响应大小,并核对元数据中的预期大小。
- 不要把 GitHub PAT 编译进客户端。公开仓库查询通常可以使用未认证 API;如必须使用凭据,建议移到受控服务端。
- 如条件允许,为 Windows 安装包增加 Authenticode 签名。
感谢维护这个项目。界面和交互做得很好,因此希望这个问题能作为发布链加固项处理。
问题概述
在对 commit
c932f64b81163ebfcc3e100f7abb373151c5e106做静态检查时,发现当前自更新链路主要依赖 HTTPS 和 GitHub Release,但下载后的安装包没有做哈希或数字签名验证。这不代表目前已经发现了可由剪贴板内容直接触发的攻击;更准确地说,这是更新链的防御纵深缺口。一旦前端、更新元数据或相关依赖受到影响,后端目前缺少第二道可信校验。
当前行为
IPC 命令直接接受前端传入的
download_url和file_name:src-tauri/src/commands/window.rs:364-382下载函数直接请求传入 URL:
file_name未先取安全 basename,便用于temp_dir.join(file_name)。对应位置:
src-tauri/src/updater.rs:220-289安装阶段只检查 canonical path 位于临时目录,且文件名以
-setup.exe或-update.exe结尾,随后直接执行:src-tauri/src/updater.rs:299-329UPDATER_GITHUB_TOKEN使用option_env!读取:src-tauri/src/updater.rs:28-29Release workflow 又把
secrets.UPDATER_TOKEN注入构建环境:.github/workflows/release.yml:77-82如果该 secret 实际配置了 PAT,token 会被编译进公开二进制,存在被提取的可能。仅凭源码无法确认线上构建时该值是否为空。
建议
Path::file_name(),拒绝路径分隔符、绝对路径和..。感谢维护这个项目。界面和交互做得很好,因此希望这个问题能作为发布链加固项处理。