Same Bytes, Different Authority: Reserved-Token Representations in Chat-Template Prompt Injection
Yan Zhan, Yunze Song, Mengkai Hou, Wanting Zhang, Shaobo Liu, Zhijun Gao
cs.CR, cs.AI, cs.LG
2026-09-28
把伪造模板标记编成普通子词、字节不变,三家模型InjecAgent成功率掉39到66点;Qwen3-8B仅掉8点,关掉推理后扩到50点。
把恶意指令包进模型自己的 chat template(把 system、user、assistant、tool 回合框起来的那套标记),攻击会强很多。ChatInject 把 AgentDojo 上的成功率从 5.18% 拉到 32.05%。前人把这解释成模板结构或角色风格,但伪造标记叠了两件事:看得见的字符串,以及 tokenizer 把它编成的保留 token(词表里专留给对话边界的控制符)id 和它学到的输入向量。
同一串「<|imstart|>」可以是一个保留控制 token,也可以拆成六个普通 subword(日常文本用的子词片段)。解码字节完全一样,请求体和审计日志看不出差别。谁决定用哪种 id?服务端 tokenizer,攻击者碰不到。vLLM 默认把工具返回里的这段字符串编成保留 id;Hugging Face 的 splitspecialtokens 则编成普通 subword。此前几乎没人在字节不变的条件下把这两件事拆开。Deng 等人在 Qwen3-8B 上按字符拆标记,目标工具调用概率从 100.00% 变到 99.99%,据此认为攻击靠的是标签语法。固定字节的对照问的是,注入指令的权威有多少来自那个学到的向量。
威胁模型很窄:攻击者只控制一条工具返回的字节,系统提示、用户任务、工具 schema、服务配置都不动。成功标准是模型下一轮调用了攻击者指定的工具。
对每个 InjecAgent 样本构造一组提示,内容、注入位置、工具集相同,只改伪造标记的编码:
身份缺口 Δ = ASR(Matched) − ASR(Split),同一案例成对比较。评四个 tokenizer 互不相关的开源家族:Qwen3-8B(加 32B 做尺度核对)、Llama-3.1-8B-Instruct、GLM-4.5、Seed-OSS-36B-Instruct。每种攻击类型 400 条,温度 0、greedy,同一配置的条件一起跑;缺口必须在每一次重复里都显著才算坐实。
Matched 全程贴着 Reserved,差不超过 1.7 个点,多出来的 token 几乎不花钱。字节和长度对齐后再拿掉保留 id,三家模型的攻击塌一截。
| 模型 | 攻击 | Reserved | Split | Δ |
| Llama-3.1-8B | 直接伤害 | 98.2% | 39.7% | +58.2 |
| Llama-3.1-8B | 数据窃取 | 99.5% | 49.1% | +50.2 |
| GLM-4.5 | 直接伤害 | 71.5% | 11.1% | +60.0 |
| GLM-4.5 | 数据窃取 | 92.3% | 27.2% | +65.5 |
| Seed-OSS-36B | 直接伤害 | 85.0% | 26.2% | +58.6 |
| Seed-OSS-36B | 数据窃取 | 76.9% | 39.3% | +39.3 |
| Qwen3-8B | 直接伤害 | 84.8% | 75.3% | +8.1 |
| Qwen3-8B | 数据窃取 | 90.9% | 89.5% | +0.5 |
Llama、GLM、Seed 是 39 到 66 个点。Qwen3-8B 直接伤害只有 8.1,数据窃取接近零。Qwen3 吃的是标记字面:首字母改大写让 Split 掉 39 个点,另外三家这个表面项在 10 个点以内。关掉 Qwen3-8B 的推理块,缺口从 8.1 扩到 49.8,Split 从 75.3% 掉到 35.8%,保留 id 一侧几乎不动。32B 上直接伤害缺口变成 18.0 个点。Deng 的零结果来自读出已经贴着 100%;换成功率口径,按字符拆在 Qwen3-8B 上要掉 54.2 个点。
权威落在标记位置上那一个向量,像后训练里学到的「新指令回合开始」戳记。换成标记 subword 向量的均值,Llama-3.1 只到 58.4%;换成嵌入空间最近的普通 token 向量,回到 98.4%,和保留向量的 98.2% 持平。另一个保留控制 token 的向量能把两家都维持在接近满强度。base 模型不会正常结束回合,所以在同一提示上比较攻击者工具相对用户工具的 logit:三对里指令微调后的 checkpoint 都更偏爱保留标记。
AgentDojo 四套件 409 对任务,按执行层安全检查计分,Qwen3-8B 缺口 +10.3 个点,32B 是 +6.8。去掉保留 id 后搜 115 到 133 种拼写,Llama、GLM、Seed 的最优解都是嵌入近邻普通 token,相对无防御只差 1.6 到 12.2 个点。
自托管开源 agent 的部署者可以做一次测量:同一串字节,只改 tokenizer 发不发保留 id,就能估计现有开关挡住了多少攻击。标准缓解只处理配置里声明为 special 的 token。Hugging Face 下载量最高的 400 个 chat 模型里,67 种 tokenizer 配置中 33 种、覆盖 255 个 checkpoint,把「<toolresponse>」这类工具协议 token 留在开关外面;只用这些 token 伪造的块,缺口仍有 9.4 到 19.9 个点。工具通道是 agent 读不可信输出的路,开关没盖住。
StruQ、SecAlign 这类训练期防御可以用同一套固定字节对照,看消掉的是触发词还是这个向量。攻击评测如果只报字符串、不报模型实际吃到的 token id,会把两种机制混在一起。
默认攻击靠保留 id。自适应攻击跟着表示走,普通近邻 token 能把权威接回来。
作者自己划了三条。只覆盖部署者能控制分词的自托管开源模型,只收字符串的托管 API 不在范围内。InjecAgent 的成功是下一轮解析出攻击者工具,执行层只在 AgentDojo 上测。向量替换动的是模型输入,不是攻击者能发出的字节。
另外几处没补上。Qwen3-8B 数据窃取缺口从未坐实,plaintext 已经 41.6%,模板字面本身就够用,不能说所有 Qwen 都主要靠向量。自适应近邻在校准集上选出再拿到测试集,现实攻击者不一定有这条通道。附录的 source-aware encoder 没有和 StruQ、spotlighting 做端到端对抗比较。GLM-4.5 用 FP8 推理,绝对成功率不能拿来排家族名次。