第 3 章 数据保护与权限

学习目标

  • 找出从输入到日志的整个数据生命周期中,敏感信息可能在什么位置泄露,并将泄露降到最低。
  • 从功能、权限和自主性三个方面分别诊断过度代理,并通过工具设计缩小权限。
  • 确定智能体究竟以谁的权限执行操作,并将委托token及其作用域缩减到必要的最小程度。
  • 将模型输出当作不受信任的输入,根据输出的目的地,进行安全的渲染和处理。
  • 纠正关于系统提示词与向量库的常见误解。

引言

某购物网站的客服聊天机器人,为了准确回答问题,使用了一个能够查询客户整个账号的工具。仅仅一次配送咨询,就会使完整地址、电话号码、最近十笔订单,以及积分记录全部进入上下文。大多数日子里,都没有发生问题。后来,一位客户使用与家人共用的账号询问:“请把上个月的全部订单显示出来。”聊天机器人便热心地将其他家庭成员的订单也一并展示了。模型并没有犯错,它只是认真整理了收到的数据。团队急忙在提示词中加入“不要透露其他人的信息”这句话,但对于共用同一账号的几个家庭成员,模型根本无从知道究竟是谁正在提问。解决办法不在提示词中,而在查询工具中。

如果说第2章讨论的是“攻击者的指令如何进入”,那么本章讨论的就是“指令进入之后,最多能够做什么”。模型能够说出已经进入上下文的内容,也能够使用手中的工具,完成这些工具所允许的操作。因此,减少数据与权限,就是注入防御的一半。本章从敏感信息的流转路径与最小化讲起,依次介绍外部AI服务的数据条件、系统提示词与向量库、过度代理与工具权限设计,以及委托与身份。最后,学习如何安全地渲染和处理模型输出。

核心概念

敏感信息从哪里泄露:数据生命周期

OWASP LLM02(Sensitive Information Disclosure)讨论个人信息、金融信息、健康记录、机密业务数据、凭据和法律文档通过模型输出暴露的风险,也指出用户输入的数据可能在后续模型输出中再次出现。仅看最终回答会遗漏许多位置,因此需要追踪整个生命周期。

阶段 泄露表现 基本控制
输入收集 用户直接输入韩国居民登记号码或密码 输入提示、模式检测与脱敏
上下文组装 加入过多记录与字段 字段级查询工具
外部模型调用 向外部供应商发送原文 脱敏、假名化、核查合同条件
工具参数 模型将敏感值传给其他工具 参数验证、目的地限制
输出 暴露其他用户或家庭成员的信息 服务端授权、输出检查
日志与缓存 原始对话留存在日志和缓存 日志脱敏、保留期限(第5章)
派生数据 残留在摘要、嵌入、微调数据中 训练前清理、派生物删除流程

OWASP警告,通过系统提示词限制“不要返回这些数据”虽有帮助,却不总能被遵守,也可能被注入绕过。最可靠的保护,是从一开始就不让模型看到数据。

最小化、脱敏、假名化

数据最小化的原则是:“只在需要的时刻,传递业务所必需的字段。”对于配送咨询,需要的是配送状态与预计送达日期,而不是完整地址。这项原则要通过工具设计来实现,不能靠提示词实现。应当创建只返回“这一笔订单的配送状态”的工具,取代返回整条客户记录的工具。韩国《个人信息安全保障措施标准》同样要求,在输出个人信息时明确用途,再根据用途将输出项目缩减到最少。向LLM上下文传递数据时,也可以按照同样的精神来设计。

确需传递的值应进行掩码处理。

方法 做什么 使用场景
脱敏(redaction) 删除值或替换为星号 日志、模型无需知道具体值时
令牌化 将值换成无意义的替代字符串,映射表另行保存 模型只需知道是“同一个人”时
假名化 使信息在没有附加信息时无法识别特定个人 分析、准备微调数据

使用令牌化后,映射表就成为了新的核心资产。不能把映射表放在与模型相同的存储中,而应加密保存,对访问单独实施控制并留下记录。数据在对外发送之前就要完成替换;收到响应之后,也只在确实需要的位置,才将替代值还原为原始值。

