AI 安全导论:威胁全景与基础概念
第 1 章 AI 安全导论:威胁全景与基础概念
1.1 AI 安全的演进史:从学术研究到工程刚需
2023 年 3 月末,三星电子的半导体部门发生了一起震惊整个科技行业的安全事件。三名工程师在使用 ChatGPT 优化代码时,将包含晶圆缺陷检测算法源码、芯片测试设备配置文件、内部会议纪要等敏感信息的资料直接粘贴进了对话窗口。这些信息随后被 OpenAI 用于模型训练,导致三星的核心半导体技术细节以不可控的方式沉淀在公共模型的参数中。事件曝光后,三星紧急切断了与外部 LLM 服务的数据通道,并启动了一项价值超过 1 亿美元的数据安全审计工程。
这不是孤例。在 2023 年至 2024 年间,类似的"无意数据泄露"事件在投行、律所、医院、政府部门反复发生。2024 年初,加拿大航空的客服聊天机器人向一位乘客提供了错误的信息——它告诉乘客,因家庭紧急情况可以申请退款,并在 90 天内提交相关证明。但根据加拿大航空的官方政策,这类退款申请必须在 21 天内提交。当乘客依据机器人提供的"错误政策"完成申请并被拒后,他选择起诉。加拿大不列颠哥伦比亚省小额法庭最终裁定:航空公司对其提供的所有信息负责,无论信息来自人工客服还是自动化系统。航空公司被判赔偿 812.02 加元,外加利息。这起被称为"Air Canada v. Moffatt"的案件虽然金额不大,但它的判例意义远超案件本身:它明确宣告了企业在部署 LLM 时承担与传统信息系统同等的法律责任。
如果我们把视野拉远,会发现 LLM 安全并不是一个突然出现的新问题。早在 2016 年,微软就在 Tay 聊天机器人上线不到 24 小时内,被用户通过精心设计的对话"教坏"成了发表种族主义言论的工具。但当时这类系统的能力边界狭窄,攻击成本与潜在收益都不高,安全问题更多停留在学术圈的研究兴趣。2018 年,ACL、S&P、NDSS 等顶级会议开始出现针对 NLP 模型的对抗样本研究,2019 年 BERT 被提出后,针对预训练模型的攻击方法(如 HotFlip、TextFooler)成为研究热点。但这些论文的引用者主要是学术界,产业界的安全团队普遍认为"这跟我们公司的业务没什么关系"。
转折点出现在 2022 年 11 月 ChatGPT 发布之后。LLM 突然从研究原型变成了任何人可以通过浏览器调用的公共服务,调用成本几乎为零,输出质量却足以让普通用户误以为在与"真正的智能"对话。这种能力跃迁带来了三个根本性变化。
第一,信任边界的扩张。在传统软件中,用户输入是数据,系统输出是函数计算的结果。但 LLM 把"理解用户输入"和"生成系统输出"这两个环节全部变成了不可解释的神经网络推理。企业开始把客服、代码辅助、法律咨询、医疗分诊等高敏感业务直接交给 LLM 处理,原有的信任假设("代码逻辑是可控的、输出是确定的")一夜之间失效。
第二,攻击面的指数级扩大。传统 Web 应用的攻击面可以枚举——每一个 API 端点、每一个输入字段都是有限集合。LLM 应用则把攻击面变成了"自然语言空间",这个空间是连续的、无限的、并且与任务语义高度耦合。一个看似无害的问题,可能因为上下文中某个词的微妙变化,导致模型输出完全不同的结果。
第三,责任的转移与模糊。三星事件中,是工程师主动把数据贴进去的;Air Canada 事件中,是 LLM 自己"编造"了政策。这两类事件的责任划分在现有法律框架下都极其复杂。企业的安全团队发现,他们不再只是保护"代码和数据"——他们还要保护"模型行为"和"用户与模型的对话"。
到了 2024 年,Gartner、Forrester、IDC 等主流咨询机构在他们的 AI 风险调研报告中得出几乎一致的结论:超过 60% 的企业 AI 试点项目在生产部署阶段会遭遇至少一次重大安全事件,AI 安全已经从"加分项"变成了 CIO 和 CISO 必填的"必答题"。在 2024 年的 RSAC(RSA Conference)上,AI 安全被列为独立 Track,议题数量是 2023 年的 3 倍。一系列新的合规要求也相继出台:欧盟 AI Act 在 2024 年正式生效,其中第二章专门规定了通用 AI 系统的安全与透明度义务;美国 NIST 在 2024 年 1 月发布了 AI Risk Management Framework(AI RMF 1.0),并在 7 月发布了对抗性机器学习(AML)相关指南;中国信通院在 2024 年也密集发布了《生成式人工智能服务安全基本要求》等多项行业标准。
理解这条演进史对于后续章节的学习至关重要。它告诉我们:LLM 安全不是一个可以"用传统安全工具简单包装一下就能解决"的问题,它是一类新的工程范式——需要新的威胁模型、新的代码审查标准、新的测试方法、新的监控体系。本书的所有后续章节,都建立在这个基本判断之上。
1.2 LLM 与传统软件的安全差异:概率性、上下文边界、提示即代码
传统软件工程经过半个多世纪的发展,已经形成了一套相对成熟的安全范式:输入验证、输出编码、访问控制、加密传输、最小权限、纵深防御。这套范式隐含了一个根本假设——系统的行为是可预测的。给同一个输入,传统软件每次都会产生相同的输出;而对于异常输入,它要么正常处理,要么抛出明确的错误,要么崩溃——但绝不会出现"看起来正常运行,但内容是错误的"这种情况。
LLM 打破了这个假设。一个在 1000 次测试中都表现良好的 LLM 应用,可能在第 1001 次调用时突然输出有害内容。这种"概率性的安全失效"是工程师最不适应、也最难防御的威胁类型。我们需要从三个维度深入理解 LLM 与传统软件的安全差异。
第一,概率性输出导致的"语义级不确定性"。
传统软件的不确定性通常表现为"程序崩溃"或"返回错误码"——这是显式的、可观测的、可以被监控告警系统捕获的失效。LLM 的不确定性则表现为"输出在语法上完全合法、语义上却偏离预期"——这是隐式的、不可观测的、必须依赖人工或另一个 AI 系统才能发现的失效。
举一个具体的例子。假设你开发了一个基于 LLM 的 SQL 生成工具,输入是自然语言问题,输出是 SQL 查询语句。在传统编译器范式下,错误的 SQL 会导致数据库返回语法错误,应用程序会捕获异常。但 LLM 生成的 SQL 可能在语法上完全正确,却把 `WHERE salary > 50000` 错误地理解成了 `WHERE salary < 50000`,或者把"销量最高的产品"理解成了"销量最低的产品"。这种错误不会被任何传统异常捕获机制发现,却可能导致严重的业务决策失误。
更危险的是概率性失效的触发条件难以复现。在传统软件中,如果你能稳定复现一个 bug,你就能修复它。但在 LLM 应用中,你可能发现"今天早上 9:32 那次调用出错了",但当你用同样的输入再次调用时,模型又返回了正确的结果。这种非确定性使得安全测试、安全监控、事后审计都变得极其困难。
从工程实践的角度看,概率性输出要求我们采用多重防御策略:用确定性代码做最终边界(例如,SQL 必须经过严格的语法解析器和权限白名单校验)、用统计方法做异常检测(例如,监控输出的多样性、长度、关键实体出现的频率)、用人工抽样做持续审计。任何依赖单一防御层的方案都不可能稳定工作。
第二,上下文窗口的"不可信边界"问题。
传统软件系统中,数据的"信任级别"通常由其来源决定。来自数据库的查询结果是可信的,因为数据库在我们的信任域内;来自用户 HTTP 请求体的参数是不可信的,因为用户可能恶意构造。这种"信任域"的边界是清晰、可枚举、可强制执行的。
LLM 的上下文窗口打破了这种清晰性。一个 LLM 应用的提示(prompt)通常由以下几部分组成:系统提示(开发者定义的角色和规则)、用户输入(来自最终用户)、检索增强生成(RAG)从外部知识库检索到的内容、工具调用(function calling)的结果、记忆系统(memory)从历史对话中提取的上下文——所有这些内容在进入 LLM 之前会被拼接成一个连续的字符串,对模型来说,它们之间没有"信任级别"的差异。
这意味着,如果你用 RAG 增强 LLM 的回答能力,攻击者可以通过污染你的知识库(上传包含恶意指令的文档、在公开网站上发布诱导性内容)来影响 LLM 的输出。同样的逻辑适用于邮件摘要助手(恶意邮件正文包含隐藏指令)、网页抓取分析工具(目标网页包含针对 LLM 的提示注入)、客服机器人(前一个用户留下的对话片段被错误地拼接到下一个用户的上下文中)——所有这些场景中,攻击面通过数据流延伸到了看似安全的内部系统。
这种"上下文不可信边界"的工程后果是巨大的:传统的输入验证范式在 LLM 时代不再足够。我们不仅要验证"用户直接输入的内容是否安全",还要验证"任何可能进入 LLM 上下文窗口的内容是否安全"。这包括来自第三方的 RAG 文档、来自其他用户的对话历史、来自外部 API 的工具返回结果。一条数据进入上下文的每一条路径都需要被视为潜在的注入向量。
第三,提示即代码的悖论。
在传统软件工程中,代码和数据是严格分离的。代码由开发者编写、经过编译、部署到生产环境;数据由用户输入、经过严格的验证和清洗、进入运行时。代码拥有"对系统的完全控制权",而数据只拥有"被代码操作的权利"。这种分离是几乎所有安全机制的基础:沙箱、权限控制、类型系统都建立在"代码是受信任的、数据是不可信的"这一基本假设之上。
但 LLM 把"提示"(prompt)变成了既像代码又像数据的存在。系统提示中的指令在功能上等价于代码——它定义了 LLM 的行为边界、业务规则、输出格式。但系统提示通常以自然语言字符串的形式存在,通过 HTTP 请求体传输,没有编译期检查,没有类型系统约束,没有权限沙箱。任何能够修改提示的人——无论是开发者、运维人员、还是通过 RAG、用户输入间接影响上下文的攻击者——都能"修改程序逻辑"。
更糟糕的是,自然语言指令的"边界"是模糊的。传统代码中,`if (user_role == "admin")` 这样的判断是精确的;但在提示中,"请仅对管理员用户显示敏感信息"这种指令可以被无数种方式绕过——用隐喻、用其他语言、用反问、用假设场景。一项经典的研究(Stanford 2022)表明,主流 LLM 在面对精心设计的越狱提示时,拒绝率从 95% 下降到不足 20%。
提示即代码的工程后果是:传统的"代码审查"和"代码版本管理"在 LLM 时代获得了新的意义。提示字符串现在需要被当作代码来对待:纳入版本控制、经过同行评审、进行单元测试、记录变更历史。一些前沿团队甚至开始尝试为提示设计"类型系统"——例如使用结构化的指令模板、用强类型约束来限制模型输出的 schema。这些工程实践,我们会在后续章节详细展开。
下面这张图对比了传统应用与 LLM 应用在安全边界上的根本差异:
```mermaid flowchart TD subgraph TRAD["传统应用信任模型"] U1[用户输入 - 不可信] --> V1[输入验证] --> S1[受信任的业务逻辑] --> O1[受控输出] D1[数据库 - 可信] --> S1 end
subgraph LLM["LLM 应用信任模型"] U2[用户输入 - 不可信] --> P1[Prompt 拼接] R1[RAG 文档 - 不可信] --> P1 T1[工具调用结果 - 不可信] --> P1 P1 --> C1[上下文窗口 - 混合信任域] --> M1[LLM 推理] --> O2[概率性输出] end ```
这张图揭示了关键差异:传统应用的信任边界在"V1 输入验证"环节是清晰的,过了这关就进入受信任区域;LLM 应用的"信任融合"发生在 Prompt 拼接之后,所有不可信数据源在进入 LLM 之前已经混合在一起,传统的"输入验证边界"无法在 LLM 时代继续承担唯一防线的角色。
1.3 OWASP Top 10 for LLM Applications 框架解读
理解了 LLM 的特殊性之后,我们需要一个结构化的清单来指导威胁识别。OWASP(Open Web Application Security Project)在 2023 年发布了第一版 LLM Top 10,2024 年又迭代到了 1.1 版本。这份清单是当前业界最被广泛引用的 LLM 安全风险分类体系,可以作为我们后续所有安全实践的"共同语言"。
LLM01: Prompt Injection(提示注入)
提示注入是 LLM 应用的"SQL 注入"——它指的是攻击者通过精心构造的输入(直接注入或间接注入),覆盖或绕过原有的系统指令,使 LLM 执行非预期的行为。直接注入发生在用户输入直接拼接到提示中时;间接注入则发生在 RAG 文档、网页内容、邮件正文中包含恶意指令时。提示注入是 LLM 安全中影响面最广、危害最直接的一类问题,也是本书第 2、3、4 章的核心主题。
LLM02: Insecure Output Handling(不安全的输出处理)
LLM 输出的内容在语法上可能合法、在语义上却可能有害。如果应用直接拼接 LLM 的输出来执行 SQL、shell 命令、HTML 渲染,就会引入传统应用层的安全漏洞——SQL 注入、命令注入、XSS,但攻击向量从用户输入变成了"模型输出"。一个常见的设计错误是把 LLM 的输出直接传入 `eval()` 或 `os.system()`,这等于把"用户(通过 LLM)"升级为"系统执行者"。
LLM03: Training Data Poisoning(训练数据投毒)
这类攻击针对模型的训练阶段,攻击者通过污染预训练数据、微调数据、RLHF 反馈数据,使模型在特定触发条件下表现出恶意行为。例如,攻击者可能发布大量包含特定触发词的良性文本,当模型在这些数据上微调后,特定触发词会导致模型输出恶意内容。这类攻击的检测极其困难,因为恶意行为只在特定条件下才显现。
LLM04: Model Denial of Service(模型拒绝服务)
LLM 的推理成本远高于传统 Web 请求(一次 GPT-4 调用可能消耗数秒 GPU 时间和数十美分成本)。攻击者可以通过构造特别长或特别复杂的输入("context window flooding")、或者在提示中要求模型"无限循环生成内容"("token exhaustion attack"),使服务成本暴涨或响应时间失控。这类攻击在 2024 年已经被多个商业 LLM 服务记录在案。
LLM05: Supply Chain Vulnerabilities(供应链漏洞)
LLM 应用大量依赖第三方组件:预训练模型权重(来自 HuggingFace 等平台)、微调数据集、第三方插件、向量数据库、外部 API。攻击者可以发布包含后门的模型权重("backdoored checkpoints")、在公开数据集注入恶意样本、或者攻陷流行的 LLM 库。2024 年研究人员发现 HuggingFace 平台上有数十个包含恶意代码的模型权重,可以实现加载时自动执行任意命令。
LLM06: Sensitive Information Disclosure(敏感信息泄露)
LLM 可能通过三种途径泄露敏感信息:训练数据记忆(模型在训练中"记住"了用户的隐私数据并在后续输出中复现)、对话历史泄露(多用户系统中的会话隔离失败)、应用设计缺陷(开发者把内部 API key、公司机密信息硬编码到系统提示中)。三星事件就是这类问题的典型。
LLM07: Insecure Plugin Design(不安全的插件设计)
LLM 通过 function calling 调用外部工具时,工具本身的安全设计至关重要。如果插件缺乏适当的输入验证、没有最小权限控制、或者允许 LLM 链式调用(chain of tool calls)执行敏感操作,攻击者可以通过提示注入间接触发危险操作。2024 年出现的多起"通过 LLM 控制智能家居设备"事件都属于这一类。
LLM08: Excessive Agency(过度授权)
这类问题指的是 LLM 应用被授予了超出其实际需要的权限和能力。例如,一个客服机器人被授予了"删除用户账户"的权限,一个代码助手被授予了"执行任意 shell 命令"的权限。即使提示注入防御做得再好,一旦 LLM 被授予了过高的权限,单次成功的注入就可能造成灾难性后果。"最小权限原则"在 LLM 时代比任何时候都更重要。
LLM09: Overreliance(过度依赖)
这不是一个技术漏洞,而是一个社会工程问题。当人类用户过度信任 LLM 的输出时,会导致错误决策、有害内容传播、责任意识淡漠。Air Canada 案就是典型:用户和公司都把机器人当成了"权威信息源",而没有进行必要的二次验证。这类问题的防御不在代码层,而在组织流程层——建立"AI 输出必须经过人类复核"的工作规范。
LLM10: Model Theft(模型窃取)
攻击者通过 API 大量查询、模型蒸馏、参数提取等技术,复现目标模型的能力。商业 LLM 服务的核心资产是模型权重和微调能力,模型窃取直接威胁企业的竞争优势。2024 年的一项研究显示,仅通过 10 万次精心设计的 API 查询,就可以以 90% 的保真度复现一个中等规模开源模型的能力。
OWASP Top 10 的价值不在于"覆盖了所有风险",而在于"提供了共同语言"。在团队内部的安全评审中、在与外部审计的沟通中、在向管理层汇报 AI 安全风险时,使用统一的分类体系可以显著提升沟通效率。本书后续章节会反复引用这套分类体系,作为组织实践案例和设计防御方案的索引。
1.4 威胁建模基础:STRIDE 在 AI 场景的适配
有了 OWASP Top 10 作为"风险清单",我们还需要一个过程性方法来识别"具体业务场景中的具体风险"。这就是威胁建模(Threat Modeling)的价值。STRIDE 是微软在 1999 年提出的威胁分类方法,经过二十多年实践检验,被公认为最成熟、最易学的威胁建模框架之一。它的名字来自六类威胁的首字母缩写:Spoofing(伪装)、Tampering(篡改)、Repudiation(抵赖)、Information Disclosure(信息泄露)、Denial of Service(拒绝服务)、Elevation of Privilege(权限提升)。
STRIDE 在传统软件中应用得非常成熟。但当我们把它迁移到 LLM 场景时,需要做一些适配性改造。下面我们逐项分析 STRIDE