Files
cmshoppe/docs/tasks/T-616.md
T

48 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-616
title: 自动升级安全下载校验与同盘暂存
phase: 8
deps: [T-615]
status: TODO
created: 2026-07-13
---
## 问题 / 背景
自动升级不能把远程zip直接交给更新器。客户端必须先完成可信地址限制、流式下载、大小/hash校验、防zip路径穿越、安全解压、包内版本与manifest逐文件校验;任何一步失败都不能碰当前程序文件。
更新临时文件不能混进用户业务数据 `data/`。本任务使用安装目录同级管理区 `<安装目录>/.cmshopee-update/`,既与程序在同一磁盘便于后续目录切换,也与账号、SQLite、图片和密钥完全隔离。
## 方案
1. 新增 `app/update_installer.py` 纯逻辑模块,定义自动安装元数据、下载结果、暂存结果和中文错误类型;不得依赖Qt控件。
2. 只接受HTTPS下载地址。下载主机采用客户端受信任域名白名单;重定向只能落在同一白名单内,禁止降级HTTP、`file://`、内网地址和任意第三方跳转。
3. 流式下载到 `.cmshopee-update/downloads/<version>.zip.part`,持续校验累计字节数,完成后要求与 `size_bytes` 完全一致、SHA-256严格一致,再原子改名为 `.zip`。包大小硬上限建议512 MiB;超限、磁盘不足、中断或取消时保留当前版本,清理不完整part文件。
4. 安全解压到 `.cmshopee-update/staging/<version>-<随机值>/`。解压前逐项拒绝绝对路径、盘符/UNC、`..`、符号链接、Windows保留名、NTFS ADS冒号、尾随点/空格、大小写不敏感重复目标;限制文件数不超过20000、解压总量不超过2 GiB,并限制异常压缩比。
5. 解压后严格验证 `version.txt`、`package-manifest.json`、`cmshopee.exe` 和 `_internal/`;版本、包格式、更新器协议必须与服务端元数据一致。按manifest逐文件复算大小和SHA-256,拒绝manifest未声明的程序文件和缺失文件。
6. 本地写入 `pending.json` 只记录版本、安装根、暂存根、hash和阶段,不记录URL查询参数、密钥或用户数据路径。下一次启动可识别已经完整校验的暂存包,避免重复下载;无效/不完整pending必须清理后重新下载。
7. 失败消息对用户保持中文概述,远程URL、内部路径、堆栈写入脱敏诊断日志,不直接展示。
## 验收要点
- 正常zip能下载、校验并暂存,当前 `cmshopee.exe`、`_internal/` 和 `data/` 完全不变。
- hash为空、格式错误、不匹配,大小不匹配,HTTP/非白名单地址和越权重定向均拒绝安装。
- zip slip、符号链接、大小写重复、保留名、ADS、zip bomb和manifest缺失/篡改均被自动化测试阻断。
- 下载中断后不会把 `.part` 当完整包;已验证pending可在重启后复用,不重复下载。
- 更新目录始终位于 `.cmshopee-update/`,不创建 `data/updates`,不读取用户业务数据。
## 测试要求
- 新增 `tests/test_update_installer.py`,使用临时目录和本地可控响应覆盖成功、取消、网络失败、所有安全拒绝路径及pending恢复。
- 运行ruff、compileall、完整unittest和 `git diff --check`;不依赖真实线上下载地址。
## 边界(不改什么)
- 不启动独立更新器,不替换程序,不自动重启。
- 不修改当前T-544强制升级GUI;GUI接入由T-618完成。
- 不读取、移动、覆盖或清理 `data/`。
## 执行记录
(完成后记录实现、验证命令与结果。)