一条 postinstall 脚本,就把自家技能塞进了别人工具的搜索范围
先说这件事被发现的方式,它比事情本身更能说明问题:最早公开吐槽的用户,是在用 Codex 干活时看到技能列表里冒出了陌生条目,回头才查到源头是几天前装的 Coze CLI。他装的是 A,出问题的是 B,中间没有任何一步提示过他 A 会去动 B。
技术上没有什么高明手段。据蓝点网的分析,Coze CLI 在包配置里定义了生命周期脚本,npm 或 pnpm 装完主程序就顺势执行,把附带技能一并装上;过程不需要用户确认,输出还通过参数隐藏,只有识别到 CI 环境或从源码开发时才跳过。postinstall 一直是 npm 生态里权限最大、审查最少的那一环——它能以你的用户身份跑任意代码,而绝大多数人装包时根本不会去看。
装上之后是探测。工具会扫描本机有没有各家 AI 编程工具的配置目录来判断"你在用什么",~/.codex 对应 Codex,~/.claude 对应 Claude Code,另外还覆盖了 Cursor、Trae AI、Cline、Gemini CLI。命中之后,内置技能会被复制到共享技能池 ~/.agents/skills/,再按各家的目录结构做软链接或副本,于是它们就出现在了别人的技能搜索范围里。被塞进去的包括 using-coze-cli、coze-code、coze-file、coze-generate 这几个。
v0.3.7 是 8 月 11 日下午紧急推的。旧版的触发条件写得极宽——用户在"开发、修改、调试、运行或迭代软件产品"时就自动加载,这几个词摞在一起基本等于"只要你在写代码";新版改成只有用户明确要求使用扣子功能,或者敲 /coze-cli、/coze 前缀才会触发。
但复核下来,新版依旧在安装时无提示地装技能、隐藏安装过程、默认全局激活写入共享目录、自动探测并记录已安装的智能体。想干净点只能自己动手:装的时候加 --ignore-scripts 跳过脚本,再用 COZE_CLI_NO_SKILL_NOTIFIER=1 coze config set skill.mode off 把技能同步关掉。截至目前,扣子没有就这件事发过公开说明。
比"多了几个技能"更值得警惕的是,这些技能自身的依赖没有锁定版本。这条通道的特征是:不需要用户确认、自动执行、会向多个 AI 工具的目录写入。上游只要有一个包被投毒,它就是现成的分发路径。审计方的结论也压在这个分寸上——没有发现传统意义上的恶意软件行为,但这种把用户锁进自家生态的做法"不可接受"。恶意与否是意图问题,而这条路修好了就摆在那儿,谁走都行。
扣子 3.0 在 6 月初上线时,主打的正是能把 Codex CLI、Claude Code 这类本地 Agent 接进它的多智能体协作。平台想做"总调度",逻辑上讲得通;但当用户不主动把调度权交出去,改成往对方的技能目录里放东西,性质就从集成滑向了占位。开发者的本地环境现在是一块被好几家同时盯上的地皮,而技能目录这种"约定优于权限"的设计,恰好是围墙最矮的一段。
实际能做的事很朴素:装完任何新的 CLI 之后,顺手看一眼 ~/.codex 和共享技能目录里有没有自己没放过的东西,把它当成 shell 配置一样定期扫一遍。Codex 稳定使用的那套配置里,多数条目其实都是同一件事的不同侧面——你得知道那个替你执行命令的工具,现在身上到底挂着谁给的东西。