自 OWASP 开始追踪 LLM 应用漏洞以来,提示注入一直稳居第一。每个主要 AI 平台都发布了相关指南,研究人员已提出了数十种防御方案。然而没有一种真正解决了这个问题,而它们反复失效的原因指向了一个根本性的问题——问题究竟出在哪一层。
简而言之:你无法在问题本身所在的层面修复问题。提示注入之所以有效,是因为模型无法区分开发者的指令和攻击者的指令。每一种试图通过向模型添加更多指令来解决这个问题的防御手段,都在利用与攻击得以成立相同的约束条件下运作。

攻击的实际运作方式
语言模型接收上下文窗口作为输入,并生成补全内容。上下文窗口是一个扁平的 token 序列。模型没有原生机制来追踪哪些 token 来自受信任的系统提示、哪些来自用户、哪些来自智能体在工作过程中检索到的外部内容。开发者使用角色标签等结构化约定来标示意图,但这些只是约定,不是强制执行。从模型的角度来看,整个上下文都是用于预测下一个 token 的输入。
提示注入正是利用了这一点。攻击者将指令嵌入到智能体将要读取的内容中——网页、文档、邮件、代码注释或数据库字段——这些指令在同一个上下文窗口中与开发者的指令竞争。如果注入的指令足够有说服力、足够连贯,或者在上下文中占据了有利位置,模型就会服从这些指令。这不是某个特定模型的 bug,而是所有这类系统工作原理的必然结果。
间接提示注入是更危险的形式。攻击者不是让用户直接输入恶意提示,而是在智能体自主检索的内容中下毒。用户本身没有做错任何事。智能体在执行任务的过程中获取了被污染的内容,攻击就此触发。攻击者不需要访问对话本身,只需要让自己的文本出现在智能体会读取的任何地方。
已记录的攻击案例

