安全
最后更新:2026年10月20日
你被要求把 OAuth 登录、以及用于费用数据的管理员 API 密钥交给一个闭源 App。为此犹豫是合理的。这个页面就是你原本只有在安装之后才能看到的记录:检查了什么、发现了什么、修复了什么——以及有意没有改动的地方。
大多数人根本不需要输入密钥
对于一个闭源的免费 App,一个合理的问题是:它要你拿什么来换。所以先说最重要的:对于大多数人来这里的目的——两个订阅——Claude 和 ChatGPT,你只需登录。登录通过 OAuth 在服务商自己的登录页面上进行,App 从不接触密码。不会创建管理员密钥,也不需要在任何地方粘贴任何东西。
每张 API 卡片都是可选的,在你决定之前一直保持为空。安装、登录、完成——对大多数人来说,管理员密钥的问题根本不会出现。只有当你还想看 API 花了多少钱时,它才变得重要,而这正是本页其余部分要讲的。
为什么要信任一个你无法阅读源码的 App?
免费的开源工具是存在的,它们最有力的理由也确实成立:在把管理员密钥交给一个程序之前,你可以读一读它做了什么。这个 App 做不到这一点。它用另一种方式来回报——便利和平台保护,而不是可验证性。沙盒由 macOS 强制执行,而不是写在 README 里的承诺;它一键安装,已签名并经过公证;安全修复通过自动更新送达每个人,而不只是盯着发布页面的人。这适用于 Mac、iPhone 和 Watch 上的 App Store 版本——Windows 版不在任何商店上架,所以那里没有沙盒、没有签名,也没有自动更新。
✓ 而对信任问题真正的回答:安全记录。
闭源并不一定意味着“相信我就好”。安全记录写明了四轮审查及其具体发现——检查了什么、发现了什么、修复了什么,以及哪些是有意没做的。它不能代替阅读源代码;但这是闭源代码所能拿出的最坦诚的东西。
如果你宁愿评判工作本身而不是关于它的说法:我会把棘手的缺陷写进笔记 (英文)——什么坏了、真正的原因是什么,以及我是怎么处理的。
这次审查是什么,不是什么
它是一次有记录的、借助模型完成的框架审查,使用 Claude Fable 5 在四个日期进行,每次都形成书面报告。它不是外部审计。没有委托任何独立机构,项目之外也没有人读过源代码。如果这是你的标准,这个 App 达不到,这里的任何措辞都改变不了这一点。
这次审查能给你的,是一份具体、可核查的说明,而不是一枚徽章。下面的每一项发现都写明了缺陷的类别以及采取了什么措施。
审查的是哪个版本
最近一次完整审查于 2026年8月10日进行,针对的是作为 5.0 版发布的代码。今天(2026年10月22日)的当前版本是 Mac App Store 中的 Mac 7.8、iPhone、iPad 和 Apple Watch 2.19,以及从 aicockpit.info 下载的 Windows 1.11.0。
此后新增、因此未经过正式审查的内容:OpenRouter 和 Grok 卡片、第二个 Claude 账户、演示模式、设置助理、拖动排序卡片、每月合计行、评分提示、GitHub Copilot、ChatGPT 实时获取、故障指示和打赏。更新的还有:可选的为终端提供状态、可通过一个小型本地脚本从 Claude Code 状态栏获取的 Claude 数据(自 7.7 起)、读取 Claude Code 和 Codex 本地会话文件(~/.claude、~/.codex)的会话卡片、诊断报告,以及把密钥保存在 Windows 凭据管理器中的 Windows 版。审查带来的加固——不跟随重定向、凭据只存于钥匙串、对外部对话记录的解析设有上限——适用于以上全部内容,因为它们位于共享的层中。但如实说,这些版本都没有经过自己的审查,如果说成别的样子,这个页面就失去了意义。
参照标准
- OWASP ASVS 4.0 · OWASP MASVS
- Apple Secure Coding Guide
- RFC 8252(面向原生 App 的 OAuth)· RFC 7636(PKCE)
- CWE Top 25
各轮审查
第 2.1 轮——五项发现,全部修复
2026年8月2日 · 两次独立运行
- 通过 Codex 路径的命令注入(CWE-78)——弃用 AppleScript,路径现在经过 shell 转义后写入
.command文件。 - OAuth 回调页面中的 HTML 注入——输出已转义。
- Codex 连接器中
startup上的数据竞争——访问已移到队列上。 - 忽略了
SecRandomCopyBytes的返回值——现在会抛出错误,而不是悄悄生成弱随机数。 - 通过取自外部对话记录的
agentId进行路径遍历——字符已过滤。
第 3.1 轮——没有严重或高危发现,修复了九项
2026年8月4日 · 两次独立运行 · 103 项测试通过
已核实 2.1 轮的五项发现仍处于关闭状态。
- 外部对话记录引发的整数陷阱(CWE-190)。只要一行包含
"input_tokens": 1e300,转换时就会让 App 崩溃——而且每次重新启动都会再崩溃,因为该文件一直留在活动时间窗口中。现在数值设有上限,求和会饱和处理。 - “打开项目文件夹”会启动路径指向的任何东西(CWE-73)。路径来自外部对话记录的
cwd字段;如果它指向一个应用程序包,点按就会启动一个程序。现在它只会在访达中显示,并且只针对真正的文件夹。 - 携带管理员密钥的重定向(CWE-522)。每个客户端都使用不跟随 HTTP 重定向的会话,所以 301 无法把密钥带到另一台主机。
- 退出登录时的竞争(CWE-613)。正在进行的令牌刷新曾会把已删除的令牌写回钥匙串。现在它会丢弃自己的结果。
- 启动 Codex 服务时先检查后设置的竞争(CWE-362)——两个调用者可能启动两个子进程,并让其中一个成为孤儿进程。现在是原子操作。
- 缺少资源限制(CWE-400):每次读取 4 MB、每个会话 200 个子代理文件、Codex 连接 4 MB 缓冲区、25 个 OpenAI 项目,Codex 日志只从文件末尾读取。
- 符号链接(CWE-59)——历史记录文件以
O_NOFOLLOW打开。 - 如实的时间戳——Codex 日志数值带有日志自己的时间,而不是查询时间;Kimi 的余额和编程配额状态分开,一个无法冒充另一个是最新的。
- 更少暴露——密钥预览只显示最后四个字符(自检结果是要发给别人的),钥匙串条目设为仅限本设备。
第 4.1 轮——显示层
2026年8月9日 · 两次运行:先是错误和改进,然后是显示层的安全性
两份报告都在发布前处理完毕。这一轮没有产生单独的安全发现清单,在这里硬列一份只是凑数。
第 4.2 轮——没有严重发现;修复两项重要问题和三项次要问题
2026年8月10日 · 随 5.0 版发布
- 余额计算中的 UTC 日界。费用 API 的分段从 UTC 午夜开始,但截止日期是按本地日历生成的——在 UTC 以西,充值那一天会从合计中漏掉,App 显示的余额偏多。现在按 UTC 计算,并有一项覆盖八个时区的测试。
- 菜单栏图标中剩余时间上没有边界的
Int(…):服务器返回的超大resets_at可能让 App 崩溃。上限设为八天。 - 次要问题:
Decimal(Double)会使金额失真,所以充值金额改为以字符串传递;可能会针对新金额显示过时的小计;关闭了一个不必要公开的接口。
已核实 2.1 至 4.1 轮的发现仍处于关闭状态。
有意没做的事
这些是权衡后的决定,不是疏忽。列出它们,是因为一份你无法提出异议的审查毫无价值。
- 任何地方都不用浏览器 Cookie。App 不读取任何浏览器的 Cookie,它自己的连接也既不发送也不保存 Cookie:Mac 上是
httpShouldSetCookies = false和httpCookieAcceptPolicy = .never,Windows 上是UseCookies = false。窃取浏览器会话 Cookie 的恶意软件是真实的威胁;一个收集 Cookie 的 App,就会多出一个可被窃取的地方。代价是:只能通过浏览器会话获取的数据——例如 Claude 积分余额——不会出现在卡片上。 - 不为 OpenAI 积分余额使用浏览器会话密钥。用一个
sess-…Cookie 读取剩余余额本来很容易——但这个 Cookie 就是你 OpenAI 账户的完全访问权限。余额改为用你自己输入的充值金额,减去 App 已经获取的每日费用来推算。没有额外请求,没有新的机密。 - 沙盒——审查时没有。审查的 5.0 版在没有 App 沙盒的情况下运行,因为它必须自由读取
~/.claude和~/.codex。从 5.1 起,Mac App Store 版本在沙盒中运行,并以明确授权的方式请求的正是这两个文件夹——访问保持只读,并由你授予。 - OAuth 回调仍使用
http://localhost:<port>/callback。RFC 8252 §7.3 建议使用字面地址127.0.0.1,但 Anthropic 的客户端只接受这种形式——改动会导致无法登录。重新绑定的风险是可控的,因为服务器只监听环回接口(requiredInterfaceType = .loopback)。
Mac App 连接到哪里
这是完整列表——与 App 在“关于”页面上显示的相同。不跟随重定向,你会话的内容也从不传输。
| 地址 | 用途 | 需要 |
|---|---|---|
claude.com, platform.claude.com |
登录和退出 Claude | 你的 Claude 订阅 |
api.anthropic.com |
订阅用量窗口,另外还有 API 费用 | 登录,或管理员密钥 |
auth.openai.com |
登录你的 ChatGPT 账户——该页面属于 OpenAI | 仅在登录期间(App Store 版本) |
chatgpt.com |
已登录的 ChatGPT 账户的配额和积分 | ChatGPT 登录 |
api.openai.com | OpenAI API 费用和 token 用量 | 管理员密钥,可选 |
api.moonshot.ai / api.moonshot.cn, api.kimi.com |
Kimi 余额和编程配额 | API 密钥,可选 |
openrouter.ai | 积分、支出和你的密钥限额 | 普通密钥,可选 |
management-api.x.ai | xAI 余额和支出上限 | 管理密钥,可选 |
api.github.com |
你的令牌对应的登录名,以及 GitHub Copilot 账单报告 | GitHub 令牌,可选 |
api.deepseek.com |
按货币显示 DeepSeek 余额——自 7.2 版起 | API 密钥,可选 |
status.claude.com, status.openai.com,
status.moonshot.cn, www.githubstatus.com |
服务商公开的故障报告——不发送任何内容,只取回一个公开的状态文件。Copilot 卡片使用 GitHub 的,自 7.2 版起 | 仅在该服务商的卡片已设置时 |
localhost:<port>/callback |
OAuth 回程,仅限环回接口 | — |
本地文件:~/.claude、~/.codex |
你的 Claude Code 会话和 ChatGPT 订阅限额,在你的 Mac 上读取。其中任何内容都不会离开设备。 | 你授予一次的只读访问权限 |
这个列表中任何地方都没有我的服务器。Mac 上的 ChatGPT 限额要么来自你本地安装的 Codex,要么在你于 App 内登录 ChatGPT 后,直接来自 chatgpt.com。
iPhone App 连接同样的服务,自 2.11 起包括 DeepSeek,自 2.13 起包括 www.githubstatus.com;它自己的表格在它的隐私政策中。Windows 版也连接同样的服务,从 1.5 起还多一项:它每天读取一次 aicockpit.info/download/windows/latest.json(1.10 及之前:查询 api.github.com),看看是否有新版本——不带凭据,只有 IP 地址和标识“AI-Cockpit”。这项检查可以在“设置”›“关于”中关闭。从 1.6 起,它还会为 Copilot 卡片读取 www.githubstatus.com,并把所有数据保存在 %APPDATA%\AI-Cockpit 中(1.5 及之前:%APPDATA%\AI Dock)。
不必听我说。自己看看网络连接。
安全记录逐行列出了 App 会连接的每一台主机,并说明每一台的用途。这个列表不是安慰——而是一个可以被抓住把柄的声明。
那就来抓吧。在 App 前面放一个网络监视器——Little Snitch、LuLu,或者任何你已经信任的工具——让它在普通工作日里运行一整天。它记录下的每一项都应该已经在那个列表上。如果有不在列表上的,就应该公开出来,我宁愿看到这样的报告:反馈表单会直接发给我。
为什么需要管理员密钥,它能做什么
OpenAI 和 Anthropic 只通过管理接口提供费用和用量数据——普通的项目密钥在那里什么也拿不到。这对你来说确实是一种让步,所以有两点值得知道:
- AI Cockpit 只读取。它不会在你的账户中创建、更改或删除任何内容。
- 密钥存放在 macOS 钥匙串中,仅限本设备,只发往它所属的主机——绝不经过重定向。“设置”→“全部还原”会在本地删除它;在你于服务商处撤销之前,它在那里仍然有效。
如果你不愿做这个交换,就不要开启这两张卡片。每张卡片都是可选的,AI Cockpit 的其余部分没有它们也能正常工作。
报告漏洞
请使用联系表单,并事先说明这是安全报告——留下一个能联系到你的地址,你会在那里收到回复,所以细节不必写进表单本身。发布之前请留出几天时间——这是一个人,不是一个安全团队。