AI安全全景:威胁建模与风险评估框架 / AI Safety Landscape: Threat Modeling & Risk Assessment Framework
第 1 章:AI安全全景:威胁建模与风险评估框架
在部署任何 LLM 应用的工程团队会议室里,第一个被提出的问题几乎总是:"这个系统最可能被怎么攻击?" 而最危险的回答是"和普通 Web 应用差不多"。2023 年 ChatGPT 插件系统的间接提示注入(Indirect Prompt Injection)漏洞,2024 年 Microsoft 365 Copilot 的 EchoLeak 零点击数据外泄漏洞,以及 2024 年底 Anthropic、OpenAI、Google 几乎同时披露的"代理式越权"(Agentic Privilege Escalation)攻击链,无一不在用真金白银的生产事故提醒我们:LLM 应用的攻击面不是一个平面,而是一个由输入、上下文、推理、输出、工具、数据六层嵌套而成的立体结构。如果不能在这一立体结构上建立结构化的威胁建模方法,所谓的"AI 安全工程"就只是漏洞补丁的集合,无法形成纵深防御。
本章的核心问题只有一个:在系统工程视角下,如何对 LLM 应用进行结构化威胁建模与风险量化? 为了回答这个问题,本章将依次建立四块基石:STRIDE-AI(将传统威胁分类法扩展到 LLM)、MITRE ATLAS(对抗性技术知识库)、OWASP LLM Top 10(行业共识的 Top-N 风险清单)、CVSS-AI(针对 AI 的严重度评分模型),并在最后用两个真实案例把它们串成一个可执行的工程流程。读者在读完本章后,应当能够独立产出一份《AI 系统威胁清单》并把它纳入到企业的安全评审流程中。
---
1.1 传统网络安全与 AI 安全的边界:从确定性系统到概率性系统
1.1.1 为什么经典威胁模型在 LLM 场景中会失效
经典的网络安全威胁建模——无论是 STRIDE(Spoofing 伪造、Tampering 篡改、Repudiation 抵赖、Information Disclosure 信息泄露、Denial of Service 拒绝服务、Elevation of Privilege 权限提升)、PASTA(Process for Attack Simulation and Threat Analysis)还是 VAST(Visual, Agile, and Simple Threat)——其底层假设是系统的行为是确定性的:给定相同的输入,相同的代码路径、相同的鉴权检查、相同的输出。一个 SQL 注入要么成功要么失败,不存在"语义上等价但字符序列不同"的中间状态。
LLM 系统打破了这一假设。给定一个 prompt,模型以概率分布的方式产生 token 序列,这种行为具有三个对安全工程至关重要的特性:
1. 不可重现性(Non-determinism):即使将 `temperature` 设为 0,浮点累加、推理框架的并行策略、KV cache 的使用方式都会让两次推理的输出在字符级别上不完全一致。 2. 语义等价性(Semantic Equivalence):攻击者可以构造无数个在字符序列上完全不同、但在 embedding 空间中相邻的 prompt 来触发同一种不安全行为。这意味着"输入过滤"无法通过简单的黑名单完成。 3. 指令-数据混淆(Instruction-Data Confusion):在传统系统中,代码(指令)和数据是分开的,编译时就能区分;在 LLM 系统中,"指令"和"数据"都是自然语言 token,模型必须自己判断一段文本是应当被遵循还是仅仅被引用。这正是间接提示注入的根源。
这三个特性意味着,传统的边界防御模型——"在入口清洗恶意输入,在出口执行不可信输出"——在 LLM 应用中天然存在一个被攻击者利用的语义缝隙。这个缝隙不是某个厂商的工程缺陷,而是当前自回归 Transformer 架构的本质特征。
1.1.2 LLM 应用的攻击面地图:六层立体结构
为了在工程上把这种"立体缝隙"画出来,我们需要一张 LLM 攻击面地图。下图把一个典型的 LLM 应用拆成六层,每一层都对应一组特定的威胁。
```mermaid flowchart TB subgraph input["输入层 Input Layer"] I1[用户直接输入] I2[外部文档/网页] I3[多模态输入: 图像/音频] end
subgraph ctx["上下文层 Context Layer"] C1[系统提示 System Prompt] C2[会话历史 Chat History] C3[RAG 检索结果] C4[工具返回 Tool Output] end
subgraph infer["推理层 Inference Layer"] R1[基座模型 Base Model] R2[微调权重 LoRA / SFT] R3[对齐层 RLHF / DPO] R4[推理引擎 vLLM / TGI] end
subgraph out["输出层 Output Layer"] O1[自然语言回答] O2[结构化 JSON / 函数调用] O3[代码片段] O4[多模态输出] end
subgraph tool["工具层 Tool Layer"] T1[浏览器/搜索引擎] T2[代码执行沙箱] T3[数据库/CRM] T4[邮件/IM API] T5[MCP Server 集群] end
subgraph data["数据层 Data Layer"] D1[训练数据集] D2[向量数据库] D3[日志与可观测性] D4[模型权重/Checkpoint] end
I1 --> C1 I2 --> C1 I3 --> C1 C1 --> R1 C2 --> R1 C3 --> R1 C4 --> R1 R1 --> O1 R1 --> O2 R1 --> O3 R1 --> O4 O2 --> T1 O2 --> T2 O2 --> T3 O2 --> T4 O2 --> T5 T1 --> C4 T2 --> C4 T3 --> C4 T4 --> C4 T5 --> C4 D2 --> C3 D1 --> R2 R2 --> R3 R3 --> R4 R4 --> R1 R3 --> D3 O1 --> D3 ```
六层职责与典型威胁一览:
- **输入层(Input Layer)**:所有进入 LLM 的原始数据。除用户直接输入外,还包括 RAG 检索到的外部文档、邮件附件、网页爬取结果、用户上传的图像/音频。威胁:直接提示注入(Direct Prompt Injection)、多模态注入(Visual Prompt Injection)、语种切换攻击。
- **上下文层(Context Layer)**:在 prompt 真正送入模型前,运行时拼装出来的完整上下文,包括系统提示、会话历史、检索片段、工具返回值。威胁:间接提示注入(Indirect Prompt Injection)、上下文窗口污染(Context Window Poisoning)、角色扮演越权、Few-shot 后门。
- **推理层(Inference Layer)**:模型本身及其运行时的算子实现。威胁:权重中毒(Weight Poisoning)、后门触发(Backdoor Trigger)、推理侧信道(Inference Side Channel,如成员推断、模型反演)、解码器攻击、KV cache 泄露。
- **输出层(Output Layer)**:模型生成的 token 序列在被下游使用之前的形态。威胁:幻觉驱动的不安全指令、不安全代码生成、JSON 注入(当输出被解析器信任时)、Markdown/HTML 渲染型 XSS、版权内容复述。
- **工具层(Tool Layer)**:模型通过 Function Calling / MCP / Agent 框架触发的外部能力。威胁:工具误用(Tool Misuse)、代理式越权(Agentic Privilege Escalation)、命令注入、SSRF、凭据泄露、级联工具调用风暴。
- **数据层(Data Layer)**:支撑模型与应用的全部数据资产。威胁:训练数据提取(Training Data Extraction)、向量数据库投毒(RAG Poisoning)、日志泄露(Log Leakage)、Checkpoint 窃取。
这张地图的核心价值在于:它把 LLM 安全从一个"输入清洗"问题,重新定义为"六层全链路"的纵深问题。任何一层失守都可能导致整体失控,因此威胁建模必须逐层进行,而不是仅仅在入口处加一道 prompt 过滤器。
1.1.3 一个重要的工程观念转变:从"信任输入"到"信任边界"
传统应用开发的隐含假设是"输入是不可信的"。但在 LLM 应用中更精确的描述是:"任何进入上下文的字符串都应当被视为不可信的指令,除非该字符串的来源在数据流图上处于受信边界内"。
这一观念带来了三个直接的工程影响:
1. 来源标注(Provenance Tagging):每一次上下文拼接,都应当附带该片段的来源标签(`source: user | tool:web_search | doc:external_pdf`)。下游解析器、过滤器和模型调用方都可以依据来源标签决定信任级别。 2. 不可信片段隔离(Untrusted Quarantine):将不可信片段用结构化标记(例如 `<untrusted>...</untrusted>`)包裹,让模型"看到"它是数据而不是指令,是 OWASP 推荐的最佳实践之一。 3. 最弱环节原则(Weakest Link):整个系统的安全等级,由最不可信的那一层决定。这与 TLS 链路的信任模型同构,因此我们完全可以借用"信任根(Root of Trust)"的术语,把系统提示和受信的代码库作为 LLM 应用的信任根。
---
1.2 STRIDE-AI:将传统威胁建模方法扩展到 LLM 场景
1.2.1 经典 STRIDE 的回顾与局限
STRIDE 由 Praerit Garg 和 Loren Kohnhofe 在 1999 年提出,至今仍是微软 SDL(Security Development Lifecycle)的核心方法。它把威胁划分为六类,每一类都可以在数据流图(DFD)上落到具体的元素上:
| 类别 | 违反的属性 | 典型对象 | |---|---|---| | Spoofing 伪造 | 真实性 Authentication | 进程、用户、文件 | | Tampering 篡改 | 完整性 Integrity | 数据流、存储 | | Repudiation 抵赖 | 不可否认性 Non-repudiation | 日志 | | Information Disclosure 信息泄露 | 机密性 Confidentiality | 数据流、存储 | | Denial of Service 拒绝服务 | 可用性 Availability | 进程、通道 | | Elevation of Privilege 权限提升 | 授权 Authorization | 进程 |
STRIDE 在传统应用上的成功,来自于它能精准地把"攻击者要干什么"映射到"在数据流图的哪个元素上动手"。然而,当它被直接照搬到 LLM 应用时,会出现三类问题:
1. 缺失的类别:模型投毒(Model Poisoning)、训练数据反演(Training Data Inversion)、对齐规避(Alignment Bypass)在 STRIDE 原表中没有对应项。 2. 粒度失配:STRIDE 把"篡改"聚焦在数据流上,但 LLM 应用的最大威胁之一是"对模型行为的篡改",这种行为是通过修改 prompt 实现的,而 prompt 在 STRIDE 的原始定义中只是普通的"用户输入"。 3. 时间维度缺失:STRIDE 是静态建模,但 LLM 系统的安全状态会随会话长度(Context Length)、工具调用次数、累计成本而漂移。
1.2.2 STRIDE-AI 的扩展:七个新类别
针对 LLM 系统的特征,本书提出 STRIDE-AI 的扩展方案:在保留原六类的基础上,新增四类专属于 AI 系统的威胁,并对其中两类做语义重定义。
新增类别:
- **P - Prompt Manipulation 提示操纵**:所有以"让模型偏离开发者意图"为目标的输入工程行为。包括直接提示注入、间接提示注入、多模态注入、角色扮演、上下文窗口饱和、Token 走私(Smuggling)。
- **M - Model Tampering 模型篡改**:对模型权重、Tokenizer、对齐策略、解码超参的任何非授权修改。包括训练阶段的数据投毒、SFT/RLHF 阶段的恶意样本注入、推理阶段的 LoRA 热加载、KV cache 篡改、采样参数攻击(`temperature`、`top_p` 越权修改)。
- **A - Alignment Evasion 对齐规避**:在不直接修改模型的情况下,绕开安全对齐的技术。包括 Jailbreak Prompt、Crescendo Attack、Many-shot Jailbreak、加密/编码混淆、反向心理(Reverse Psychology)、多轮渐进式越狱。
- **X - eXtraction 提取**:从模型或其上下文中获取不应获取的信息。包括训练数据提取(Training Data Extraction)、系统提示泄露(System Prompt Leakage)、PII 提取、模型反演(Model Inversion)、成员推断(Membership Inference)。
语义重定义:
- **T - Tampering 篡改** 扩展为"对推理链中任何文本片段、向量嵌入、工具返回值的非授权修改"。这就把"上下文层污染"和"RAG 投毒"正式纳入。
- **I - Information Disclosure 信息泄露** 扩展为"任何让模型输出包含训练数据、PII、系统提示、用户上下文等敏感内容的路径",与原版的"被动读取数据"不同,新增了"主动诱导模型泄露"这一主动维度。
对其他类别的增强:
- **S - Spoofing 伪造**:在 LLM 时代,攻击者可以伪造一个"看起来像系统提示"的字符串诱导模型遵循,也可以伪造一个"看起来像工具返回值"的内容污染上下文。**信任根的伪造**成为新热点。
- **R - Repudiation 抵赖**:当模型调用工具时,传统的"谁点了那个按钮"日志无法回答"模型为什么做出这个决策"。这要求我们引入决策可追溯性(Decision Provenance)。
- **D - Denial of Service**:除了传统的资源耗尽,LLM 时代多了"上下文窗口耗尽"、"推理预算耗尽(Cost DoS)"、"工具调用循环(Agentic Loop DoS)"、"Token 配额 DoS"。
- **E - Elevation of Privilege**:从"越权访问系统资源"扩展为"模型触发了超出开发者意图的工具调用组合",对应 OWASP LLM08 过度代理(Excessive Agency)。
1.2.3 一张可立即使用的 STRIDE-AI 速查表
下表把 STRIDE-AI 的十个类别映射到 LLM 攻击面六层,并给出每类的"红队问题"。在企业内进行威胁建模评审时,评审人可以把这些问题当作检查项。
| 类别 | 输入层 | 上下文层 | 推理层 | 输出层 | 工具层 | 数据层 | |---|---|---|---|---|---|---| | S 伪造 | 来源伪造? | 工具返回值伪造? | — | — | MCP Server 身份伪造? | Checkpoint 来源伪造? | | T 篡改 | 输入清洗绕过? | RAG 投毒? | 权重篡改? | 输出结构被解析器信任? | 工具参数注入? | 向量库写入越权? | | R 抵赖 | — | — | 决策链可追溯? | 输出可归因? | 工具调用可审计? | 训练数据可追溯? | | I 泄露 | — | 历史泄露? | 侧信道? | 训练数据复述? | 凭据泄露? | PII 提取? | | D 拒绝服务 | 超长 prompt? | 上下文耗尽? | 算力耗尽? | — | 工具风暴? | 检索慢查询? | | E 越权 | — | — | — | 触发未授权工具? | 代理式越权? | — | | P 提示操纵 | 直接注入? | 间接注入? | 解码参数攻击? | 诱导不安全输出? | 工具 prompt 注入? | 检索结果投毒? | | M 模型篡改 | — | Few-shot 后门? | 数据投毒 / 权重后门? | — | — | Checkpoint 替换? | | A 对齐规避 | Jailbreak? | 多轮越狱? | — | 不安全内容输出? | — | — | | X 提取 | — | 系统提示泄露? | 模型反演? | 训练数据复述? | 工具返回值反推? | 成员推断? |
使用方法:在画完 LLM 应用的 DFD 之后,针对每一个元素(进程、数据流、数据存储、信任边界),把上表中对应的那一列当作"提问清单"逐条问一遍。所有问出"是"或"不清楚"的项都应当被记录为潜在威胁。
1.2.4 一个最小化案例:单轮客服 LLM 的 STRIDE-AI 建模
为了让读者把握 STRIDE-AI 的实际产出,我们以一个"基于内部知识库的客服 LLM"为例做一次 30 分钟的快速建模。
场景:用户在前端输入问题,LLM 检索公司内部 Confluence,返回自然语言答案。不调用其他工具,不持久化会话。
**DFD