提示注入是一个授权漏洞
2025年5月,一位研究人员在公共GitHub仓库上提交了一个问题。它读起来像是一个功能请求。
在其他地方,一位开发者向他们的编码代理提出了一个合理的问题:看看我公共仓库上的问题。
这包括一个名为Jupiter Star的私人项目、开发者计划搬到南美以及他们的薪水。
没有越狱。没有奇异的Unicode。没有对抗性后缀。模型从未被诱骗去做它没有权限做的事情。
Invariant Labs这个苏黎世团队在2025年5月26日演示了这一点,他们使用Claude 4 Opus对抗官方GitHub的模型上下文协议(MCP)服务器——代理用于调用外部工具的标准——使用一个可以同时看到两个仓库的令牌。
他们的结论值得钉在你的桌子上:
"这不是GitHub MCP服务器代码本身的缺陷,而是必须在代理系统层面解决的根本架构问题。这意味着GitHub无法仅通过服务器端补丁来解决这个漏洞。"
Invariant Labs,MCP GitHub漏洞披露,2025年5月26日
仔细想想。服务器行为正确,模型也是,令牌才是漏洞。
我大部分时间都在研究代理系统离开演示后为什么崩溃,以及评估销售修复方案的公司。我曾将提示注入归类为模型安全性,大约一年,接近越狱和拒绝训练。错误的抽屉。注入是传递机制。决定它是否重要的是工具调用背后的凭证集。
提示注入是一个授权漏洞。
1、每个人都在购买的防御
走过供应商展台,推销是一致的:分类输入,检测注入,在到达模型之前清理。
这里的工具是真实的,值得拥有。输入分类器捕获明显的有效负载。聚光灯和分隔符方案帮助模型区分指令和数据。系统提示得到加固。所有这些都提高了朴素攻击的成本,没有一个是浪费的。
它不能成为唯一的防线,有三个原因。
1. 通道是相同的。 LLM通过一个无区分的令牌流读取指令和数据。没有"这来自你的操作员"的特权总线,也没有"这来自网页"的污染标志。每个缓解措施都是在没有结构分离来执行的架构上分层的启发式方法。
2. 攻击面是代理读取的所有内容。 检索的文档。网页。日历邀请。代码注释。支持工单。工具自己的响应。这些都可以携带文本,而文本就是有效负载。你不是在防御一个输入框,你是在防御你的代理将要摄取的所有内容。(我专门在为什么你的MCP服务器是一个等待发生的灾难中映射了MCP服务器的这个表面。)
3. 检测针对开放空间运行。 分类器学习它见过的措辞。重新措辞是免费的,而生成重新措辞的模型与进行防御的模型属于同一类。这是你依赖你的爆炸半径的失败军备竞赛。(这与我在为什么大多数AI代理在生产中失败中写到的动态相同:演示成立是因为其中没有发生任何对抗性事情。)
GitHub在这里不是异常值。Aim Labs在Microsoft 365 Copilot中披露了EchoLeak为CVE-2025-32711,评分为9.3严重:一封看起来无害的电子邮件,无需点击,Copilot就泄露了其访问范围内的任何内容,跨越SharePoint、OneDrive和Teams。相同的形状,不同的供应商,同样有效负载通过助手已经持有的访问权限传播。
推动所有这三个,你会到达一个不舒服的地方。你不会将成功注入的概率降低到零。所以工程问题改变了形状。
不要问模型是否可以被说服进行调用。问问调用可以到达什么。
2、这个漏洞已经有了名字
安全在拥有语言模型之前很久就有这个问题了。
1988年,Norm Hardy描述了混淆的代理人:一个拥有合法权限的程序被权限较低的调用者诱骗代表调用者使用该权限。代理人正在做它的工作,使用它自己的凭证,为一个永远不应该能够请求的请求者。
再次阅读这个,心中想着一个代理。
你的代理持有一个令牌。不受信任的内容说服它进行调用。调用在代理的权限下执行。攻击者从未花费他们自己的任何东西。经典混淆代理人的所有属性都存在,唯一新的事情是说服以英语到达。
这意味着对策是旧的(能力研究自1980年代以来一直在这么说)。缩小代理人持有的范围,停止试图让它更难被混淆。
Simon Willison一直在用他所谓的致命三要素表达这个观点:一个可以访问私有数据、暴露于不受信任的内容以及有外部通信方式的代理。任何两个都是可存活的。一个代理中全部三个,成功的注入直接转化为数据泄露。注意这三个中有两个是授权决策。
3、你的代理实际持有什么
去看看今天生产中典型代理携带什么。打开环境变量,真相就在那里。
通常是一些长期存在的API密钥,每个集成一个,每个都限定在供应商仪表板在设置日提供的范围内。通常是帐户的完全读写权限。密钥不会过期。它不知道代理当前代表哪个用户操作。没有字段说哪个人委托了什么。
(Invariant的开发者正是运行这种设置,这就是为什么一个问题评论到达了私人仓库。)Descope在其自己的发布文章中将代理的静态API密钥称为"安全非启动器",在这一点上他们准确地描述了行业。
所以实际的失败链看起来像这样。(1) 不受信任的文本进入上下文。(2) 模型发出工具调用。(3) 工具使用广泛、永久且匿名的凭证执行。步骤3是坏句子变成事件的地方,步骤3是你完全控制的唯一一个。
值得做的事情都在那里。
4、限制爆炸半径
其中一些会成功。确保它们到达不值得拥有的东西。四件事完成了大部分工作,没有一件与模型层相关。
在阅读时针对GitHub泄露运行每一个(重要的测试是它是否会让Jupiter Star远离公共拉取请求)。
1. 给每个代理它自己的身份。 每个代理一个不同的身份,携带它代表的用户和它所属的租户。共享服务帐户和团队范围的密钥都未能通过此测试。没有它,接下来的三个都无法表达,你的审计跟踪在"服务帐户7做了它"处到底。仅此本身不会拯救Jupiter Star,之后没有任何东西在没有它的情况下工作。
2. 按工具限定范围。 重要的单元是单个工具调用,因此允许读取一个资源的令牌不应也允许写入另一个。Descope的Agentic Identity Hub在MCP服务器上实现了每个代理和每个工具的范围,当代理真正需要更多时逐步升级。最小权限是一个旧想法;新部分是将其应用于在运行时决定要调用什么的调用者。这是阻止GitHub攻击的那个,Invariant独立地得出了同样的结论:他们自己的缓解措施是最小权限令牌和每个会话一个仓库。
3. 使凭证短命并按需交换。 代理呈现它自己的令牌,并在使用时刻将其交换为狭隘的、过期的凭证。它根本不持有下游秘密。该机制标准化为RFC 8693令牌交换,这就是此类别中"代理"的含义。泄露的凭证在几分钟内过期并打开一扇门,与打开建筑物的永久密钥是非常不同的事件。5月的开发者的令牌既不狭隘也不短命,这就是为什么一个问题评论到达了薪水。
4. 在日志中保留委托链。 每个操作都应该追溯到代理、委托用户、租户、工具和范围。这就是使事件可调查的原因,在受监管的公司中,也是使它可辩护的原因。Descope记录了这些步骤中的每一个,从客户端注册到令牌签发到工具执行,并将它们流式传输到安全信息和事件管理(SIEM)平台。(问问自己你明天早上如何从自己的日志中重建GitHub序列。)
注意这四个控制有什么共同点。没有一个试图阻止注入。
它们都假设它有效,并使结果可存活。这就是重新构建,与停止提示,开始设计背后的直觉相同,那里的胜利进入了架构。
如果你想每周检查这个生态系统当周发布的内容,那是我的通讯,The AI Engineer。
5、为什么你现有的IdP在这里与你对抗
明显的反对意见:我们已经有Okta,我们已经有Entra,我们已经有身份。
你有,对人类来说(那里的假设值得大声说出来)。人类IdP下的假设是主体是人,人在需要同意时出现在浏览器中,访问是预先配置的并且变化缓慢。
代理打破了所有这三个假设。它们在凌晨3点自主行动,没有人在键盘旁。它们在运行时决定要使用哪个工具,因此它们的访问需求在调用时刻决定。代理从不真正代表自己行动,它代表用户行动,这意味着身份必须携带人类身份和访问管理没有字段的委托链。
这里的协议工作是真正新的,这就是为什么MCP认证即使对实现了十几次OAuth的人来说看起来也很陌生。代理作为没有人预先注册的客户端出现,因此注册必须在运行时发生。这就是动态客户端注册和客户端ID元数据文档的用途,以及OAuth 2.1和代码交换证明密钥(PKCE)。
Descope的答案是作为代理的专用授权服务器,独立或分层在你已经运行的劳动力IdP上。这是务实的形状:你的人类留在Okta中,你的代理获得一个理解它们是什么的身份控制平面。
Descope的免费层是开放的,上述机制可以在一个下午内检查。
6、这不能修复什么
它不能阻止注入。 有限的代理仍然会被说服去做事情。它调用它被允许调用的工具,使用它被允许接触的数据,出于错误的原因。当该集合敏感时,你仍然有事件。限定范围将爆炸半径缩小到代理合法需要的任何东西,而该底线永远不会是零。
限定范围是真正的工作。 必须有人决定每个工具可能接触什么,按代理,按租户。太紧代理会不断失败,你的团队会扩大范围以停止警报,这就是最小权限在实践中如何死亡的。太松你就是在用额外步骤重建API密钥。
只读代理仍然可以泄露。 数据泄露需要输出通道,而令人惊讶的是很多东西都是输出通道:渲染的图像URL、webhook、错误消息。(这是Willison三要素的第三条腿,也是人们忘记关闭的那条。)限定写入访问是简单的一半。
这个类别还很年轻。 代理身份标准移动得足够快,你今天构建的任何东西都需要重新审视。这是使用跟踪规范的基础设施的论据,同样也是不要将你的架构押在任何单一供应商的抽象上的论据。
在这里保持你的选择松散。
7、我在哪里着陆
我以一个自己打开的拉取请求和一个最终公开的薪水开始。
注入从来不是那个故事中有趣的部分。有趣的是GitHub无法修复它,Anthropic无法修复它,而开发者本可以通过给他们的代理一个一次只能看到一个仓库的令牌来修复它。
你无法使语言模型不可腐蚀,但你可以使它的凭证无聊。
周一早上的版本花费一个下午(这是我购买任何东西之前会运行的练习):拿一个你已经运行的代理,列出它持有的每个凭证,对于每一个,写下如果文档中的一段话告诉模型,攻击者可以用它做什么。那个列表是你真正的爆炸半径,大多数团队从未写下来。
原文链接:Prompt Injection Is an Authorization Bug
汇智网翻译整理,转载请标明出处