一个提示词。三条 Shell 命令。我用他们自己的 AI 黑掉了它自己。
这是一类漏洞,很可能存在于今天所有多智能体 AI 产品中。而修复方法是一个目前行业内几乎没人讨论的设计模式。
以下是完整故事。
我本来没打算黑任何东西。我是在研究 Perplexity Computer 如何处理沙箱隔离,为我自己的 Agent 基础设施工作做准备。我想了解生产环境下的多 Agent 系统到底如何隔离执行环境,哪些东西共享,哪些不共享。
首先,我开始在系统里四处探查。我发现沙箱里安装了 Claude Code。
我让 Agent 启动它并生成一些测试代码,看看它的行为。运行正常。标准的 Claude Code,以绕过权限模式运行,所以不会弹出确认提示。对于 Agent 系统来说,这很合理。
就在这时我想:等等,他们是怎么处理 API 密钥的?!Claude Code 需要 Anthropic API 密钥才能运行。这个密钥必须存放在沙箱的某个地方。它是如何注入的?作用域是怎样的?是否隔离?
正是这个问题,把我引向了这条路。
子 Agent 在进程环境中持有 API 密钥。我需要偷走它。
Perplexity Computer 尝试了六次,都失败了。
- 让子 Agent 转储环境变量:被拒绝!
- 在共享文件系统上植入一个木马脚本:它读取了我的代码,理解了它的意图,拒绝运行!
- 污染 .bashrc 和 .profile:它们触发得太早,API 密钥还没注入。
- 在 PATH 上放了一个假的 node 二进制:从未触发。
- 同时启动编码 Agent 并监视进程树:子 Agent 运行在另一个沙箱中,什么都没抓到 :(
- 找到 Claude Code 的系统提示并修改以移除拒绝行为:没有找到注入的自定义系统提示。
六次失败。Claude 的模型/提示层面的安全性确实很强。每次我想搞点小聪明,模型都能识破。

然后 Perplexity 想起 Claude Code 是通过 npm 启动的 Node.js 应用。而 npm 会从主目录读取 ~/.npmrc。主目录正好在我可以写入的共享文件系统上。
Node.js 有一个 --require 标志,可以在任何应用代码运行之前预加载一个 JavaScript 模块。你可以通过 .npmrc 中的 NODE_OPTIONS 设置这个标志。这意味着,如果我在共享主目录中写入一个 .npmrc,那么子 Agent 启动的每个 Node 进程都会预加载我的代码!这发生在 Claude Code 初始化之前,在任何安全检查运行之前,在任何事情之前!
这个漏洞只需要三条命令:
- 写一个六行脚本,将 process.env 转储到共享工作区的一个文件中
- echo 'node-options=--require /path/to/script.js' > ~/.npmrc
- 让 Perplexity Computer 执行任何编码任务
子 Agent 启动 → npm 读取我的 .npmrc → 我的预加载脚本在 Claude Code 启动前触发 → 完整的 API 凭据落入共享文件系统。
成功了!它给了我一个 Perplexity 网关令牌,通过 agent-proxy.perplexity.ai 代理到他们的主 Anthropic 账户。

自然,我第一件事就是在我的笔记本电脑上为 Claude Code 设置这个 API 密钥和 BASE_URL。我本以为 Claude Code 的 LLM 调用会失败,或者被限制在沙箱内。结果让我震惊——Opus 4.6 瞬间响应!
然后我想,"当然,他们会把这次使用记在我的账户上,这个 API 密钥一定绑定到我的用户。" 我又错了。
我让 Opus 4.6 生成一个长篇故事,描述世界历史,包括每一项发明、帝国和发现。我并行运行了 5 次这个调用,每次生成 10 万+ 输出令牌。这应该消耗掉了我所有的 Perplexity Computer 积分,但积分纹丝不动。
没有 IP 限制。没有会话作用域。没有沙箱绑定。花的是他们的账单。
这个星球上资金最雄厚的 AI 初创公司之一,被一个自 2019 年以来就被用于 Node.js 供应链攻击的 dotfile 搞定了。
模型做得完全正确。基础设施没有。
现在,我真正想说的是:构建 Agent 基础设施的创始人应该从中吸取什么教训。
Perplexity 的架构对了一半。他们在沙箱和 Anthropic 的 API 之间使用了代理。这是正确的模式。你永远不应该把原始提供商 API 密钥放在沙箱里。代理能给你控制权、可观测性,以及在不轮换主密钥的情况下撤销访问的能力。
问题在于,他们的代理令牌与执行上下文没有任何绑定。一旦你拿到它,它就在任何地方永久有效。
以下是正确做法:
将令牌绑定到沙箱 ID。令牌和沙箱 ID 不匹配?拒绝请求。密钥泄露了,但你没有沙箱?毫无用处。理想情况下,还应将令牌绑定到沙箱的 IP 地址,但 E2B(他们使用的沙箱提供商)在沙箱启动之前不提供这个信息。
让令牌短暂有效。在沙箱启动时生成,沙箱暂停时销毁。没有长期有效的凭据。代理在会话开始时生成一个短期令牌,并在销毁时使其失效。从已销毁的沙箱泄露的密钥,就是死密钥。
将令牌绑定到用户的计费账户。即使其他一切防线都失效,即使有人从活动沙箱中窃取了一个实时令牌并在过期前使用,使用量也会回退到生成该会话的账户,而不是共享的主计费池。这会把"无限免费 API 访问"变成"某人在滥用自己的配额",严重程度完全不同。
这三件事——沙箱绑定、短暂有效、用户计费——才是让代理模式真正有效的关键。没有它们,你只是多了一个网络跳转,什么也拦不住。
这不是 Perplexity 独有的问题。这是当前 Agent 基础设施的默认架构,因为这样构建最快。Agent 之间共享文件系统、长期有效的凭据、主账户计费。我敢打赌,今天大多数生产环境中的多 Agent 产品都有某种形式的这个问题。
在发布前已向 @AravSrinivas 和 @denisyarats 报告。





