macOS 热更新产物代码签名无效,导致桌面文件权限反复报错
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 401
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
**客户端版本**: 0.1.18
**反馈类型**: bug
---
## 现象
Cindy 在访问桌面项目时反复提示“桌面文件夹访问被拒”,并持续引导用户打开“系统设置 → 隐私与安全性 → 文件与文件夹”。即使 Cindy 已经出现在该权限列表中,提示仍会重复出现。
对当前安装产物进行只读校验后发现,Cindy.app 以及主可执行文件的代码签名均无效;entitlements 也无法被系统正常识别。这会使 macOS TCC 无法稳定识别应用身份,权限可能无法正常授予或在更新后失效。
## 复现步骤
1. 通过 Cindy 自带热更新升级并重启应用。
2. 打开位于 `~/Desktop` 下的项目。
3. 执行涉及桌面文件读取或写入的任务。
4. 观察到 Cindy 提示桌面文件夹权限被拒,并打开 `Privacy_DesktopFolder` 设置页。
5. 在终端执行以下只读校验:
```bash
codesign --verify --deep --strict --verbose=4 /Applications/Cindy.app
codesign --verify --strict --verbose=4 /Applications/Cindy.app/Contents/MacOS/Cindy
codesign -d --entitlements :- /Applications/Cindy.app
spctl --assess --type execute -vv /Applications/Cindy.app
```
## 期望行为
- 热更新发布的最终 App 保持有效的 Developer ID 签名、Hardened Runtime entitlements 和 Apple 公证状态。
- 更新前后保持稳定的 designated requirement,使用户授予一次桌面文件夹权限后可以继续生效。
- 更新器在替换应用前验证新产物签名;签名无效时应中止更新并保留上一版本。
## 实际行为
校验结果包括:
```text
invalid signature (code or signature have been modified)
warning: binary contains an invalid entitlements blob. The OS will ignore these entitlements.
internal error in Code Signing subsystem
```
更新日志显示热更新流程会解压新的 `Cindy.app`、删除旧应用、移动新应用到 `/Applications`,随后清理 xattr 并启动,但没有看到替换前的签名验证步骤。
## 补充诊断
权限提示逻辑目前还会把所有包含桌面路径的 `Operation not permitted / EPERM` 识别成 macOS TCC 拒绝。工作区沙箱越界同样会产生 EPERM,因此即使真实原因是会话沙箱限制,也可能错误引导用户修改系统权限。建议将该误判作为关联问题修复:区分 TCC 拒绝与工作区沙箱拒绝,不要仅靠错误字符串匹配。
## 建议验收
- 对最终分发 ZIP 解压后的 App 执行 `codesign --verify --deep --strict`,返回码为 0。
- `spctl --assess --type execute` 显示已接受,并能验证 Developer ID 与公证。
- 升级前授予的桌面文件夹权限在升级、退出和重新启动后仍然有效。
- 人为制造工作区沙箱 EPERM 时,不再打开 macOS 文件夹权限设置页。
---
**OS**: darwin arm64 (25.5.0)
**界面语言**: zh-CN
Contributor guide
Research direction
The payload names no repository files; start by locating the hot-update path that unpacks, removes, moves, cleans xattrs, and launches Cindy.app, then inspect the macOS permission-error classification. Reproduce with the listed codesign and spctl commands against the final ZIP's app. Done means invalid updates are rejected without replacing the previous app, valid releases pass verification, and sandbox EPERM does not open TCC settings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, macos, typescript
- Domain
- desktop, release, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100