优先级
P1 — 中优先级(视 CI 是否已有 Developer ID 证书而定)
问题描述
installAndRelaunch 在 macOS 上解压新 .app 后,调用 codesign --force --deep --sign - 做 ad-hoc 签名(空身份签名)。这能让新 .app 通过基础 Gatekeeper 检查,但没有验证下载的 .app 是否由可信开发者(即 Gridea Pro 项目本身)签过。
影响 / 风险
- 下载的
.app 可能是恶意构造的(配合下载无 SHA256 / 无 URL 白名单的场景放大风险)
- ad-hoc 签名只保证"形式合规",不保证"身份合规"
- 破坏用户信任链:他们最初装的是"经过 Apple 开发者证书签名的 Gridea Pro";自更新拿到一个未由 Gridea 开发团队签名的
.app,本质上突破了原信任链
问题位置
backend/internal/facade/update_installer_darwin.go — codesign --force --deep --sign - 的调用位置(大约第 80-90 行)
最佳解决方案
前提:项目需要有 Apple Developer 证书(Developer ID Application),并在 CI 中使用它对 release 的 .app 签名。
运行时校验:解压下载的 .app 后、替换旧版本前,执行:
codesign -v --verify --deep --strict "<downloaded>.app"
spctl -a -t exec -vv "<downloaded>.app" # Gatekeeper 检查
脚本检查这两个命令的 exit code,非 0 就拒绝替换、清理临时文件。
更严格:验证 Team ID 必须等于预期的 Gridea Pro Team ID:
codesign -dv --verbose=4 "<path>" 2>&1 | grep "TeamIdentifier" | grep "<expected-team-id>"
替代方案
如果短期内无 Apple 证书:
- 先做 SHA256 校验(见对应 issue)作为兜底
- 在 README / 发布说明里告知用户"自更新依赖哈希校验而非签名"
验收标准
优先级
P1 — 中优先级(视 CI 是否已有 Developer ID 证书而定)
问题描述
installAndRelaunch在 macOS 上解压新.app后,调用codesign --force --deep --sign -做 ad-hoc 签名(空身份签名)。这能让新.app通过基础 Gatekeeper 检查,但没有验证下载的.app是否由可信开发者(即 Gridea Pro 项目本身)签过。影响 / 风险
.app可能是恶意构造的(配合下载无 SHA256 / 无 URL 白名单的场景放大风险).app,本质上突破了原信任链问题位置
backend/internal/facade/update_installer_darwin.go—codesign --force --deep --sign -的调用位置(大约第 80-90 行)最佳解决方案
前提:项目需要有 Apple Developer 证书(Developer ID Application),并在 CI 中使用它对 release 的
.app签名。运行时校验:解压下载的
.app后、替换旧版本前,执行:脚本检查这两个命令的 exit code,非 0 就拒绝替换、清理临时文件。
更严格:验证 Team ID 必须等于预期的 Gridea Pro Team ID:
替代方案
如果短期内无 Apple 证书:
验收标准
codesign -v --verify --deep --strict,通过才替换