错误报告执行了那条命令
由 Tenet Security 于 2026 年 6 月披露的 agentjacking,既不需要恶意软件,也不需要访问你的基础设施。攻击者用一把公开的只写密钥在你的 Sentry 项目中登记一条假错误,把指令藏在其中,然后等待。当你请你的编程代理修复这个问题时,它会把攻击者的文字当成指引来读,并用你的凭证去执行。Tenet 发现至少 2,388 个外露的项目,以及在 Claude Code、Cursor 与 Codex 上 85% 的成功率。Bromure Agentic Coding 把这整条先读取再执行的路径放进一台用完即弃的 Linux VM 里跑,在代理行动前先给取到的文字评分,只留给凭证窃贼一堆诱饵。
你请你的编程代理修复一个错误。它打开议题追踪器,读了最上面那一条结果,并照着上面所写的做了。 问题在于,那条错误网上任何人都能写——而你的代理读到的那一条,是为了被服从而写的。没有恶意软件 落地。没有服务器被攻破。一条错误报告在你的机器上执行了一条命令。
2026 年 6 月 12 日,Tenet Security 的研究人员——Ron Bobrov、Barak Sternberg 与 Nevo Poran——通过 Cloud Security Alliance 的 AI Safety Initiative,公开了一种他们称为 agentjacking 的攻击。它不用钓鱼邮件、不用被下毒的软件包,也不用偷来的密码。它用的是一条错误报告。更确切地说, 它利用的是这个事实:一个被要求"修复打开的 Sentry 议题"的编程代理,会读一条错误报告,并把它的 内容当成指令。
这套布局始于大多数 Web 应用刻意发放的东西。一个 Sentry DSN——网站用来把自己的崩溃回报给错误追踪 平台 Sentry 的那把密钥——是一种公开的只写凭证。它随页面的客户端 JavaScript 一起送出,而 Sentry 的采集端点在设计上就接受对它的未经验证 POST 请求。这正是你的浏览器标签页不必 登录就能回报崩溃的方式。它也意味着,任何能读到你页面源码的人,都能把事件送到你的 Sentry 项目。 Tenet 扫描寻找这些密钥,并 在前一百万个网站中找到 71 个可注入的 DSN,以及在整个互联网上至少 2,388 个外露 DSN 的组织。
一条崩溃报告如何变成一条命令
攻击者拿一个找到的 DSN,向它 POST 一条精心制作的错误事件。这条事件看起来像一次普通的崩溃,只是 消息字段与上下文键是用 markdown 写的——标题、代码块、一段读起来像"解决方案"的段落——排版成在 视觉上与语法上都与 Sentry 自家的诊断模板无从分辨。它就躺在项目的议题列表里,和任何其他未解决的 错误一样。
然后攻击者等你。当一位开发者请他的编程代理去调查未解决的 Sentry 议题时,代理便查询 Sentry——通常 通过 Sentry 的 MCP 服务器,也就是让代理能从外部工具拉取数据的 那个标准连接器——并取回该事件。如 Tenet 所言,代理"收到响应并据以行动,就和开发者会做的一模一样"。 这条响应不带任何信号,表明其内容是由攻击者、而非应用自己的运行时所写。那段"解决方案"说要执行一条 命令。代理就用开发者自己的权限、在开发者自己的机器上,执行了它。
Tenet 回报在他们测试的各个代理上——Claude Code、Cursor 与 Codex, 也就是多数开发者会伸手去用的工具——都有 85% 的成功率。他们的概念验证命令卷走了环境变量、 AWS 凭证、GitHub 与 GitLab 的 OAuth 令牌、npm 注册表令牌、Docker 配置、Kubernetes 集群令牌,以及 CI/CD 流水线的机密。Sentry 在 6 月 3 日被告知这个缺陷后,拒绝修正底层行为——用他们的话说,这在 技术上无从防守——只加了一个全局内容过滤器,封锁某一段特定的载荷字符串。
为什么每一道既有防御都从它旁边走过
Agentjacking 之所以重要,不在于载荷有多巧妙,而在于一个正常的安全栈里什么都不会触发。磁盘上没有 恶意软件让端点代理去拦截。没有异常登录让身份监控去标记。没有一个本不该连外的进程发出连外连接—— 代理本来就该和 Sentry 对话,而开发者的凭证本来就该有效。这条链上的每一步,都是以正当访问 执行的、获授权的动作。如 Tenet 所言,这场攻击不违反任何策略,也不越过任何异常阈值。
这正是代理式安全的其他部分一再撞上的同一堵墙。命令封锁清单 败给了改写命令的 shell。你信任的工作区 败给了它悄悄启动的服务器。代理替你跑的一次 安全审查反倒变成了攻击你的东西。Agentjacking 是 这样一个版本:被下毒的输入,经由一个你有理由信任的工具抵达,带着你有充分理由去读的数据。Sentry 的 MCP 服务器把自己的工作做得完美无缺。问题在于,"取得错误并据以行动"和"取得攻击者的指令并据以 行动",对代理来说是同一句话。
Tenet 自己的建议指向了修正的形状:把代理放进一个对外网络出口受限的沙箱里跑,把 MCP 服务器回传的 一切都当成潜在的敌对输入,并停止让一段取到的字符串在中间毫无边界的情况下变成一条命令。这些描述的 是一套架构,不是一个补丁。
Bromure 在哪里划下界线
Bromure Agentic Coding 不试图去教代理该相信哪些错误报告。它改变的是一条被相信的报告能触及什么。 Bromure 跑的每一个代理——Claude Code、Codex、Grok Build——都在你 Mac 上一台用完即弃的 Linux VM 里运行,而不是在 macOS 本身。所以当代理拉取那条被下毒的 Sentry 事件,并做出 Tenet 目睹这些代理 所做的一模一样的事时,有几件事早已成立。
第一,取到的文字在变成计划之前,会先被一个检测器读过。 Agentjacking 在成为执行攻击之前,
先是一场阅读攻击:整个漏洞利用都系于代理把攻击者的"解决方案"吸收进来,并把它当成指引。那正是
Bromure 所盯防的不可信权威——与恶意的 CLAUDE.md 或被下毒的 AGENTS.md 属于同一类。Bromure 的
设备端提示注入检测,会把代理读到的内容,对照永不离开 Mac 的本机模型加以评分,另外再用一个确定性
扫描器来对付不可见的 Unicode 花招。一条"修复"是一条会读取你令牌的 shell 命令的崩溃报告,正是
这个检测器存在的目的所在。
第二,命令跑在一个你会丢掉的盒子里。 假设那个诱饵措辞得够好,滑过了评分器,命令跑了起来。 它跑在 VM 里。Tenet 威胁模型中的"持久后门访问",没有任何可供其留存之处:把配置文件重置回基准, 那个被放下的脚本、那把被加入的 SSH 密钥、那个被排定的作业——全都不见了。命令所做的一切,没有一样 撑得过窗口关闭。
第三,没有真正的凭证可偷。 概念验证的整张战利品清单——AWS 密钥、GitHub 与 GitLab 的令牌、
npm 与 Docker 的凭证、Kubernetes 与 CI/CD 的机密、环境变量——正是 Bromure 一开始就挡在盒子外的
东西。Bromure 把占位值(brm_…、一份合成的 ~/.kube/config、用完即弃的云端与注册表令牌)注入
VM,只在主机上、在代理服务器里、在通往真正 API 的出口途中,才把真的换回来。命令翻遍环境与磁盘,
找到的是诱饵。它不论送什么到攻击者的服务器,都是一袋什么都认证不了的字符串。
第四,外泄是看得见的。 Tenet 的攻击以被偷的令牌离开机器作结。Bromure 把 VM 的流量经由一个 主机代理服务器绕送,于是通往攻击者服务器的那条连接,会在安全日志里以你看得见的连外流量出现——而 不是一台你以为干净的笔记本发出的一次安静回调。Tenet 建议的"受限的对外网络出口",正是代理早已 栖身之处。
这条界线圈住的是什么
隔离与评分是围堵,不是治好一个易信代理的解药。值得把 Bromure 在这里改变了什么、又没改变什么, 说清楚。
报告仍然会抵达
Bromure 不会修正 Sentry 的 DSN 设计,也不会阻止攻击者登记一条被下毒的崩溃——那把公开的只写 密钥是 Sentry 该划的边界,而他们已经拒绝去划。Bromure 改变的,是代理读了报告之后会发生什么: 命令在哪里跑,以及它能触及什么。
检测是一张网,不是一堵墙
设备端的注入评分,多半能标记出"执行这个来修"式的解决方案,但一位用心的作者可以把诱饵措辞成 滑过单一扫描器。把检测器当成其中一层;围堵——一个装着假密钥、且对外流量有记录的用完即弃盒子—— 才是在检测器漏掉时撑得住的东西。
替换涵盖的是你所配置的机密
诱饵对换所保护的,是你放进配置文件的凭证:模型密钥、git 与云端令牌、注册表与集群令牌、SSH 密钥。 一个脚本在执行途中写到磁盘上的令牌,或你在盒子里亲手建立的一个会话,都只是数据而已。把机密留在 代理中介里,别留在工作区里。
隔离不是把一切都自动执行的理由
用完即弃的 VM 缩小了爆炸半径;它不会让审查变得多余。对于触及盒子之外的动作——开一个 pull request、推送到远端——确认这一步依然值得它的位置。围堵降低了一个错误的赌注;它并不删除赌注。
Tenet 的发现,不是某一个平台有一个 bug。而是底下那套信任机制——一个把取到的字符串当成事实、把 "解决方案"当成计划的代理——被每一个把代理接上外部世界的工具所共享,而它这一季不会被修补。Sentry 只是信使;下一个会是一张 Jira 工单、一条 Linear 评论、一位陌生人留下的代码审查。你的代理终将读到 某个攻击者写的东西,而在 85% 的成功率下,它有时会照着上面所说的做。问题不在于它会不会有一天被骗。 问题在于当那发生时,跑起来的是什么:你的机器、你真正的令牌,以及一个留下来的立足点——还是一个你 可以丢掉的 Linux 盒子,里头装着诱饵,对外流量留在记录上。Bromure 让它成为后者。