发送给外部AI服务的数据条件

使用外部供应商的模型,意味着数据会越过组织的边界。需要核查的问题包括:数据是否用于训练;为监测滥用会保留多长时间;应用状态(对话、文件、向量库)会留存到何时;减少留存的选项,必须满足什么条件才能使用;以及数据存放在哪一个地区。

以OpenAI的数据控制文档为例,具体情况如下。除非用户明确同意,否则通过API发送的数据不会用于模型训练。滥用监测日志最多保留30天,但如果法律要求,或为保护服务和第三方免受损害而确有必要,也可能保留更长时间。用于减少数据留存的Zero Data Retention与Modified Abuse Monitoring,都必须事先获得批准才能使用。部分功能会一直保存应用状态,直到用户主动删除。各项条件因功能与合同而异,因此应按功能逐项核查官方文档和合同,并记录核查日期。如果向境外供应商发送个人信息,还要与个人信息保护负责人共同核查韩国《个人信息保护法》第28条之8规定的境外传输条件,即单独同意,或者法律规定的例外情形。

系统提示词不是秘密

OWASP LLM07的核心是“不得将系统提示词视为机密或用作安全控制”。同一文档解释,真正的风险并非提示词文字本身暴露,而是其中存放的敏感信息与权限结构。

不应放入提示词的内容 暴露后的后果 应放的位置
API密钥、数据库连接信息 直接访问其他系统 机密存储、服务器配置
交易限额、审批规则 拆分为略低于限额的请求 服务端策略引擎
过滤标准 寻找规避过滤的表达 独立护栏
用户角色与权限结构 尝试权限提升 授权系统

权限分离与授权检查应在模型外,以确定且可审计的方式执行。访问级别不同的任务,应分给多个具有最小权限的智能体。目标是“即使整个提示词公开,也不会发生问题”。OWASP 2026年版将此条目扩展为隐藏上下文暴露(LLM08:2026 Hidden Context Exposure),把开发者指令、检索加入的政策文字、工具schema也纳入同一原则。

RAG与向量库的权限

OWASP LLM08(Vector and Embedding Weaknesses)列出了向量库的几类风险:访问控制失效与数据泄露;多个用户群体共享同一个存储时发生的跨上下文泄露;通过嵌入反演恢复相当一部分原文;以及索引数据受到污染。缓解措施包括采用能够识别权限的向量库并严格划分数据,验证知识来源,审查并分类组合的数据,以及为检索活动保存无法更改的日志。

设计原则是:“在生成之前,就在检索阶段落实权限。”让模型先读到无权访问的文档,然后再指示它“不要透露这份文档”,就是错误地把提示词当作控制。应当在检索查询本身附加请求者的权限条件,通过预过滤,从一开始就只返回获准访问的文档片段。如果文档的权限发生变化,或者文档被删除,索引中的片段与缓存也必须同步更新。原文已经删除,却仍然留在索引中不断被检索到,这种情况很常见。对嵌入也应视同原文,按同样敏感的数据进行处理。它只是一个数字数组这一事实,并不能起到保护作用。

过度代理:三个根源与八项预防措施

OWASP LLM06(Excessive Agency)指的是这样一种漏洞:系统在应对非预期、含糊不清,或者受到操纵的模型输出时,能够执行有害行动。无论原因是幻觉还是注入,关键都在于:模型判断出错后,究竟可能进一步发生什么。它有三个根源。

根源 示例 修正方法
功能过多 文档读取工具还带修改、删除功能,测试后遗留工具 只保留所需功能的工具,移除不用的工具
权限过大 只需读取却有写权限,使用能访问全部用户数据的高权限共享账号 只读权限、在用户上下文中执行
自主性过高 高影响行动未经独立验证或用户确认就执行 用户批准

2025年版提出八项预防措施:减少扩展功能(工具)数量、缩减单个工具功能、避免通用工具、缩小工具权限、在用户上下文中执行、取得用户批准、完全仲裁、清理输入输出。2026年版(LLM03:2026)移除了输入输出清理,整理为七项。日志、监控及请求速率限制另被列为减小损害规模的手段,因为它们无法预防过度代理本身。

完全仲裁(complete mediation)原则是“每次请求是否被允许,都必须由下游系统判定,而非由模型决定”。就像门禁检查应由门禁设备执行,而非依靠接待员记忆。模型或许无法伪造门禁卡,却可能说服接待员。

将工具权限最小化落实到设计

工具权限最小化不能只停留在原则,应体现在工具规格中。OWASP AI Agent Security Cheat Sheet建议按工具区分读写及目标资源设置权限,为不同信任级别的智能体提供不同工具集;遇到未知工具或审批要求缺失时,应采用故障关闭(fail closed)。

设计手段 示例
查询与修改分离 将get_order_status与request_refund设为独立工具
用专用工具代替开放工具 用run_test_suite代替通用shell,用允许域名搜索代替任意URL抓取
参数约束 schema中设置枚举、范围、格式,服务器再次验证
目标限制 收件人允许列表、金额上限、每日调用次数
短期凭据 按任务签发,结束即撤销
默认拒绝 不执行列表以外的工具、参数、目标
{
  "name": "reschedule_my_booking",
  "description": "修改已登录用户本人的一笔预约日期。执行前须经用户确认。",
  "input_schema": {
    "type": "object",
    "properties": {
      "booking_id": { "type": "string", "pattern": "^BK-[0-9]{8}$" },
      "new_date": { "type": "string", "format": "date" }
    },
    "required": ["booking_id", "new_date"],
    "additionalProperties": false
  }
}

schema帮助模型避免生成形式错误的参数,真正的控制在服务器。服务器应逐次重新检查:此预约是否属于已登录用户,新日期是否在允许范围内,以及用户是否已确认。

委托与身份:以谁的权限执行

智能体代用户调用其他系统时,必须明确“以谁的权限”。若所有调用都使用高权限共享服务账号,欺骗模型的用户就能触达该账号能访问的全部数据,日志中也没有实际请求者。OWASP Agentic Top 10指出,智能体若没有受管理的自身身份,就无法真正强制执行最小权限,并将其列为ASI03(Identity and Privilege Abuse)的原因。OWASP LLM06建议,代用户采取行动时,应在该用户的上下文中以最小权限执行,例如使用最小必要作用域的OAuth认证。MCP安全最佳实践具体指出委托结构中的陷阱。

陷阱 MCP文档的要求
token透传(token passthrough) 检查收到token的受众(audience)是否为此MCP服务器,拒绝为其他对象签发的token。授权规范明确禁止该模式
混淆代理人(confused deputy,有权限的中介被骗为他人使用权限) 中转第三方API的MCP代理服务器必须实现逐客户端同意
状态句柄劫持 不得把持有状态句柄当作认证,服务器须将句柄绑定到已认证用户
过宽作用域 从最小作用域开始,必要时逐步提升,避免通配符或综合作用域

token透传会使下游API的请求速率限制与审计记录失效,窃取token的人还可以把中转服务器用作数据泄露的通道。如果一开始就申请了过宽的作用域,那么一个token泄露的瞬间,所有工具就都会开放。

输出是不可信输入

OWASP LLM05(Improper Output Handling)指的是在将模型输出交给下游组件前,没有验证、清理和处理的缺陷。提示词可操纵输出,因此直接使用输出,就等于给用户提供了下游功能的间接访问。OWASP建议采取零信任方式,把模型视为“另一个用户”。

输出目的地 风险 基本控制
浏览器(HTML、Markdown) XSS、通过外部请求外传数据 按上下文编码、净化、CSP
数据库 SQL注入 参数化查询
shell、eval、模板引擎 远程代码执行 不执行;不可避免时使用沙箱
文件路径 路径操纵 规范化、允许目录
邮件模板 钓鱼 转义
导出到电子表格的CSV 公式执行 处理单元格,避免以公式字符开头

当模型权限高于用户、容易受间接注入影响、或输出未按上下文编码时,影响会更大。模型虚构软件包名,导致安装攻击者上传的同名恶意软件包,这类风险OWASP也在本条目及LLM09中讨论。

