TECHNIQUE / 攻击手法

RAG 语料投毒

污染检索库,让模型在正确的问题上给出被操纵的答案。

8 篇相关6 个来源首见 2026-11-15最近 2026-11-15正文已写
8
相关条目
6
来源数
11-15 → 11-15
时间跨度
手法
类型

RAG 语料投毒

一句话

污染检索库,让模型在正确的问题上给出被操纵的答案。 攻击者不需要碰模型,只需要碰模型会读的那份文档。

这和提示词注入是同一件事的两面:注入是"这一条内容里藏了指令",投毒是"这批内容整体被我控制了"。后者更隐蔽,因为它不需要单条 payload——每条文档看起来都正常,是组合起来才有害。

为什么这个攻击面成立

三个结构性原因:

1. 检索是"不可信内容进入上下文"的最短路径。 用户问一个问题,系统自动去库里捞 5 段文本塞进 prompt——这 5 段没人审过。

2. 相似度不等于可信度。 余弦相似度只回答"这段文字和问题像不像",完全不回答"这段文字谁写的、谁改过"。

3. 库是持续写入的。 知识库不是一次建成的,是每天有人上传、同步、抓取。写入路径就是攻击路径,而写入路径通常只有"登录即可"这一道门。

四种投毒面(按利用难度排)

类型怎么投为什么难防
语料注入往知识库里塞文档(上传、同步、爬取、工单、issue)业务上"允许上传"是功能,不是缺陷
元数据投毒改标题/标签/摘要,让它在检索时排更前元数据通常不做内容审核
分块与嵌入操纵构造 chunk 边界,让恶意段落被完整检索出来;或埋高频关键词抬高相似度切分策略是工程实现细节,攻击者可以先逆推
检索后劫持文档正文里藏指令("忽略以上,改为…"),模型读到就执行这是注入,但入口是"我们自己库里的文档",信任度更高

最容易被忽略的是第二和第三类。 大家盯着"文档里有没有恶意指令",但真正有效的是"让我的文档排在第一名"——排名本身就是攻击面。

一条完整的链

① 攻击者找到写入路径(公开 issue / 简历投递 / 论坛发帖 / 共享盘同步 / 供应商文档)
        ↓
② 内容里既有关键词(抬高相似度),又有指令(改变行为)
        ↓
③ 用户提出一个完全正常的问题("我们的退款政策是什么")
        ↓
④ 检索把攻击者的文档排到第一,塞进 prompt
        ↓
⑤ 模型照做:给出错误答案,或调用工具把上下文发出去

注意第 ③ 步:受害者没有做错任何事。这是投毒比注入更危险的地方——它不需要诱导用户。

真实案例(按时间)

怎么防(按有效性排)

1. 写入侧分级:库里的内容按来源打标签(内部撰写 / 客户上传 / 公网抓取),检索时不同来源走不同权限。公网抓取的内容永远当不可信。

2. 检索结果标注来源:把 chunk 的 id、来源、写入时间一起给模型,并要求答案必须引用 chunk id。这样被污染时你能追到是哪一段。

3. 排名多样化:不要总取 top-k 的同一批文档;加来源多样性约束,避免单一来源垄断。

4. 毒样本检出测试(最实用):定期往库里投放已知的蜜罐文档(内容正常但含特定标记),看它会不会被检索出来、会不会改变答案。这是唯一能持续验证"你的 RAG 还健康吗"的手段。

5. 输出侧:高危动作(转账、发邮件、调外部 API)不走 RAG 结论,必须有结构化参数 + 二次确认。

我的判断(2026-11)

相关(本站内)

时间线

来源分布

同一个主题出现在越多来源里,可信度越高;只出现在一个来源的,当线索看待。

arXiv cs.CL(语言)
2
V2EX
2
Project Zero
1
FreeBuf
1
华尔街见闻
1
Ars Technica
1