Skip to content

[Security] macOS 自更新未验证下载 .app 的代码签名 #54

@Tespera

Description

@Tespera

优先级

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.gocodesign --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 证书:

  1. 先做 SHA256 校验(见对应 issue)作为兜底
  2. 在 README / 发布说明里告知用户"自更新依赖哈希校验而非签名"

验收标准

  • CI 对 macOS 产物使用 Developer ID Application 证书签名
  • 下载后执行 codesign -v --verify --deep --strict,通过才替换
  • 可选:验证 Team ID 与预期一致
  • 验证失败时清理临时文件并向前端报清晰错误

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1中优先级 / 强烈建议处理enhancementNew feature or requestsecurity安全相关

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions