跳到主要内容

每个开放 RAG 系统自带的攻击向量

· 阅读需 11 分钟
Tian Pan
Software Engineer

五份精心设计的文档。260 万条记录的语料库。操纵特定 AI 响应的成功率高达 97%。这是来自 PoisonedRAG 的基准测试结果,该研究发表于 USENIX Security 2025 —— 而且这种攻击不需要模型访问权限,不需要在推理阶段进行提示词注入,甚至不需要与系统进行任何直接交互。攻击者只需向知识库贡献内容即可。

如果你的 RAG 系统允许用户添加内容 —— 服务台工单、Wiki 编辑、客户反馈、共享笔记 —— 那么你已经发布了攻击载体。问题在于你是否也同步发布了防御机制。

RAG 的检索信任问题

RAG 系统的工作原理是检索知识库中的相关文档,并将其作为上下文注入到 LLM 的提示词中。这种机制本身就是漏洞所在。被检索到的文档会被模型视为权威信息 —— 它们存在于上下文窗口中,而不是用户对话轮次(user turn)中,这使得它们在 LLM 衡量权重时处于更高的信任地位。

传统的软件漏洞会留下痕迹:错误代码、堆栈跟踪、异常延迟。而受污染的 RAG 上下文则完全不留痕迹。模型响应正常。流水线运行无误。虽然质量已经发生偏移,但只有当你将其与历史基准进行对比或观察特定的查询集群时,这种偏移才会变得可见。这就是为什么 RAG 投毒在生产环境中尤为危险:直到用户开始注意到错误的答案,或者有人故意揭露攻击,你才会意识到自己遭到了攻击。

这种威胁并非仅停留在理论层面。2024 年 8 月的一个 Slack AI 漏洞利用案例表明,在可访问频道中发布的投毒消息可以影响 Copilot 的行为,并实现未经授权的文档访问。同年发现的一个 ChatGPT 记忆攻击显示,攻击者通过 RAG 上下文将持久性指令注入长期记忆中 —— 这些指令在跨会话对话中依然有效。这些案例的底层机制完全一致:系统检索并信任了这些内容。

投毒如何隐藏在众目睽睽之下

RAG 投毒之所以能逃避检测,是因为其结构特性:投毒内容经过精心设计,看起来完全合法。

基于文本的攻击在保留正常语义的同时嵌入隐藏指令。“忽略之前的指令”对人类审查员来说可能像胡言乱语,但大多数技术文档对非专家来说同样晦涩。在大规模环境下,人工审查是不可行的。如果你的语料库有一百万份文档,从中寻找五份精心隐藏的投毒文本在计算和实践上都是不可能完成的任务。

基于嵌入(Embedding)的攻击更难被察觉。对抗性嵌入被设计为在相似度搜索中获得极高评分 —— 它们看起来与那些与其恶意内容毫无关系的查询高度匹配。检索排名与语义连贯性之间的脱钩在文本层面上是不可见的。一份在“退款政策”查询中排名第一的文档可能包含批准所有退款请求(无论是否符合条件)的指令。文本看起来像政策文档,但嵌入向量已针对这些查询进行了优化以确保其被召回。

休眠攻击模式让情况变得更糟。单个投毒文档在正常查询期间可以保持静默,仅在特定触发关键词出现时才激活。这意味着你的标准评估流水线(通常只测试常见查询)不会显示任何性能下降。攻击通过针对长尾(long tail)查询绕过了你的测试覆盖范围。

并非所有贡献者都是平等的:信任层级

最重要的概念转变是将贡献者身份视为知识库的一等安全属性(first-class security attribute)。

大多数 RAG 系统采用的是隐含的扁平信任模型:内容一旦被摄取,无论来源何处,都会被同等对待。对于经过审查的内部文档构成的封闭语料库,这没有问题。但当用户可以直接贡献内容时,这就是一个严重的漏洞。

一个有效的来源信任层级至少应区分三个等级:

内部/经验证的来源 —— 由授权员工创建的内容、从官方系统导入的内容、摄取前经过审查的内容。这些内容获得完全信任,可以直接检索而无需额外安全防护。

外部用户贡献 —— 服务台工单、Wiki 编辑、客户反馈、共享笔记。这些内容在进入检索索引之前应排队等待验证。不一定对每个条目都进行人工审查,但需要经过自动化网关处理并存放在暂存区。

第三方抓取内容 —— 网页、外部 API、合作伙伴数据。即使域名看起来合法,也要将这些内容视为不可信。2024 年的研究发现,在随机抽样的电子商务网站中,有 13% 包含适合 RAG 投毒攻击的内容 —— 攻击者发布恶意评论,因为他们知道 RAG 流水线会抓取这些信息。

贡献者的信誉随时间累积。一个提交过数百个合法工单的用户与一个新创建的账号应具有不同的风险评分。一个入职三年的认证内部员工与一个通过 API 密钥访问的供应商合作伙伴应受到不同的对待。跟踪这些元数据,将其与每份文档关联存储,并在检索阶段加以利用。

真正有效的三个防御层

针对 RAG 投毒的防御需要在流水线的三个不同点进行控制 —— 漏掉其中任何一个都会产生其他环节无法覆盖的漏洞。

摄入层:在文档进入索引之前进行验证。

最早的干预点也是最有效的。在任何用户贡献的内容进入你的向量数据库之前,先通过验证闸门:扫描已知的提示词注入(prompt injection)模式(如 “忽略之前的指令”、“新的系统提示词”、“扮演...”),检查异常的指令密度,并验证文档结构是否符合其内容类型的预期。帮助台工单不应包含带有 Shell 命令的 Markdown 代码块。

高风险内容不会直接被拒绝 —— 而是被隔离。将被标记的文档移至审核队列,在那里授权审核员仍然可以搜索到它们,但在清除风险之前,它们将被排除在生产检索之外。这在不悄无声息地丢弃潜在合法内容的情况下,保留了审计追踪。

检索层:监控分布异常,强制执行权限。

即使有了摄入层控制,一些投毒内容仍可能混入。检索层防御增加了第二道关卡。

监控检索器的评分分布。对抗性嵌入(adversarial embeddings)往往以一种不自然的锐度在检索中占据主导地位 —— 它们经过优化以排在首位,因此其评分往往明显高于排名紧随其后的文档,而普通内容则不会出现这种情况。标记那些排名第一的文档相对于检索集其余部分具有异常相似度分数的查询。

实现权限感知检索。一个客户支持 RAG 系统不应该检索到内部薪酬战略文档,即使攻击者精心设计了对抗性查询试图让它们浮出水面。向量数据库需要在查询时强制执行文档级访问控制,而不只是在摄入时。将检索视为一种权限而非简单的搜索操作,可以消除一整类攻击。

生成层:根据权威来源验证输出。

生成后的验证是最后的安全网。在向用户返回答案之前,检查核心事实主张是否与来自最高信任源的内容一致。如果模型说 “所有退款请求都会自动批准”,但你经过验证的政策文档却说法相反,这就是一个信号。

这并不需要构建一个完整的事实核查流水线。对于结构化领域(定价、政策、账户数据),针对权威查询进行窄范围的验证检查即可捕获最严重的错误。目标不是捕捉每一个幻觉(hallucination);而是捕捉投毒攻击所针对的特定的、高风险的事实主张。

保持开放贡献模式

应对这种威胁的显而易见的反应是关闭贡献模式 —— 除了授权编辑外,让知识库变为只读。这确实有效,但它也消除了让 RAG 系统最初产生价值的功能。帮助台上下文、客户反馈、共享的机构知识:这些都是值得拥有的。

更好的路径是使贡献模式变得明确且有纪律。

向贡献者展示他们的内容在流水线中所处的位置。如果提交的文章正在审核队列中,请显示该状态。如果内容因验证而被隔离,请通知贡献者(但不要透露触发标记的具体原因 —— 不要教攻击者是什么触发了警报)。这种透明度降低了合法用户的挫败感,并为安全审查创建了审计追踪。

按风险等级分担审核负担。自动化闸门处理大部分明显合法或明显可疑的内容。人工审核则留给那些真正模棱两可的部分 —— 在一个调优良好的系统中,这只占总量的很小一部分。要求对每一项贡献进行人工审核无法规模化;但要求对被标记的贡献进行人工审核则是可行的。

建立反馈循环。追踪生产中检索到的内容是否与下游质量信号相关联 —— 如低用户评分、明确的投诉、问题升级。当你发现某种模式时,追溯到源文档。这就是你捕获那些通过了摄入验证的高级潜伏攻击的方法:不是通过发现毒素,而是通过注意到中毒后的反应。

在攻击发生前你需要的基准

一个被低估的需求是:如果没有基准,你就无法检测到 RAG 投毒。如果你在攻击发生前不知道正确的答案长什么样,你就不会注意到答案何时发生了偏移。

纵向评估(Longitudinal evaluation)在这里至关重要。定期针对你的 RAG 系统运行一组固定的查询并存储结果。当输出发生漂移时(通过衡量与历史答案的语义距离,而不仅仅是字符串比较),调查为这些查询检索到的源文档。这就是你发现三周前激活的潜伏攻击的方法:触发查询终于出现在了生产流量中,而输出突然变错了。

OWASP 在其 2025 年的更新中,正式将向量和嵌入弱点列为 LLM 系统的前十大风险。研究界已经发布了多个攻击基准测试,显示目前的防御措施存在显著差距,特别是针对单文档攻击和嵌入优化的对抗性内容。防御者的工具链尚不如攻击者的工具链成熟。

这不是避开开放式 RAG 系统的理由 —— 而是应该以对待任何接收并处理用户输入的系统同样的严谨性来构建它们。知识库就是一条代码路径。像对待代码一样对待它。


实际的建议是:如果你正在构建或运行一个带有开放贡献的 RAG 系统,请先审计你的摄入流水线。这是杠杆率最高的干预点,也是投毒内容最容易被检测到的地方,在验证闸门上的投入会在每一个下游风险中获得回报。源信任层级和检索异常检测紧随其后。生产监控排在最后 —— 不是因为它不重要,而是因为如果没有摄入环节的纪律所提供的基准,监控也无济于事。

References:Let's stay in touch and Follow me for more thoughts and updates