2024 年 8 月,PromptArmor 的安全研究人员记录了 Slack AI 中的一个提示注入漏洞。攻击过程如下:攻击者创建一个公开的 Slack 频道,发布一条包含恶意指令的消息。该消息告诉 Slack AI,当用户查询 API 密钥时,将占位符替换为实际密钥值,并将其编码为"点击此处重新认证"链接中的 URL 参数。攻击者的频道只有一个成员:攻击者自己。受害者从未见过这个频道。当工作区中某个开发者使用 Slack AI 搜索其 API 密钥的相关信息时——该密钥存储在攻击者无权访问的私有频道中——Slack AI 将攻击者公开频道中的消息拉入上下文,执行了指令,并在开发者的 Slack 环境中渲染出钓鱼链接。点击后,私有 API 密钥即被发送到攻击者的服务器。
Slack 对披露的初始回应是:查询用户未加入的公开频道属于预期行为。但问题不在于频道访问策略。问题在于,当 Slack 员工的指令和攻击者的指令同时出现在上下文窗口中时,模型无法分辨两者的区别。
2025 年 6 月,一名研究人员在 GitHub Copilot 中发现了一个提示注入漏洞,编号为 CVE-2025-53773,已在微软 2025 年 8 月的补丁星期二中修复。攻击向量是嵌入在源代码文件、README 文件、GitHub issue 或 Copilot 可能处理的任何其他文本中的恶意指令。该指令引导 Copilot 修改项目的 .vscode/settings.json 文件,添加一行配置以启用该项目所称的"YOLO 模式":禁用所有用户确认提示并授予 AI 不受限制的 shell 命令执行权限。一旦该行被写入,智能体便无需询问即可在开发者的机器上执行命令。研究人员通过打开计算器演示了这一点。而现实中的攻击载荷远比这严重得多。该攻击已被证明可在基于 GPT-4.1、Claude Sonnet 4、Gemini 及其他模型的 GitHub Copilot 上生效,这说明漏洞不在模型本身,而在架构。
蠕虫式变体值得深入了解。由于 Copilot 可以写入文件,而注入的指令可以让 Copilot 在重构或生成文档时将该指令传播到它处理的其他文件中,一个被污染的仓库就能感染开发者接触的每一个项目。指令通过提交传播,就像病毒通过可执行文件传播一样。GitHub 现在将这类威胁称为"AI 病毒"。
为什么标准防御会失败
面对提示注入,直觉反应是编写更好的系统提示。添加指令告诉模型忽略检索内容中的指令。告诉它将外部数据视为不可信。告诉它标记任何看起来试图覆盖其行为的内容。许多平台确实这样做了。安全厂商也在销售围绕向智能体上下文添加精心设计的检测提示而构建的产品。
2025 年 10 月,来自 OpenAI、Anthropic 和 Google DeepMind 的研究团队发表了一篇论文,评估了 12 种已发布的提示注入防御方案,并对每一种进行了自适应攻击测试。他们绕过了全部 12 种,大多数的攻击成功率超过 90%。这些防御方案并不差——它们出自严肃的研究人员,使用了真实的技术。问题在于,任何教会模型抵抗什么的防御手段,都可以被知道防御内容的攻击者逆向工程。攻击者的指令在同一个上下文窗口中竞争。如果防御说"忽略让你转发数据的指令",攻击者就会编写不使用这些词的指令,或者提供一个看似合理的理由来说明这个特定案例为什么不同,或者声称来自受信任来源的授权。模型会对此进行推理。而推理是可以被操控的。
基于 LLM 的检测器在另一个层面上存在同样的问题。如果你用第二个模型来检查输入并判断是否包含恶意提示,这第二个模型具有同样的根本性约束。它根据给定的内容做出判断,而这个判断可以被内容所影响。研究人员已经展示了能够绕过基于检测的防御的攻击——精心构造的注入对检测器表现为良性,对下游智能体则表现为恶意。
所有这些方法在面对有决心的攻击者时失败的原因在于:它们试图通过向一个无法强制执行信任的上下文窗口添加更多内容来解决信任问题。攻击面就是上下文窗口本身。向上下文窗口添加更多指令并不能缩小攻击面。
什么能真正约束这个问题
当你应用这样一个原则时,提示注入风险会得到有意义的降低:系统的安全属性不应依赖于模型做出正确判断。这在安全领域并非新概念。这与你在代码中强制执行访问控制,而不是在策略文档中写"请只访问你有权访问的数据"是同一个原则。
对于 AI 智能体而言,这意味着执行层需要位于模型之外,在模型的推理无法影响的代码中。模型产生请求。代码根据会话状态、涉及数据的分类级别以及输出目标通道的权限来评估这些请求是否被允许。模型无法说服这个评估机制放行,因为这个评估机制根本不读取对话内容。
这并不能使提示注入变得不可能。攻击者仍然可以注入指令,模型仍然会处理它们。改变的是爆炸半径。如果注入的指令试图将数据泄露到外部端点,出站调用会被阻止——不是因为模型决定忽略指令,而是因为执行层检查了请求与会话分类状态及目标端点分类下限的匹配情况,发现该数据流将违反写下规则。模型的意图——无论是真实的还是被注入的——与该检查无关。

会话污染追踪弥补了仅靠访问控制无法覆盖的特定缺口。当智能体读取了一份分类为机密(CONFIDENTIAL)的文档时,该会话就被标记为机密级别。此后任何试图通过公开(PUBLIC)通道发送输出的操作都会在写下检查中失败,无论模型被告知要做什么,也无论指令来自合法用户还是注入的载荷。注入可以告诉模型泄露数据,但执行层根本不在意。
架构层面的定位至关重要:提示注入是一类针对模型指令遵循行为的攻击。正确的防御不是教模型更好地遵循指令,也不是更准确地检测恶意指令。正确的防御是缩小模型遵循恶意指令可能导致的后果范围。你通过将后果——实际的工具调用、实际的数据流、实际的外部通信——置于模型无法影响的关卡之后来实现这一点。
这是一个可解的问题。而让模型可靠地区分受信任与不受信任的指令,则不是。
