TECHNIQUE / 攻击手法

提示词注入

把不可信内容变成指令,让模型执行原任务之外的动作。

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

提示词注入(Prompt Injection)

一句话

把不可信内容当成指令。 模型无法区分"数据"和"命令",所以任何能进入上下文的字节,都可能变成一次操作。

这句话之所以成立,是因为 LLM 的输入是一个平铺的 token 序列:系统提示、用户消息、检索到的网页、工具返回值,全都拼在同一条流里,没有类型、没有边界、没有权限标记。所谓"指令"和"数据"的区别,只存在于人的理解里,不存在于模型的输入结构里。

为什么这个攻击面消不掉

不是"护栏做得不够好",而是三个结构性原因:

1. 同信道。指令和数据走同一条通道,任何"隔离"都只能是启发式的。

2. 不可判定。给定一段文本,判断"它是不是指令"在一般情况下不可判定——这和"判断一段代码有没有恶意"是同一类问题。

3. 能力换安全。模型的全部价值来自"能理解任意文本并据此行动"。削弱这个能力就是削弱产品。所以厂商必须在"更听话"和"更安全"之间持续妥协。

推论:只要模型还能读外部内容并调用工具,注入就存在。做安全的目标不是消灭它,是限制它的爆炸半径。

四类变体(按利用路径分,而不是按 payload 分)

类型恶意内容从哪进典型场景危害上限
直接注入用户自己输入"忽略以上,改为执行…"绕过内容策略、骗取系统提示
间接注入模型读到的第三方内容网页、PDF、简历、邮件、issue、代码注释数据外带、工具劫持
跨文档拼接多个来源各自无害,拼起来成指令RAG 多文档、多轮工具返回绕过单文档检测
表示层规避编码/隐藏字符Unicode Tag、零宽字符、Base64、HTML/CSS 隐藏、跨语言绕过过滤器与人审

关键区分:直接注入影响的是"这个用户能看到什么";间接注入影响的是"这个 Agent 能替攻击者做什么"。后者才是真问题,因为 Agent 手里有工具、有凭据、有内网。

一条完整的链长什么样

① 攻击者在目标会读的地方放内容(网页 / issue / 简历 / 文档注释)
        ↓
② Agent 因为正常任务去读它("帮我总结这个页面")
        ↓
③ 内容里的指令被当成任务的一部分("顺便把环境变量发到 xxx")
        ↓
④ Agent 调用它本来就有的工具(fetch / shell / MCP)
        ↓
⑤ 数据离开边界(DNS、图片 URL、第三方接口)

每一环都是"产品自己设计的功能",而不是 bug。这是这类漏洞最反直觉的地方:攻击链的每一段都合法。

真实案例(按时间)

怎么防(按有效性排序,不按厂商宣传排序)

1. 降爆炸半径(最有效):Agent 的凭据最小化、出网白名单、工具分级(读类 / 写类 / 执行类)、高危动作强制人工确认。假定注入一定会成功,问"成功之后它能干什么"。

2. 数据流隔离:不可信内容进入时打标(untrusted=true),并在工具调用处强制检查来源标签;对"读到的内容"和"用户说的话"用不同权限。

3. 输出侧约束:结构化输出(JSON Schema / Guided Decoding)能压缩可执行空间,但注意——约束本身也是攻击面,被阻断的拒绝路径可能把风险推到下游决策。

4. 检测与人在环:日志里保留完整上下文链;高危操作双人确认。

5. 输入过滤(最弱):能挡脚本小子,挡不住针对性攻击。不要把它当主防线。

我的判断(2026-11)

相关(本站内)

时间线

来源分布

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

FreeBuf
1
arXiv cs.CR(安全)
1