安全渲染输出

将模型输出绘制到界面,应遵循与渲染用户输入相同的规则。把OWASP XSS Prevention Cheat Sheet的原则应用到LLM输出,可得到以下做法。

  1. 默认按文本渲染,使用textContent等仅将数据当文本处理的方式,代替innerHTML。
  2. 确实需要格式时,在Markdown渲染器中禁用原始HTML,并采用基于允许列表的净化工具过滤输出。OWASP推荐使用DOMPurify净化HTML。
  3. 框架绕过转义的功能(如React的dangerouslySetInnerHTML)不得在未净化时使用。
  4. 用允许列表限制链接和图片。不自动加载外部图片,就能阻止利用图片地址夹带数据的外传通道。检查链接协议(如javascript:)和域名,必要时在点击前展示实际地址。
  5. CSP(Content Security Policy)是附加防御层。OWASP指出,不应把CSP作为主要防御手段。
  6. 流式输出会在片段尚未收齐时渲染,因此要确认未经净化的中间结果不会被绘制到界面。
<!-- 错误示例:将模型输出直接解释为HTML -->
<div id="answer"></div>
<script>answer.innerHTML = modelOutput;</script>

<!-- 较好示例:按文本渲染;格式内容仅使用净化后的结果 -->
<script>answer.textContent = modelOutput;</script>

模型选择的地址与代码:SSRF与代码执行

服务器如果根据模型生成的值发送请求,或者执行代码,输出处理的风险就会进入服务器内部。如果服务器直接获取模型选定的URL,注入就可能将这个URL改成内部管理页面,或者云服务的元数据地址。这就是服务端请求伪造(SSRF,Server-Side Request Forgery)。MCP安全最佳实践对于获取OAuth相关URL的客户端提出以下建议:在生产环境中要求使用HTTPS;阻止私有、环回和链路本地地址段;对重定向目标采用相同标准进行检查;并使用能够阻止内部目的地的出站代理。它还提醒,不要自行实现IP校验,因为这样很容易遗漏编码方面的绕过手法。这些原则原样适用于所有由模型选择URL的工具。

如果没有充分验证并做好隔离,就执行模型生成的代码或命令,将会带来OWASP Agentic Top 10中ASI05(Unexpected Code Execution)的风险。基本原则是:“如果可以不执行,就不要执行。”如果必须执行,则应在权限最小的专用容器或虚拟机中运行,限制网络与文件访问,并且不携带机密值。Anthropic的计算机使用工具文档,同样将权限最小的专用虚拟机或容器、域名允许列表,以及对登录信息等敏感数据的隔离,列为预防措施。

深入阅读

绑定批准与执行

即使设置了人工确认,只要“用户看到的内容”与“实际执行的内容”不同,确认就失去了意义。例如,审批界面上写的是“修改会议日程”,而实际调用的参数中,却可能额外加入了十位参会者。又或者,在一个长时间任务的执行途中,用户的权限已经被撤销,但系统仍然凭任务开始时得到的批准,一直执行到底。这就是检查时点与使用时点不一致的问题(TOCTOU,Time-of-Check to Time-of-Use)。

与执行绑定的批准,需要具备以下条件。审批请求要以原始值展示操作对象、参数和预期效果。批准记录要与这些参数的哈希一同保存,在执行前的最后一刻比较参数是否仍然相同;只要不同,就重新询问。批准还应有有效时限,并且只能使用一次。此外,在实际执行前,必须重新核查用户当前拥有的权限。OWASP AI Agent Security Cheat Sheet建议的“执行前行动预览”与“撤销”,也应与这套设计结合使用。

派生数据隔离:缓存、记忆、摘要、导出

即使原始存储的权限控制完全正确,数据也可能在派生路径中混在一起。如果响应缓存的键没有包含用户或组织标识,另一个组织提出相似问题时,就会收到前一个组织的回答。如果多个团队复用一份公共摘要,已经融入摘要中的机密,就会流向没有相应权限的团队。对话导出与分享链接,也经常不经过原始对话的权限检查。

