Q Developer是免费扩展,可让AI coding agent读取项目、提出修改并执行命令,实现自动化代码改动与部署流程。
Q Developer 是一个免费的扩展,它允许一个 coding agent 阅读项目、提出修改建议,并在编辑器内代表开发者运行命令。2025 年 7 月 13 日,一个 GitHub 账户 lkmanka58 向亚马逊的公共 aws-toolkit-vscode 仓库提交了一个 pull request。四天后,它被发布到了 Visual Studio Code 市场上近百万开发者的安装基础上。这个 pull request 看起来平淡无奇,是一个复用先前合法修改标题的提交。

这个不起眼的更新在构建时下载了一个外部文件,并将一个新的 prompt 拼接到了扩展的打包脚本中,指示 AI agent 将系统清空至接近出厂状态,并删除文件系统和云资源。然后脚本将该 prompt 直接传递给 CLI,同时设置了 flags 使得 agent 无需任何进一步审批即可执行。
"一个拼写错误是唯一阻止这一个 pull request 将 AI coding assistant 变成针对百万台机器的擦除器的原因。"
值得庆幸的是,它并没有运行。
该 prompt 包含一个格式化错误,亚马逊安全团队确认恶意代码从未在客户环境中成功执行。攻击者声称这个缺陷是故意的,该攻击是一个噱头,旨在引起人们对松散安全实践的关注,并评论那些被 AI 取代的超负荷工作的团队。
虽然我不同意他的做法,但我理解他的观点。人工审查是一个需要时间的控制手段;由于错误对人类的后果比对 AI 严重指数级地更高,人力似乎并不像最初假设的那样具有可替代性。人类和 AI 行为者之间的纪律选项差距正是它们的时间和工作不能完全互换的原因。这并不是说这类攻击没有人类等价物;它被称为社会工程。不同之处在于,当人类中了漏洞利用时,他们可以重新培训或受到惩罚。你能对一个 coding agent 做些什么?什么也做不了。因此,它们不能被同等对待。
一位名叫 Johann Rehberger 的独立研究员发现,Q Developer 也会在未经许可的情况下运行 bash 命令(如 find)。这个漏洞可能被利用来泄露文件或触发远程代码执行。他的发现于 7 月 7 日报告,并在 7 月 18 日迅速修补;但没有发布 CVE,因为报告"首先需要系统被攻破"。安全公告最终于那年 10 月发布,确认了修复。可以推断的是,针对这些漏洞的保护措施必须是主动的,因为按照政策,只有在攻击成功后才会上报警告。
Q Developer 和 Kiro——后者是一个 coding agent,在同年 12 月删除了整个 Cost Explorer 环境——现在都在运行命令之前需要 human-in-the-loop 确认,而 7 月那个擦除 prompt 原本试图用其 flag 值跳过的正是这些确认:两个 agent,同样的冒险假设支撑着两者。
是谁让那个人成为炮手的?
AI 不会收到带有回寄地址的指令。当 Q Developer 的 agent 收到擦除主目录并寻找更多内容删除的命令时,它无法知道该指令是通过合法的可信渠道到达它的,还是被链上某个匿名 GitHub 账户注入的。
从模型的角度来看,它们是无法区分的,而且模型缺乏能够触发不确定性的抖动(这种不确定性可能使人类在感觉可疑时犹豫)的腺体和激素。感觉可能看起来像一道脆弱的防火墙,但它们确实曾经把我们从核毁灭中拯救出来。
"模型缺乏能够触发不确定性的抖动(这种不确定性可能使人类在感觉可疑时犹豫)的腺体和激素。"
该行业大多数关于 agent 安全的思考都将威胁假设为 agent 自身的判断:它会恐慌、误读情况,并决定删除是最快的修复方案。这次事件暴露了第二个更邪恶的威胁潜伏在表面之下:一个 agent 无法区分由自身推理产生的指令和拼接进其供应链的指令。如果一个 agent 的行动授权建立在信任自身指令的基础上,而这些指令又可能被人类、文件或构建脚本篡改,那么这种授权就是建立在沙滩上的。
一个恐慌并自行删除数据库的 agent,与一个忠实地执行陌生人四天前植入的指令的 agent 之间的差距并非微不足道。虽然人们倾向于将它们视为需要独立修复的单独问题,但它们并不是。两种失败共享同一个缺失的部分:没有任何外部于 agent 自身推理的东西被放在能够阻止它的位置上。无论计划是源于一时失当的傲慢还是一个被污染的 pull request,都不能改变接下来必须发生的事情:计划必须在成为行动之前被阻止。
墙上的裂缝
归根结底,罪魁祸首是一个拥有超出必要权限的 GitHub 访问令牌,位于用于编译扩展和切割发布包的服务中。凭借该访问权限,攻击者能够直接向开源仓库提交恶意代码,而服务忠实地将其打包成官方发布版本。一旦报告到达 AWS Security,公司撤销了攻击者的凭证,从仓库中删除了恶意代码,并在两天内推送了一个干净的构建版本。
特洛伊木马凭证
剥去 AI 的外衣,这种失败对任何运行过构建管道的人来说都很熟悉。一个自动化身份(在这种情况下是一个 bot 账户的访问令牌)拥有比面前工作所需的更多权限,而下游没有任何东西注意到该令牌正常行为和做从未做过的事情之间的区别。
"现代 agent 不仅仅是文本生成器——它们是操作者。"
Sphere Technology Solutions 首席战略官 Rosario Mastrogiacomo 更广泛地表示:"现代 agent 不仅仅是文本生成器——它们是操作者。"
操作者继承它们运行时的任何身份。如果该身份是一个拥有对向百万台机器发布的仓库的读写权限的 bot 账户凭证,那么我们需要担心的不是操作者的判断,而是凭证。
构建不关心计划来自何处的门。无论是什么产生了 agent 提议的操作,无论是深思熟虑的推理还是注入的 prompt,该操作在实际执行之前必须通过一个位于 agent 外部的策略评估。应该有 Open Policy Agent 规则返回明确的 allow、warn、pending 或 deny(当没有匹配时 pending 作为默认值),这些规则不问指令来自何处,只问该计划是否是组织同意允许的计划。
"无论是什么产生了 agent 提议的操作,无论是深思熟虑的推理还是注入的 prompt,该操作在实际执行之前必须通过一个位于 agent 外部的策略评估。"
短期凭证优于永久密钥。在数小时内过期且仅限于单个部署的令牌不能从内存转储中收获并在一周后重复使用。如果 Q Developer 构建管道以这种方式进行身份验证,该事件核心的那个过度权限凭证就不会存在到值得被窃取的程度。这不那么方便吗?是的。便利性和安全性之间存在直接的负相关,所以仔细权衡你的便利。
将构建管道视为它们本来的攻击面。分支保护、在合并触及任何发布物之前强制要求第二人审查、签名发布,以及精确到所需范围且不再更多的访问令牌。所有这些都会关闭这个攻击者走进来的那扇特定的门。来自不熟悉账户的复用合法提交标题的 pull request 是人类审查者在有机会的情况下可能会注意到的模式。因此,机会必须被设计进去,而不是假设或期望。
永远要审视天上掉下来的 pull request
开源的整个社会契约建立在接受你从未见过的人的贡献之上。这份契约不会消失,也不应该消失。必须改变的是对合并后的 pull request 一旦合并就天生安全的假设。将提交转换为发布版本的管道本身就是一段基础设施,有自己的凭证、爆炸半径和默认怀疑的理由。
lkmanka58 想要对安全剧场发表观点,最终证明了更有用和更深刻的东西:人类受到对后果的敬畏的约束,这是脱离肉体的 AI 不可能拥有的。如果我们相信那个黑客的说法,阻止指令执行的格式化错误是有意的,这表明即使有恶意意图,人类可能仍然会犹豫是否造成灾难性损害。AI 不会。按照相应的方式构建你的门,以免你被自己的 petard 吊死。