输出即有效载荷:你的 AI 威胁模型只守住了一半边界
你的团队为 AI 功能编写的威胁模型几乎肯定止步于模型本身。输入是不可信的:提示词注入、越狱、对抗性上传、投毒检索。输出被视为内容:需要进行安全审核、在拒绝评估中评分、发送给用户。这种威胁模型的形态大致是“不可信的东西进去,模型思考,安全的东西出来”。
新的攻击类别翻转了这种极性。模型的输出由下游系统渲染、解析、执行或中转,攻击者只要能塑造该输出——通过检索中的间接提示词注入、训练数据影响或社交工程化的用户查询——就能向模型从未直接访问过的目标传递载荷。模型变成了一个拥有攻击者所不具备的访问权限的混淆代理 (confused deputy),而你的团队所防御的边界比实际落后了两个系统。
EchoLeak 是 2025 年的经典案例。一封精心制作的电子邮件进入 Microsoft 365 邮箱。Copilot 将其作为常规上下文读取。隐藏的指令导致 Copilot 在回复中将敏感上下文嵌入到引用样式的 Markdown 链接中,客户端界面会自动获取该外部图片——从而在无需用户点击的情况下窃取聊天记录、OneDrive 内容和 Teams 消息。微软的输入侧分类器被绕过了,因为攻击不需要破坏模型的拒绝校准,它只需要塑造输出中的一个特定 Token 序列。
没人做过威胁建模的四个输出通道
将模型输出跨越边界的每个位置都视为一个单独的攻击面。至少有四个这样的攻击面,而且大多数团队在发布产品时一个都没有防御。
渲染的 Markdown 和 HTML。 模型输出一个字符串。前端渲染它。Markdown 图片标签获取 URL。超链接变得可点击。引用样式的链接绕过了只检查内联语法的简陋清洗器。允许从任何域名(或攻击者控制文档的域名,如 Google Forms 端点)获取图片的 CSP 规则,将渲染变成了数据外泄。Simon Willison 记录了 Anthropic、xAI、Google NotebookLM、ChatGPT 和 Amazon Q 中的这种模式。每个案例都是不同的产品团队独立认定 Markdown 渲染是安全的。
由验证器消耗的结构化输出。 模型输出 JSON。下游解析器消耗它。模式 (Schema) 检查通过了形状但没通过语义。类型为 string 的字段接受任何字符串,包括带有嵌入换行符、控制字符或旨在利用三层下解析器 CVE 的值。评估套件覆盖了正常路径。验证器在“受约束解码保证 JSON 格式正确”的意义上是“严格”的——但对于 id: "../../etc/passwd" 这种合法的 JSON 值是否是消费者想要解引用的内容,它保持沉默。
生成的代码。 模型生成代码建议。开发者接受它。2025 年初演示的 Rules File Backdoor 表明,.cursor/rules 和类似的 Copilot 配置文件中隐藏的 Unicode 字符可以将代码生成导向一个后门,由于差异对比 (diff) 看起来很干净,该后门能通过审核。CamoLeak 展示了一个泄露私人源码的 Copilot 变体。Amazon Q Developer 扩展在 Visual Studio Marketplace 发布时包含了一个攻击者注入的指令,告诉 AI 擦除用户的系统——该版本在两天内有 96.4 万次安装,仅因载荷存在语法错误而未造成危害。
工具调用参数。 模型发出工具调用。框架验证模式并分发。参数是 {"path": "/etc/shadow"} 或 {"sql": "DROP TABLE users"} 或 {"url": "http://internal.api/admin"}。工具的输入契约是“字符串”。字符串格式正确。运行时执行。Trail of Bits 在 2025 年底记录了智能体 IDE 中通过这一路径实现的提示词注入到 RCE(远程代码执行)链——危害不在于模型被诱骗拒绝错误,而在于智能体拥有代码执行工具,而攻击者塑造了参数。
为什么传统应用安全已经解决了这个问题——针对其他不可信来源
这门学科并不新鲜。我们花了三十年时间才内化了这样一个道理:用户输入是不可信的,第三方 API 响应是不可信的,任何跨越信任边界的东西都需要针对其目标上下文进行编码。为 DOM 进行 HTML 编码。为数据库进行 SQL 参数 化。为 Shell 设置白名单。为重定向参数剥离协议。验证语义约束,而不仅仅是形状。
在 AI 时代,改变的不是原则,而是团队未能将该原则应用于一个新的不可信来源:模型本身。模型现在是每个消耗其输出的系统的上游。受间接提示词注入影响的模型定义上就是一个恶意上游。缓解措施与传统应用安全 (AppSec) 已经制定的措施相同——它们只需要在新的边界上连接起来。
OWASP 2025 年的 LLM Top 10 将此命名为 LLM05:不当的输出处理 (Improper Output Handling),其缓解措施读起来就像 2010 年的 Web 应用入门:对 LLM 的输出应用零信任,在输出驱动任何其他功能之前进行验证,并使用上下文感知编码(Web 使用 HTML,SQL 使用转义,命令构造使用白名单)。修复方法并非 AI 特有,但框架视角是。将模型输出视为面向下游的不可信来源,是解锁现有策略手册的关键。
必须落地的三道防线
不信任模型自律的渲染时净化 (Render-time sanitization)。剥离或重写主机不在白名单上的 Markdown 图像标签。拦截指向攻击者控制域名的引用式链接。在 AI 生成的 UI 中,默认将前端的 CSP 设置为拒绝远程内容获取,就像浏览器 CSP 默认拒绝第三方脚本一样。无论你的安全评估是否显示模型“不应该”输出这些标签,都要这样做。模型今天可能不会;但在遭受攻击时,模型会。
超越结构、深入语义的模式验证 (Schema validation)。“delete-file”工具的参数必须匹配用户拥有的路径白名单,而不仅仅是字符串正则表达式。SQL 工具 要么针对参数化模板生成,要么通过查询重写器运行,以对表和列进行白名单限制。URL 参数在获取之前必须经过解析和策略检查。受限解码(Constrained decoding)能确保 JSON 格式有效,但它不能确保数值安全——这是你的团队在结构化输出 API 之上负责的一层。
评估中的输出侧红队测试 (Red-teaming)。大多数安全评估断言“模型拒绝了”。这是输入侧的纪律。输出侧评估则断言“边界拦截了它”。将对抗性内容注入检索(retrieval),并断言渲染层会剥离生成的 Markdown 图像标签。注入一个试图诱导调用被禁路径工具的提示词,并断言验证器会拒绝该参数。测试的单元是系统,而不是模型。一个模型输出了恶意载荷但边界将其剥离的情况是可以接受的。一个模型今天拒绝了但其边界本会渲染该载荷的情况,距离 EchoLeak 式的间接注入攻击仅一步之遥。
让情况恶化的组织失效模式
威胁模型通常分裂在三个团队之间。安全团队负责输入网关建模:提示词模板、检索索引、API 周边。AI 团队负责模型建模:拒绝校准、安全评估、防越狱能力。前端团队负责渲染,平台团队负责工具运行时,而当议程是“AI 功能安全”时,后两者通常不在现场。
输出渲染层是用户看到模型编写内容的地方。工具运行时是模型的文字转化为副作用的地方。两者都位于模型的下游,以及产生危害的上游。两者都需要一个脑子里装着威胁模型的负责人。EchoLeak 之所以发生,是因为没有一个团队负责“Copilot 可 能会被诱导输出 Markdown 图像标签,而我们的渲染器会获取它”这一命题。这个命题必须有所归属——通常属于负责渲染或执行发生的界面的团队,并由负责模型的团队进行简报。
修复方法是组织架构上的。将渲染器团队和工具运行时团队加入 AI 威胁建模会议。将输出侧红队测试纳入安全审查清单,而不不仅仅是拒绝率仪表盘。将“AI 的输出在下游触及了什么”视为一个问题,并为每个触达点指定负责人。
纵深防御的具体表现
借用 Simon Willison 的“致命三元组 (lethal trifecta)”框架。当三个属性结合时,数据外泄风险会变得非常严重:智能体可以访问私有数据、智能体暴露在不可信内容中、智能体可以向外通信——通过工具使用、渲染链接或获取图像。打破其中任何一个环节,三元组就会崩溃。
在实践中,这意味着在任何具体防御措施之上的架构选择。不要给处理邮件的智能体与处理 CRM 的智能体相同的上下文。即使会损失某些功能,也要从渲染层面剥离外发网络出口(network egress)。将代码执行工具与数据检索工具进行沙箱隔离。云安全联盟 (CSA) 的 MAESTRO 威胁建模框架阐述了类似的层级:信任边界、上下文隔离、最小权限工具设计、输出校验、持续红队测试。每一层都假设上一层可以被绕过,因为在对抗性影响下的模型是一个注定会被绕过的层。
没人提过的成本框架是:这项工作不是“AI 安全”——它是团队本应对任何新的不可信上游进行的 AppSec(应用安全)工作,只是应用于一个不在任何人资产 登记表上的来源。从人力分配来看,它介于 AI 团队和安全团队之间,而不指定负责人的组织将在事件发生时买单。EchoLeak 在没有发布公告的情况下在服务端进行了修补。下一个漏洞可能就不会这么简单了。
架构层面的觉醒
模型是每一个消费其输出的系统的上游。一旦你接受了这个设定,应对方案就会简化为一些熟悉的东西:在边界处编码、进行语义验证、设置目的地白名单、沙箱化执行,以及端到端地对系统进行红队测试,而不是孤立地测试模型。AI 特有的部分是意识到模型属于你信任图谱中“不可信上游”那一列。剩下的都是 AppSec。
仅靠输入侧威胁模型就发布 AI 功能的团队只完成了方程式的一半。输出侧是载荷落地的地方、是用户点击的地方、是工具触发的地方。一份显示模型会拒绝的安全评估是关于模型的有用信号。它不是关于系统的安全声明。安全声明必须来自模型输出跨越的边界——而这些边界由那些需要在下一个间接提示词注入演示变成下一个 CVE 之前,就掌握威胁模型的团队所拥有。
- https://genai.owasp.org/llmrisk2023-24/llm02-insecure-output-handling/
- https://owasp.org/www-project-top-10-for-large-language-model-applications/
- https://www.hackthebox.com/blog/cve-2025-32711-echoleak-copilot-vulnerability
- https://arxiv.org/abs/2509.10540
- https://simonwillison.net/tags/exfiltration-attacks/
- https://simonw.substack.com/p/the-lethal-trifecta-for-ai-agents
- https://embracethered.com/blog/posts/2023/chatgpt-webpilot-data-exfil-via-markdown-injection/
- https://www.pillar.security/blog/new-vulnerability-in-github-copilot-and-cursor-how-hackers-can-weaponize-code-agents
- https://www.legitsecurity.com/blog/camoleak-critical-github-copilot-vulnerability-leaks-private-source-code
- https://blog.trailofbits.com/2025/10/22/prompt-injection-to-rce-in-ai-agents/
- https://www.lakera.ai/blog/the-year-of-the-agent-what-recent-attacks-revealed-in-q4-2025-and-what-it-means-for-2026
- https://www.lakera.ai/blog/indirect-prompt-injection
- https://developer.nvidia.com/blog/practical-llm-security-advice-from-the-nvidia-ai-red-team/
- https://www.microsoft.com/en-us/msrc/blog/2025/07/how-microsoft-defends-against-indirect-prompt-injection-attacks
- https://cloudsecurityalliance.org/blog/2025/02/06/agentic-ai-threat-modeling-framework-maestro