检查时只需围绕一个问题:“这个派生物是否继承了原始数据的权限边界?”对于缓存键、记忆存储、摘要存储、导出文件和嵌入索引,都要分别回答这个问题。凡是答案为“否”的地方,就要加上用户或组织的范围限制,或者禁止复用。OWASP AI Agent Security Cheat Sheet也将用户之间与会话之间的记忆隔离,作为单独一项列出。

工作场景

本然医院:为何移除预约智能体访问诊疗记录的权限

综合医院“本然医院”准备引入诊疗预约智能体。在初步设计中,智能体使用的服务账号,对全院患者数据库拥有读写权限。为了提高回答质量,系统还会把患者近期的全部诊疗记录放入上下文,并让智能体直接执行预约变更。应用界面将智能体写出的说明以HTML呈现,而系统提示词中则包含内部预约API的地址与密钥。

安全审查者按照三个根源逐项诊断。在功能方面,他先问:“处理预约是否需要查询诊疗记录?”得到的回答是,真正需要的只有可预约时段,以及患者本人的预约列表。因此,诊疗记录查询工具被移除了。在权限方面,写入权限被收窄到预约表,调用则改用已登录患者本人的token。预约服务器会在每一次请求中,直接检查“这名患者能否修改这笔预约”。在自主性方面,取消预约或改到其他诊疗科室,必须由患者在界面上确认日期、科室和医护人员之后,才允许执行。

团队还检查了输出与机密值。说明按文本呈现,并经过只允许粗体和列表的净化器处理;链接与图片则仅允许来自医院域名。原来放在系统提示词中的API地址与密钥,分别迁移到了服务器配置和机密存储中。已经通过提示词暴露的密钥,则予以撤销并重新签发。

面对“有诊疗记录才能更好地推荐医生”的反对意见,团队用一个只返回科室与主治医生两个字段的工具解决了需求。最终,即使智能体受到欺骗,它所能做的也被缩减为“展示患者本人的预约,并在取得确认后修改”。风险登记册中记下的残余风险是:“患者在确认界面没有阅读内容便批准。”另外,团队将“取消后24小时内可以撤销”的功能,列为下一季度的任务。

鲸鱼集市:同一句话在三处有不同风险

二手交易平台“鲸鱼集市”开发了一项功能:卖家上传照片并填写简短备注后,模型就为商品撰写出售帖的标题与说明。模型生成的说明会流向三个地方:在公开出售帖页面上,以Markdown渲染;在运营团队的审核界面上显示;以及每周导出为运营报告用的CSV,并在电子表格中打开。

Beta测试期间发现了两件事。一位卖家在备注中放入了一段HTML,模型将它原样搬进了说明,导致审核界面中的格式出现混乱,脚本标签也原样混在页面内容里。幸好审核界面按文本渲染,因此这些内容并未被执行。此外,部分说明中还出现了外部付款网站的链接,是卖家通过备注诱导模型加入的。运营团队于是提议:“给模型下指令,让它不要写HTML和链接。”

安全负责人只把这条指令作为辅助手段接受,同时针对每一个目的地分别设置控制。公开页面先经过禁用原始HTML的Markdown渲染器,再经过基于允许列表的净化器;链接只保留平台域名,图片也只显示上传到平台的照片。审核界面继续按文本渲染,并将卖家的原始备注与模型生成的说明并排展示。导出CSV时,在以公式字符开头的单元格之前,加上单引号或制表符,使其被解释为文本。OWASP提醒,不同电子表格程序的行为不同,不存在通用的净化方法,因此团队使用运营人员实际使用的程序,测试了导出结果。

这里的教训是:“即使是相同的输出,到达不同的目的地,风险与控制也各不相同。”如果只依赖给模型的一句指令,那么指令被忽略的那一天,这三个位置就会同时暴露于风险之中。

