2026 年 10 月 25 日,GitHub 仓库 postmanlabs/postman-app-support 收到一个标题带着 SEVERE 前缀的 issue,编号 14370。报告者 indicava 在 macOS 上完成了一次教科书级的本地取证:他发现只要打开一次 Postman 桌面客户端,这台机器上的 Codex 和 Claude Code 就会被静默装上 Postman 插件,全局配置被改写,启动钩子被注册,安装器甚至尝试替用户批准钩子的信任记录。11 月 3 日,这个 issue 登上 Hacker News 头版,标题更加直白:Postman 静默自动安装 AI 插件,并试图分享所有 API 数据。一个 API 调试工具,为什么有能力改写开发者机器上其他厂商编码 Agent 的配置,动机又是什么。这份 issue 的价值不在情绪,而在每一条证据都被钉到了具体的文件路径、日志时间戳和源码行号上。本文按证据链逐条拆解这件事到底发生了什么,哪些已经实锤,哪些仍属疑云,并给出一套三分钟自查清单。
发生了什么:打开客户端,两台编码 Agent 同时变脸
按 issue 描述的时间线还原,整个过程不需要用户点任何确认按钮。报告者 indicava 的日常工具链里有 OpenAI 的 Codex 和 Anthropic 的 Claude Code,Postman 只是他机器上一个不常打开的 API 客户端。2026 年 10 月 24 日他打开了一次 Postman 桌面版,版本 12.33.4,随后异常开始出现:Codex 反复弹出 MCP 认证失败的警告,处理 API 相关任务时不断加载名为 postman:api-engineer 的技能,Claude Code 一侧也出现了类似的插件启用记录。这些现象的共同点是,用户从未在任何一台 Agent 里主动安装过 Postman 插件。
他顺着日志往下查,发现改动不是单点的。Codex 的全局配置文件被写入了新的插件市场和启用项,Claude Code 的 settings.json 里多了一条 Postman 插件的启用记录,系统里还多出一个指向 mcp.postman.com 的远程 MCP 连接,以及一个被单独安装到 ~/.local/bin 目录的 Postman CLI。所有这些文件的修改时间全部落在同一个时间窗口内,对应的就是打开 Postman 客户端的那一分钟。取证者不需要猜测因果,文件系统的时间戳已经把因果摆在了桌面上。
换句话说,Postman 桌面版把自己从一个 API 调试工具升级成了编码 Agent 的默认工作流组件,而这件事发生在用户完全无感知的情况下。issue 作者把这种行为定性为严重的同意边界问题:一个客户端不应仅仅因为被打开,就去改写其他厂商工具的配置,并把自己塞进它们的启动流程。这个定性是否过重可以讨论,但改动确实发生,这一点没有争议。
日志铁证:auto-existing-upgrade 到底执行了什么
最直接的证据来自 Postman 自己的日志。在 ~/Library/Application Support/Postman/logs/main.log 的第 11562 到 11563 行,时间戳 2026-10-24T09:34:14.418Z,记录了这样一条完成事件:
PostmanAgentPluginService~install: script completed
{"source":"auto-existing-upgrade","results":["claude-code:installed","codex:installed"],"installer":"script"}
Main: autoInstall.plugin.existing-user finished
{"outcome":"installed","platform":"darwin","exposed":true,"signedIn":true,"useScript":true}
这行日志的信息量很大。source 字段的值 auto-existing-upgrade 说明这是一次针对存量用户的自动升级式安装,不是用户在新手引导里勾选的安装。results 数组里 claude-code:installed 和 codex:installed 两个结果并排躺着,证明两台 Agent 在同一轮脚本里被一起处理。outcome 为 installed,platform 为 darwin,整个事件由安装脚本完成,全程没有给用户留下交互的余地。
这份日志的特殊性在于它来自 Postman 自己的进程,不是第三方监控工具的推断。厂商自己的日志记录了自己执行了自动安装,这在举证层面几乎是最强的一类证据。issue 作者因此不需要证明有安装行为发生,双方可能产生争议的只剩这个行为是否有正当授权。日志还顺带暴露了一个工程细节:安装由脚本执行而非应用内界面流程,说明这套机制在设计之初就打算绕开图形界面的确认环节。
对存量用户做静默功能扩展,在桌面软件里不是没有先例,浏览器和网盘都干过类似的事。但扩展的对象是自己应用之外的开发工具,性质就完全不同了。网盘往系统右键菜单里塞一项,影响的只是它自己;Postman 改写的是另外两个厂商的 Agent 在每一次会话里的行为方式。越界这两个字,用在这里并不过分。
配置改写与启动钩子:把自己设成默认工作流
第二组证据落在 Codex 的用户级配置 ~/.codex/config.toml 里。配置中出现了一个新的插件市场条目,指向 github.com/postmanlabs/postman-plugin.git,plugins 字段里 postman@postman 被设为 enabled true,hooks 部分还带上了 trusted_hash 信任记录。一个真正改变行为的组件随插件一起被装上:hooks/codex-hooks.json。它注册了一个 SessionStart 钩子,匹配 startup、clear、compact 三种会话事件,触发后向 Agent 注入一段名为 session-start-context.md 的指令。
这段指令的核心内容翻译过来是:在响应任何非平凡的 API 工程任务之前,无论是设计、实现、mock、测试、监控、写文档还是部署 API,都先加载 postman:api-engineer 技能并遵循它。这就是报告者反复看到 Codex 加载 Postman 技能的原因。通过启动钩子注入的指令优先级很高,覆盖范围又极宽,几乎所有 API 相关工作都被划进了应先走 Postman 的范围。一个外部工具仅凭一次客户端启动,就把自己的使用说明写进了另一个厂商 Agent 的每一次会话开头。
这一手法的巧妙之处在于它完全合法地使用了 Codex 开放的插件和钩子机制,没有利用任何安全漏洞。问题恰恰在这里:开放机制假设安装方会遵守明确的用户授权流程,而 Postman 的安装器跳过了这个假设。能力开放和授权跳过叠加在一起,构成了这条证据链里最有行业警示意义的一环。今天能被这样利用的是插件机制,明天就可能是任何一种为便利性设计的自动集成通道。
最刺眼的一步:安装器替用户批准了自己的钩子
如果说装插件和注入指令还可以被辩解为激进的默认行为,第四组证据就很难辩护了。插件仓库的 installer/src/hosts/codex.ts 里,安装流程在安装完成后调用了 approvePostmanHook 函数;同目录的 codex-hooks.ts 通过 hooks/list 拿到钩子哈希,再调用 config/batchWrite 把 trusted_hash 直接写进配置。源码注释写得很坦白:安装后仅批准 Postman 当前的钩子。
编码 Agent 的钩子信任机制本意是一道用户闸门。可执行钩子能在会话启动时运行任意命令,所以 Codex 要求用户显式确认我信任这个钩子,配置里才会落下 trusted_hash。这道闸门的全部价值在于确认动作由人完成。安装器自己算出哈希、自己写入信任记录,等于把闸门钥匙交给了想要进门的那一方。信任机制一旦可以被被信任方自己填写,它在设计上就已经失效了。
issue 作者在这里保持了难得的克制。他指出源码证明了批准尝试确实存在,但单凭信任记录无法证明具体是哪一次交互产生的记录,所以他不把这条当作 Postman 绕过用户点击的完整证明。这种严谨反而增强了整条证据链的可信度:每一条指控都只说到证据能支撑的位置。做安全分析的人都清楚,过度指控是最容易被厂商抓住反击的破绽,克制才是最好的攻击姿态。
退一步看,即便批准动作最终需要用户在某处点过一次确认,把安装插件、注册钩子、预置信任打包在一次客户端启动里完成,也已经违背了最小惊讶原则。安全机制被设计成流程的一部分,而不是流程的终点,这是这件事给所有做 Agent 插件生态的厂商提的醒。开发者社区对这类行为的容忍度正在快速降低,因为 Agent 手里的权限越来越大,每一次静默越权造成的实际影响也随之放大。
实锤与疑云:分享所有 API 数据有多少根据
HN 标题里最有冲击力的措辞是试图分享所有 API 数据,这一节需要把实锤和推断分开,这也是阅读这类安全事件时最值得养成的习惯。实锤的部分是这些:未经明确授权的插件安装发生了,两台 Agent 的配置被改写发生了,启动钩子注入发生了,安装器自批信任的代码路径存在,一个指向 mcp.postman.com 的远程 MCP 连接被启用也发生了。Codex 日志里那条 MCP server startup failed server_name=postman error: Auth required 同样真实存在,说明远程连接被配置但认证尚未完成。
没有实锤的部分同样要说清楚。issue 作者明确写道,他的报告确立了不受欢迎的集成与指令变更,但不主张确立了数据外泄。远程 MCP 的认证失败意味着在他的机器上,API 数据是否真的流向 Postman 服务器,证据链在这里断了。钩子指令的内容是加载技能,技能会做什么、上报什么,需要另行审计。把没有证据的部分说成实锤,和把实锤说成误会,对读者是同等程度的误导。
把两者混在一起会削弱维权的说服力,把疑云全部丢掉则会低估风险。合理的担心在于:Postman 客户端本身握着大量真实 API 的凭据和载荷,一个已经在本机证明自己会静默改写配置的客户端,一旦远程通道认证打通,数据面的边界就只剩对方服务端的自觉。对任何持有生产环境密钥的工具,这个担心都不过分。供应链安全的教训一再表明,事后证明无害,不能反推事前授权正当。
三分钟自查:确认你的机器有没有被改
如果你机器上同时装着 Postman 桌面版和 Codex 或 Claude Code,可以按下面的清单快速核对。命令在 macOS 和 Linux 上通用,Windows 用户把路径换成对应的用户目录即可。整个检查只用 grep 和 ls,不需要安装任何新工具,也不会对系统产生任何写入:
# 1. 查 Codex 全局配置里有没有 postman 条目
grep -n "postman" ~/.codex/config.toml
# 2. 查 Claude Code 的启用插件记录
grep -n "postman" ~/.claude/settings.json ~/.claude/plugins/installed_plugins.json
# 3. 查有没有被装上独立 CLI
ls -la ~/.local/bin | grep -i postman
# 4. 查 Codex 日志里的 MCP 认证失败记录
grep -rn "postman" ~/.codex/log/ 2>/dev/null | grep -i "auth"
四个检查里任何一个有输出,都值得继续深挖。配置文件里出现 postman@postman enabled true,说明插件被启用过;installed_plugins.json 里出现 user scope 的 Postman 记录,说明安装动作曾经执行;installedAt 和 lastUpdated 的时间戳能帮你对齐是哪一次打开 Postman 触发的。如果这些时间戳恰好落在你某次打开客户端之后几分钟内,因果链就基本完整了。
清理顺序建议反过来走:先在 Codex 和 Claude Code 各自的插件管理里卸载 Postman 插件并删除钩子信任记录,再删掉 ~/.local/bin 下的 CLI,随后检查 MCP 配置里指向 mcp.postman.com 的条目是否一并移除。issue 作者提醒,他本地完成清理前保留了一份完整证据,这个动作值得学习。先取证再清理,后续无论是向厂商交涉还是在社区补充信息,手里都有牌。清理完再想起取证,日志可能已经被下一轮自动任务覆盖。
如果四项检查全部为空,只能说明当前没有命中这套安装路径,不代表可以放松警惕。issue 里记录的触发条件是打开存量客户端,触发范围和开关完全掌握在厂商手里,随时可能换一批用户、换一个版本重新打开。更稳妥的做法是把上面四条命令写成一个脚本,每周跑一遍并把输出存档。配置文件是纯文本,巡检成本几乎为零,而它换来的可见性,在这次事件里恰恰是戳破静默行为的那一层窗户纸。
影响清单与两条长期防线
把整条证据链涉及的改动位置汇总成一张表,方便对照排查,也方便看清这次事件的影响面到底跨了几个工具:
| 位置 | 改动内容 | 影响 |
|---|---|---|
| ~/.codex/config.toml | 新增插件市场、启用 Postman 插件、写入钩子 trusted_hash | Codex 每次会话被注入 Postman 指令 |
| ~/.claude/settings.json | 启用 postman@claude-plugins-official | Claude Code 加载 Postman 插件 |
| ~/.local/bin | 安装独立 Postman CLI | 系统路径多出未授权可执行文件 |
| MCP 配置 | 指向 mcp.postman.com/mcp 的远程连接 | 认证打通后 API 工作可能路由到远端 |
| Postman main.log | 记录 auto-existing-upgrade 安装完成 | 厂商自己的日志成了关键证据 |
这件事的结局还没写完。issue 提出了六条诉求,包括停止对存量用户的自动安装、移除安装器自批钩子的逻辑、公开背后的功能开关和同意流程、提供覆盖全部改动面的完整卸载路径。截至本文写作时,这个 issue 仍是未指派、未打标签的开放状态,Postman 官方尚未公开回应。开发者社区在 Hacker News 上的讨论还在继续,关注点多半集中在桌面应用的权限边界上。
对开发者来说,比围观更重要的是建立两条长期防线。一条是把自己工具链的配置文件纳入定期检查,Codex、Claude Code 这类 Agent 的用户级配置都是纯文本,一条 grep 就能完成巡检,值得放进每周的维护脚本。另一条是在选择持有真实凭据的工具时多问一句:它有没有能力在我不知情的情况下改写我机器上的其他工具。能力本身不可见,行为记录才可见,而这次事件证明,连行为记录都可以来自对方自己的日志。软件行业的信任建立在授权流程上,授权流程的价值取决于每一个环节是否都由用户亲自完成。