From 12740afb53e099ec33510534da488680d5acbc68 Mon Sep 17 00:00:00 2001 From: jakevin Date: Fri, 15 May 2026 15:47:15 +0800 Subject: [PATCH] docs(macos): document codesign side-effect popup (#64) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(macos): document codesign side-effect popup ("微信" 想访问其他 App 的数据) After `codesign --force --deep --sign - /Applications/WeChat.app`, macOS treats the re-signed WeChat as a different code identity from the original. When WeChat then accesses its own container / cache / app-group data (notably triggered when opening 公众号 articles), macOS fires the "'微信' 想访问其他 App 的数据" popup. This is a known side-effect of the current macOS invasive init path, not a "wx-cli is reading other apps' data" issue and not a 公众号-only problem — 公众号 is just a high-frequency trigger surface because of WebView / cache access. Document this in 3 places per agreed scope: - README.md macOS init: add "副作用提示" callout linking to the guide - docs/macos-permission-guide.md: new §六 with first-principles explanation, mitigation options, and long-term direction - src/cli/init.rs: print a short macOS-only warning at the end of `wx init` so users see it right when they finish the invasive setup * review: stop overstating the trade-off and condition the init warning Per codex review on PR #64: 1. src/cli/init.rs warning was unconditional but the wording presumed the user had taken the ad-hoc re-sign path. If init goes through the tier 2 path (Apple-signed WeChat + GUI Terminal + Developer Tools TCC authorization), the warning would mis-fire. Reword conditionally and point to the GitHub URL of the doc instead of a relative path that release-binary / npm-installed users won't have on disk. 2. docs/macos-permission-guide.md §六 and the matching README callout said "restoring official WeChat = giving up macOS memory-scan". This contradicts the same guide's §一 实测表 which shows "Apple 签名 + 本机 Terminal sudo = ✅". Restoring the official signature only gives up the default re-sign path; the local-Terminal + Developer-Tools route still works on Apple-signed WeChat. Only SSH + Apple-signed WeChat actually requires re-signing. * review (round 2): caveat empirical gap + drop emoji Self-review found two issues both LGTMs missed: 1. The "tier 2 仍走通" claim (README + §六) leans on §一 实测表 row "Apple 签名 + 本机 Terminal sudo = ✅". But that data only covers macOS 10.15 (Catalina) and 11.1 (Big Sur). macOS 14/15 — the exact versions where the popup behavior originates — were never tested for that path in this project. Add an explicit caveat instead of silently extrapolating across major macOS versions. 2. `init.rs` warning used a ⚠️ emoji prefix, which violates the project + global "no emojis in files unless requested" rule. README and the rest of init.rs have no emoji. Replace with `[macOS]`. --- README.md | 2 ++ docs/macos-permission-guide.md | 47 ++++++++++++++++++++++++++++++++++ src/cli/init.rs | 13 ++++++++++ 3 files changed, 62 insertions(+) diff --git a/README.md b/README.md index 29c8736..6faeb7d 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ sudo wx init > > 重签名后 macOS 的 TCC 隐私授权按新 code signature 重新校验,旧记录会失效。如果跳过 `tccutil reset`,微信截图/视频通话/麦克风等权限可能"看起来已开启但实际拒绝"。详见 [macOS 权限与签名指南](docs/macos-permission-guide.md#五重签名后微信权限-silent-失效)。 +> **副作用提示**:完成上面的 ad-hoc 重签后,macOS 会比较频繁地弹 `"微信" 想访问其他 App 的数据`(在微信里打开公众号文章时尤其容易触发)。这是当前 macOS invasive init 路径的已知副作用:重签后 WeChat 的 code identity 变了,它再访问自己原来的 container / 缓存数据会被系统识别为"跨 App 访问"。点"允许"通常只是放行当前 WeChat 进程;想彻底不弹得恢复官方 WeChat——这只放弃**当前依赖重签的默认路径**,**不等于放弃 memory-scan**:在本机 GUI Terminal 下、Terminal.app 拿到「开发者工具」TCC 授权后,对 Apple 官方签名的 WeChat 应当仍可以走通(实证覆盖只有 Catalina / Big Sur,macOS 14+ 未在本项目内实测);只有 SSH 远程 + Apple 签名 WeChat 这种组合才必须重签。详见 [macOS 权限与签名指南 §六](docs/macos-permission-guide.md#六微信-想访问其他-app-的数据-弹窗)。 + **Linux** ```bash diff --git a/docs/macos-permission-guide.md b/docs/macos-permission-guide.md index 322cb90..56ae1ed 100644 --- a/docs/macos-permission-guide.md +++ b/docs/macos-permission-guide.md @@ -272,3 +272,50 @@ TeamIdentifier=not set ``` 最直接的功能验证:在微信里使用截图、视频通话、麦克风等功能,按 GUI 弹窗的"允许"重新授权一次,之后正常工作。 + +--- + +## 六、`"微信" 想访问其他 App 的数据` 弹窗 + +### 现象 + +执行过 `wx init`、对 `/Applications/WeChat.app` 做过 ad-hoc 重签名之后,再使用微信时会比较频繁地看到 macOS 弹出: + +``` +"微信" 想访问其他 App 的数据。 +单独存放 App 数据可让你更容易管理隐私和安全。 +[ 不允许 ] [ 允许 ] +``` + +最常见的触发面是**在微信里打开公众号文章**,但这只是高频触发面,不是根因。 + +### 根因(第一性原理) + +这弹窗是 macOS Ventura+ / 14 / 15 对 **app data container 跨身份访问** 的保护:当前进程("微信")正在读取另一个 code identity 的 app 留下的数据。 + +我们当前 macOS 方案为了让 `task_for_pid` 能拿到 WeChat 的 task port、读取进程内存里的 raw key,要求用户执行: + +```bash +codesign --force --deep --sign - /Applications/WeChat.app +``` + +这一步把 WeChat 从 Apple 官方签名换成 ad-hoc 身份。对用户来说它仍然是"微信";对 macOS 安全模型来说,**重签前的 WeChat** 和 **重签后的 WeChat** 已经不是同一个 app identity。 + +之后当(重签后的)微信访问它原本的 `~/Library/Containers/com.tencent.xinWeChat/...`、缓存、app group 等数据时,系统看到的是"一个新身份在读旧身份留下的 container 数据",于是按隐私保护策略弹这个对话框。公众号文章里的 webview / cookie / 缓存路径刚好踩到了这条访问路径,所以"打开公众号就弹"会非常容易复现,但**本质不是公众号页面的问题**,而是 code identity + container access。 + +> 注意:这**不是** "wx-cli 在偷偷读别的 App 的数据",wx-cli 进程本身对 WeChat container 是只读访问;但**要求用户重签 WeChat** 这一步本身就是这类弹窗的直接诱因。所以这是当前 macOS invasive init 路径的已知副作用,不是与 wx-cli 无关的系统行为。 + +### 应对 + +短期缓解: +- 点"允许"通常只是放行**当前这次** WeChat 进程;下一次 WeChat 启动权限会 reset,可能还会再弹 +- 该授权一般不会在 System Settings 里留下显式开关,因为它绑定的是动态的 code identity + +彻底不弹: +- 把 `/Applications/WeChat.app` 恢复成官方签名(重装官方 WeChat 包),不再执行 `codesign --force --deep --sign -` +- 这一步只是放弃**当前依赖 ad-hoc 重签的默认路径**,并不等于放弃 macOS memory-scan:在本机 GUI Terminal 下、对 Terminal.app 授予「开发者工具」TCC 权限后,`task_for_pid` 对 Apple 官方签名(hardened runtime)的 WeChat 应当仍能走通——参考 §一 实测表里的"Apple 签名 + 本机 Terminal sudo = ✅" +- ⚠️ 实测覆盖范围说明:§一 实测表里 "Apple 签名 + 本机 Terminal sudo ✅" 的两条实证只覆盖 macOS 10.15 (Catalina) 与 11.1 (Big Sur);macOS 14 (Sonoma) / 15 (Sequoia) 上是否仍走通**未在本项目内实测**。如果你按这条路恢复官方签名后发现 init 走不通,请回到重签路径并接受本节描述的弹窗副作用 +- 真正受限的场景是 SSH 远程 + Apple 签名 WeChat:`sshd` 拿不到 TCC 开发者工具授权,这时才必须走重签路径 + +长期方向: +- 这条副作用的真正修复是把 `wx init` 重新设计成 `safe → assisted → invasive fallback` 三层:默认不动 WeChat,只有在前两条都不可行时才走 ad-hoc 重签,并先打出完整副作用清单让用户显式确认。在那之前,这是已知 trade-off。 diff --git a/src/cli/init.rs b/src/cli/init.rs index d7553b7..5b8ce8f 100644 --- a/src/cli/init.rs +++ b/src/cli/init.rs @@ -97,6 +97,19 @@ pub fn cmd_init(force: bool) -> Result<()> { println!("初始化完成,可以使用 wx sessions / wx history 等命令了"); + #[cfg(target_os = "macos")] + { + eprintln!(); + eprintln!("[macOS] 副作用提示:"); + eprintln!(" 如果你是通过对 /Applications/WeChat.app 做 ad-hoc 重签来让 init 走通的,"); + eprintln!(" 之后 macOS 可能弹 \"微信\" 想访问其他 App 的数据(在微信里打开公众号文章"); + eprintln!(" 时尤其常见)。这是 ad-hoc 重签后 WeChat 的 code identity 变了导致的,"); + eprintln!(" 不是 wx-cli 在读其他 App 数据。"); + eprintln!(" 完整说明:https://github.com/jackwener/wx-cli/blob/main/docs/macos-permission-guide.md#六微信-想访问其他-app-的数据-弹窗"); + eprintln!(" (如果你的 WeChat 仍是 Apple 官方签名、init 是靠 GUI Terminal + 开发者工具"); + eprintln!(" 授权走通的,则不会出现这个弹窗,可以忽略本提示。)"); + } + Ok(()) }