易错点

  1. “在提示词里写下禁止规则,就实现了权限控制。” 遵守规则的主体仍然是模型。是否允许某项操作,应由下游系统在每一次请求中作出判断。
  2. “这是自家模型生成的输出,可以信任。” 输出会反映模型读取过的外部内容与用户输入。在渲染和执行之前,应像对待用户输入一样,处理这些输出。
  3. “用户看不到,所以可以把密钥放在系统提示词里。” 看不见,并不是保护手段。密钥应当放在模型无法直接接触的位置。
  4. “为了提高准确性,放入的数据越多越好。” 放入多少数据,就会增加相应的暴露面。应创建只返回所需字段的工具。
  5. “嵌入是数字,所以安全。” 通过嵌入反演,可能恢复相当一部分原文。应当按照与原文相同的保护级别,对访问实施控制。
  6. “已经加了日志与请求速率限制,过度代理就解决了。” OWASP将这两者归为减小损害的手段。预防过度代理,需要从缩减功能、权限和自主性入手。
  7. “通过了schema验证,就是安全的参数。” 即使格式正确,操作对象和金额也可能有误。服务器必须重新核查业务规则,并在每一次请求中,再次确认对该具体对象的访问权限(OWASP Authorization Cheat Sheet)。
  8. “已经有CSP,可以省略输出编码。” CSP只是额外的防御层。应先按照上下文做好编码与净化。

要点速览

主题 要记住的话
敏感信息 模型能说出所见;不让它看到最可靠
最小化 使用字段级工具,对外传输前脱敏
外部供应商 按功能确认训练用途、保留期限、状态留存、审批条件
系统提示词 不是秘密,也不是控制
RAG 检索时落实权限,删除与权限变更同步至索引
过度代理 功能、权限、自主性,以及完全仲裁
工具设计 查询与修改分离、专用工具、参数约束、默认拒绝
委托 用户上下文、最小作用域、禁止token透传
输出处理 把模型当不可信用户,按目的地实施控制
渲染 文本优先、净化、链接与图片允许列表,CSP为辅助
SSRF与代码执行 验证模型选择的地址,代码仅在隔离环境执行

查阅官方文档

自测

3-1. 除最终回答外,举出三个可能残留或泄露敏感信息的生命周期位置,并各写一项基本控制。

3-2. OWASP LLM06将哪两项与预防措施区分,列为“减小损害规模的手段”?为什么它们不属于预防措施?

3-3. 用一句话定义完全仲裁原则,并举出一个违反该原则的设计。

3-4. 审查外部LLM API供应商的数据条件时,应按功能确认哪四项内容?

3-5. 分别用一句话说明:模型输出渲染到网页的默认方式、必须使用带格式HTML时的方式,以及CSP与二者的关系。

3-6. MCP安全最佳实践对状态句柄禁止了什么?服务器应改为做什么?

3-7. 设计题:某内部助手读取员工日程并预订会议室。请为它设计不超过三个工具,并逐一用一行说明功能、权限及是否需要用户确认。

实操练习

练习

编写工具权限收缩方案(40分钟)

  1. 列出智能体或聊天机器人使用的全部工具,按工具将功能、权限、自主性(是否未经确认执行)和执行身份(共享账号还是用户上下文)填入表格。
  2. 在旁边一列写出实际业务所需的最少功能和权限。
  3. 对存在差距的单元格,从“替换为专用工具”“查询与修改分离”“只读”“用户上下文执行”“参数与目标限制”“人工批准”中选择缩减方式。
  4. 检查系统提示词是否含机密值、限额、权限结构,列出清单并写明迁移位置。

完成标准: 至少一个工具的功能或权限得到实际缩减,并制定从提示词中彻底移除机密值的计划。

练习

制作模型输出目的地检查表(35分钟)

  1. 列出模型输出的全部目的地(网页、管理界面、邮件、DB、文件、导出、其他工具参数)。
  2. 对每个目的地写出“输出可能被解释为什么”(HTML、SQL、shell、路径、公式、URL)。
  3. 比较现有控制与本章基本控制,标出各目的地缺失的控制。
  4. 针对最危险的一个目的地,假定模型产生危险输出,用虚构数据设计一个测试输入并写出预期结果。

完成标准: 至少整理三个目的地,每个目的地都写有至少一项不依赖模型指令而工作的控制。