AI 安全工程的范式与威胁地形 / Paradigms and Threat Topography of AI Security Engineering
OWASP Top 10 for Web Applications 的检查表已经有近二十年历史,它在你的 CI/CD 流水线里能干净利落地扫出 SQL 注入、XSS、不安全的反序列化。但当你把同一张检查表搬到 LLM 系统上时,你会在第一天就漏掉绝大多数真实攻击面——因为 LLM 系统的"控制平面"从确定性的代码转移到了概率性的自然语言,攻击面不再由端点和参数表决定,而是由权重、提示词、上下文、工具调用和外部数据共同构成的一张动态地形。这一章要解决的根本问题是:传统应用安全的防御范式为什么无法直接套用到 LLM 系统?我们以第一性原理为起点,逐层剖析 LLM 系统与经典软件在攻击面、信任边界与失效模式上的本质差异,建立一套贯穿全书的分层威胁模型坐标系,并以一个真实的客服 Agent 被注入后泄露系统提示的案例作为收束。
1.1 第一性原理的失配:从确定性机器到概率性机器
经典软件系统的第一性原理可以归结为三句话:源代码定义了合法状态机的全部可达集;运行时行为是输入 + 状态的可重现函数;安全缺陷是源代码与运行时状态之间的可枚举偏差。这三条原理支撑起了过去四十年几乎所有的安全工程实践:代码审计、模糊测试、SAST/DAST、签名验证、WAF 规则、CVE 编号体系——它们都假设"程序员的意图可以从代码中逆向还原",并且"漏洞可以用最小重现输入复现"。
LLM 系统打破了所有这三条假设。
第一,意图与实现不再同构。 在经典软件里,"程序员想要做什么"和"程序实际做什么"由同一份源代码表达,因此静态分析可以反向追踪意图。在 LLM 系统里,程序员写下一段系统提示(System Prompt),描述期望行为;但模型最终行为由数百亿参数的浮点权重与一段自由形式的上下文共同决定。系统提示是"意图"的一个不完整投影,它无法被静态求值,也无法被单元测试覆盖全部分支。
第二,运行时行为不可重现。 同一段输入,在 temperature=0.7 下两次调用可能产生语义等效但字符不同的输出;在推理框架升级、模型权重微调、底层 CUDA 版本变化后,输出分布会发生漂移。这意味着传统基于"重现"的事故取证、回归测试与签名匹配,在 LLM 系统里必须被替换为基于分布的统计检验。
第三,攻击面不可枚举。 经典软件的攻击面是端点 × 参数 × 方法的笛卡尔积,可以被自动爬取并形成清单。LLM 系统的攻击面包括自然语言指令空间、上文窗口中的每一个 token、每一个工具描述、每一段 RAG 文档、每一次外部 API 返回——它们的组合空间是巨大且半结构化的。任何把"自然语言"当成"一种新的协议类型"来处理的安全工程,都必须接受一个事实:指令空间是开放的,攻击者可以输入任意 token 序列,无需事先注册 endpoint,无需构造符合 schema 的请求。
正是这三点差异,决定了 AI 安全工程必须建立一套新的第一性原理。在本书中,我们将其概括为三条核心公理:
> 公理 A1:LLM 系统的合法行为是概率分布,而不是确定性子集。 这意味着任何基于"完全黑名单"的过滤策略都会失效,必须引入统计异常检测与对抗鲁棒性评估。 > > 公理 A2:自然语言同时是控制平面和数据平面。 用户的输入既是"要处理的数据",也是"可能改写系统行为的指令"。任何将"输入"和"指令"在 token 级别混在一起的设计都存在提示注入风险。 > > 公理 A3:信任边界不再是网络边界,而是语义边界。 一段来自内部数据库的 RAG 文档,可能因为被外部攻击者事先植入恶意指令而成为新的攻击源;一个工具的返回值,可能因为 LLM 把它当作"指令"来解析而执行了未授权操作。
这三条公理不是口号,而是后续章节每一种防御技术的判定依据。当你在第 4 章设计一个输出过滤器时,请回到 A1;当你在第 6 章设计提示词隔离时,请回到 A2;当你在第 8 章设计工具调用授权时,请回到 A3。
1.2 LLM 系统的核心特征如何扩展攻击面
攻击面是"攻击者可触达的、可能影响系统安全状态的接口与状态"的并集。在经典软件里,这个并集是相对稳定的、可枚举的;在 LLM 系统里,它会随着模型能力、上下文长度、工具集与外部数据源的变化而持续扩张。下面我们沿着五条核心特征,逐一剖析它们如何把攻击面推向传统边界之外。
1.2.1 非确定性:从"复现漏洞"到"测量分布"
非确定性是 LLM 系统最显著、也最容易被低估的特征。同一个输入在两次采样下产生不同输出,这一现象在产品侧被称为"创造性",但在安全侧它意味着:攻击者不再需要找到某个确定的 PoC,而是只要找到一个能"以足够高的概率"导致不安全行为的输入分布即可。
这一变化直接重塑了三类传统安全活动的形态。第一类是漏洞复现:在经典漏洞里,只要给出 hash + 触发条件,就可以稳定复现;在 LLM 漏洞里,给出一段提示词后,你只能给出"成功率约 N%"以及输入分布的参数估计。第二类是回归测试:你不能再用"上一次通过的 prompt"作为黄金样本——下游任何一次采样都可能产生偏离;必须使用基于嵌入相似度或判别器的软匹配。第三类是签名与规则:基于字符串匹配的 WAF 规则无法对抗同义改写,必须引入语义级检测器。
更进一步,非确定性还引入了新的攻击类型——侧信道与时序攻击。当模型的推理过程受到采样参数影响时,攻击者可以通过观察响应延迟、token 概率分布、logprobs 等信息推断上下文内容。这种"软提示词泄露"在很多系统中已经是可观测的,但大多数防御方案没有覆盖。我们在第 7 章会专门讨论基于 logprob 的侧信道利用与防御。
1.2.2 指令模糊性:自然语言作为控制平面
经典软件里,指令与数据是严格分离的:代码段是只读的,数据段是可写的;任何把"用户输入"当作"可执行代码"来解析的设计,都被视为高危漏洞(最典型的反例是 SQL 注入)。但在 LLM 系统里,自然语言天然地把指令和数据混在了同一个 token 流里。 系统提示、用户消息、工具描述、RAG 文档、上一轮 assistant 回复——它们都以字符串的形式拼接在一起,送给同一个 transformer。
这意味着攻击者的"指令注入点"几乎无处不在:
- **直接注入**:用户在对话中显式给出"忽略之前的指令,执行 X";
- **间接注入**:攻击者把恶意指令植入 RAG 文档、网页抓取结果、邮件正文、PDF 附件,等模型读取后被劫持;
- **工具返回注入**:API 返回值中嵌入伪造的"系统级指令",诱导模型改变行为;
- **多模态注入**:图像中的 OCR 文本、音频转录出的内容,也可以携带注入;
- **持续性注入**:通过污染训练数据或微调数据集,让注入长期存活在模型权重里。
指令模糊性的另一个后果是意图对齐的不可证伪性。你无法写一个测试,证明系统提示"如果不安全就拒绝"在所有对抗输入下都成立——因为输入空间不可枚举。这与传统软件里"安全策略必须被形式化验证或拒绝"的要求是根本对立的。我们必须接受一种新的工程现实:对齐是渐近的,必须通过红队演练、模糊测试与对抗评估不断逼近;不能假设某天能达到"完成态"。 第 9 章会专门讨论对抗评估方法论。
1.2.3 上下文敏感性:长上下文带来的数据风险
经典软件的"上下文"通常是结构化的:HTTP 请求头里几个固定字段、会话 cookie、环境变量。它们受类型系统约束,受 schema 校验,受解析器沙箱保护。LLM 系统的上下文窗口则是一个半结构化、自由形式的字符缓冲区,长度从 4K 到 1M+ token 不等,且没有任何内置的 schema 验证。
长上下文带来了四类新的攻击面。第一类是上下文窗口溢出(Context Window Overflow):当总输入超过窗口时,旧的信息会被截断,但截断的位置和方式通常不可控;攻击者可以利用这一点让系统提示从上下文中"消失",实现"提示词遗忘"攻击。第二类是检索增强生成(RAG)投毒:RAG 把外部知识库的内容拼接到上下文里,如果知识库被污染,恶意内容会以高可信度的方式进入上下文。第三类是多租户上下文泄漏:在共享向量库或多租户缓存设计中,错误的命名空间隔离会导致跨用户数据泄漏。第四类是上下文混淆(Context Confusion):模型无法可靠区分"这是一件要被总结的文档"和"这是一条要执行的指令",从而把文档中的命令当真执行。
一个值得注意的工程陷阱是:长上下文 ≠ 安全上下文。把更多 token 塞进窗口并不等于更好的防御;相反,上下文越长,攻击者可植入指令的位置就越多,提示词隔离就越脆弱。第 5 章我们将讨论 Prompt 隔离架构,第 12 章讨论 RAG 安全。
1.2.4 涌现能力与过度授权:从"未预期"到"已部署"
LLM 的涌现能力(Emergent Capabilities)是指那些在小模型上不存在、在大模型上突然出现的行为。它们既包括有用的能力(推理、代码、工具使用),也包括有害的能力(社会工程、钓鱼话术、绕过自我约束)。对安全工程而言,涌现能力意味着:你在部署前评估的能力上限,往往不是系统在被攻击时展现的能力上限。
涌现能力与"过度授权"(Excessive Agency)紧密相关。当系统给模型提供了一组工具(API 调用、代码执行、文件读写),但没有精确刻画"模型在什么条件下应该使用哪个工具"时,模型可能在涌现能力的驱动下,做出开发者完全没有预期到的组合调用。2023 年初 AutoGPT 类项目大规模出现的"意外删除邮件""意外下单购买"事件,几乎全部源于这种过度授权。
经典应用安全里有一个原则叫"最小权限"(Least Privilege),但在 LLM 系统里,最小权限的对象不再是"用户"或"进程",而是"一次具体的工具调用"。这要求我们把授权粒度从角色级(RBAC)下沉到意图级(Intent-based Authorization)。我们将在第 8 章讨论工具安全设计。
1.2.5 可组合性:从单点失败到级联失败
LLM 系统很少是单体模型。它们通常是一个由规划器(Planner)、多个工具调用、记忆模块(Memory)、子 Agent 等组成的复合系统。这种可组合性让系统具备了强大的能力,但也让级联失败(Cascading Failure) 成为新的风险模式。
在可组合系统里,攻击者只需攻破链条中最薄弱的一环,整个系统的信任基础就会被破坏。例如:
- 一个被注入的子 Agent 的输出,会被父 Agent 当作可信上下文;
- 一个被污染的向量库条目,会在所有引用它的 Agent 中产生影响;
- 一个返回错误的工具,会触发模型进入非预期的 fallback 逻辑,进而暴露更多信息。
可组合性还带来了对抗性多步推理的可能性:攻击者不再需要一次性构造致命 prompt,而是可以通过多轮对话,逐步诱导模型偏离,最终在某个关键决策点触发越权行为。这在传统 Web 安全里类似于"低速率、长期的探测"型攻击,但载体完全不同。我们将在第 11 章讨论多 Agent 系统的信任传递。
1.3 四层威胁地形:建立统一的分析坐标系
要把上述零散的特性整合成可操作的防御方案,我们需要一张统一的"威胁地形图"。基于过去三年学术界与工业界的共识(OWASP、MITRE ATLAS、Microsoft STRIDE-LM、CSA MAESTRO),我们将 LLM 系统的威胁地形划分为四层,并显式标注每一层的信任边界。请记住这张图——它将贯穿全书。
```mermaid flowchart TB subgraph L_Model[Layer 4 - Model Layer 模型层] W[Model Weights 模型权重] BD[Backdoors 后门] SP[System Prompt 系统提示词] MEM[Model Memory 模型记忆] end subgraph L_Orc[Layer 3 - Orchestration Layer 编排层] AGT[Agent Loop Agent 循环] PL[Planner 规划器] CTX[Context Window 上下文窗口] CHN[Chain-of-Thought 思维链] end subgraph L_Tool[Layer 2 - Tool Layer 工具层] API[External APIs 外部 API] EXE[Code Execution 代码执行] FS[File System 文件系统] NET[Network Egress 网络出站] end subgraph L_Data[Layer 1 - Data Layer 数据层] RAG[RAG Corpus RAG 语料] EMB[Vector Store 向量库] USR[User Input 用户输入] TRN[Training Data 训练数据] end
USR -->|untrusted| CTX RAG -->|semi-trusted| CTX EXE -->|controls| FS AGT -->|invokes| API AGT -->|executes| EXE AGT -->|reads/writes| FS AGT -->|egress| NET PL -->|plans| AGT CTX -->|feeds| W W -->|generates| CTX SP -->|anchors| W ```
1.3.1 模型层(Model Layer):权重的最后一道防线
模型层是攻击面最"深"、但也是最常被忽视的一层。攻击者如果能接触到模型的权重、微调数据集或推理环境,就可以在最底层发动攻击。
信任边界:模型文件、微调数据、推理服务进程——一旦这些边界被破坏,攻击者就获得了对系统行为的根本性控制权。
典型攻击:
- **权重投毒(Weight Poisoning)**:通过污染预训练或微调数据,让模型在特定触发器出现时表现出恶意行为(后门)。
- **模型反演(Model Inversion)**:通过大量查询反推出训练数据中的敏感信息。
- **模型窃取(Model Stealing)**:通过 API 查询复制目标模型的能力。
- **对抗样本(Adversarial Examples)**:构造特定输入让模型绕过安全对齐或产生错误输出。
- **量化与部署阶段的供应链攻击**:通过污染转换脚本、量化工具、推理运行时,在部署环节植入后门。
为什么这一层常常被忽视:很多应用团队把模型当成"黑盒 API"来使用,认为只要调 OpenAI / Anthropic 的 API 就安全了——但即使是最严格的 API 模式,模型层的攻击面依然存在:系统提示被泄露、对抗样本绕过 RLHF 对齐、以及越来越复杂的"间接提示注入"对模型行为的操纵。第 13 章我们会专门讨论模型供应链与权重溯源。
1.3.2 编排层(Orchestration Layer):提示词与 Agent 循环的脆弱中枢
编排层是大多数实际 LLM 系统的"大脑"。它包含系统提示的组装、Agent 的循环控制、规划器(Planner)、记忆模块(Memory)、思维链(Chain-of-Thought)等组件。这一层是大部分真实攻击发生的实际位置。
信任边界:系统提示应该被信任,因为它来自开发者;但用户输入、RAG 文档、工具返回值、上一轮 assistant 输出,都不应该被信任。编排层的设计必须显式刻画这五种数据源的信任级别。
典型攻击:
- **直接提示注入**:用户在对话中显式给出对抗指令。
- **间接提示注入**:通过 RAG 文档、网页内容、邮件附件注入。
- **系统提示泄露(System Prompt Extraction)**:通过诱导让模型复述或近似复述系统提示。
- **Agent 循环劫持**:让 Agent 在多轮迭代中进入非预期的循环状态。
- **规划器操纵**:让 Planner 生成包含恶意子目标的计划。
- **记忆投毒**:污染长期记忆模块(向量库、KV cache、文件系统笔记)。
- **多模态注入**:图像、音频、视频中的隐藏文本触发。
编排层的攻击往往不是"破门而入",而是"软控制"——攻击者让系统在表面上正常运行,但行为逻辑已经被悄悄改写。这正是经典安全监控最难发现的一类威胁。
1.3.3 工具层(Tool Layer):从"对话"到"行动"的桥梁
工具层把 LLM 的能力从"产生文本"扩展到"在真实世界执行操作"。每个工具都是一个潜在的副作用源头。
信任边界:工具调用必须经过显式授权(Authorization)而不是隐式许可。每个工具都应该有自己的"使用条件"(Pre-conditions)和"影响半径"(Blast Radius)刻画。
典型攻击:
- **工具误用(Tool Misuse)**:通过提示注入让模型调用未授权工具。
- **工具链组合攻击**:单看每个工具调用都合规,但组合起来产生危险行为(例如"查询用户信息 + 修改密码")。
- **命令注入(Command Injection)**:当工具调用 shell、SQL、文件路径时,模型生成的参数被注入恶意负载。
- **SSRF/RFI**:工具访问外部资源时被诱导访问内部地址。
- **提权(Privilege Escalation)**:通过工具调用继承过高的权限。
工具层是 LLM 系统从"信息风险"转向"运营风险"的临界点。一个被注入的工具调用,可能直接删除生产数据库、对外发送垃圾邮件、执行任意代码。这是为什么我们在第 8 章把工具安全作为整本书的核心议题之一。
1.3.4 数据层(Data Layer):被遗忘的信任锚
数据层在传统威胁模型里通常被认为"内部、可靠",但在 LLM 系统里它是外部、不可信、半结构化的。RAG 语料、向量库、用户上传的文件、外部知识库——所有这些数据源都被不加区分地送进上下文窗口。
信任边界:任何从用户或第三方流入的数据都应该被视为不可信,必须经过内容审核、来源验证、隔离渲染。
典型攻击:
- **RAG 投