loading

Loading

探索与发现

首页 AI 前沿

对话模板拼接漏洞:推理服务的隐形入口

分类:AI 前沿
字数: (2079)
阅读: (3)
0
摘要:对话模板拼接漏洞不只是消息派发上的一个瑕疵,它发生在历史、重试、工具结果和预填充被各种工程细节层层拼到一个上下文的时候。这篇文章从组装责任、缓存复用与角色边界三个取舍展开,说明为什么一个拼接输入最终会决定整条推理链的信任边界。

从一个“多轮对话拼接”说起

先明确一个前提:对话模板拼接漏洞是近两年论文里反复出现的推理服务侧注入面。它的成因不在于模型本身被越狱,而在于服务端组装 messages 的方式——把历史、重试、重试失败重试、摘要、工具结果,一层层 plaintext 拼接进同一条上下文时,信任边界没有画清楚。

我在之前几篇文章讨论过流式工具调用、Agent沙箱和上下文压缩。对话模板拼接漏洞与这几件事有重叠,但它更底层:它恰好位于 web 框架和推理引擎之间,很多团队认为它不重要,两个都没碰过该职责边界。

漏洞是怎么被“拼”出来的

三个必需的要素。第一,服务端负责拼 messages,而不是每个 turn 都拿客户端传进来的完整 messages 原样转发。现实中几乎一半的对话产品属于前一种——为了做滑动窗口、摘要压缩、失败掉早于 N 轮的东西,不得不自己管理 history。

第二,拼接中混用不同角色之间的边界标记。典型的错误写法:

// 错误示例
let prompt = "You are a helpful assistant.\n";
for (

类似遗漏边界、忘记转义历史内容,就容易被历史内容反噬。历史上容易被用户注入的一轮 assistant-turn,下一次请求就变成模板里受信任的片段。

预填充这一类特殊拼接

另一条常见路径是故意把“assistant”预填充进最后一轮。Security 论文里提到,Gemini、Claude、Kimi K2 等模型在合法场景(例如强制 JSON 开头、控制思考语气)普遍使用该能力。各家推理平台对预填充的处理完全不同:Claude 走 assistant-turn 预填充,而 GPT-5.6 Luna 的 API 会拒绝超过约 50 token 的逐字子串拼接——双方在 security 层面的处理差异,与模型能力如 Haiku 4.5、Opus 4.8、Gemini Robotics ER-1.6 往往关系不大;分水岭正在于这一层。

权限与会话串线的交汇

AGENT-2026-001 到 010 那类清单,在通用报告里把模板注入列为高危条目。对话模板拼接一旦失败,后果最小是一轮 shell 历史泄露,严重则是对话窗口越权。拼接入口必须拿到会话 id、操作者 id 这类信息,但它与实际 access token 一旦相连,任何对模板注入的攻击就不再只是“让模型多说两句”,而是构造一条横向挪移。

工程上的三个取舍

取舍一:拼接交给谁。 客户端传 messages、服务端原样转发,拼接错误的风险低、可以维护模板;但客户端能改写 assistant 内容。反过来,客户端只是纯数据,拼接和服务侧负责,可以让长度治理容易做、但入口不能容忍一个没有 session 更新的 turn。我倾向后者——但要额外加固 role 标记和各角色的边界归属。

取舍二:每轮重建还是增量传递。 全量重建相当于每轮以拼接模板为基准重新组装 messages,可审计、能重放,开销主要在 token 和拼装;增量传递即 KV/request 参数做收敛,省前缀、也省拼接代码量,但一旦上一轮有一处异常渲染(或者 tool trace 发生),问题会静默传到后面每一轮。我的做法是全量 message 重建,引擎侧 warm 前缀留作可回退的冷启动入口,别把一份推理历史里可复用的参数也当作缓存的一部分透明化。

取舍三:工具结果、thinking 块、摘要能不能拆、放在哪。 这三者最容易打破角色消息结构。团队常见的处理有两个极端——一把塞进 data 或 system 里省事;或者把摘要放到独立 context 但显式区分 assistant-vs-runtime。前者在日志里混为一体,后者的模型组合反而更稳。我看对输入安全的验证优先使用后者做灰度。

推理轨迹可能带有隐藏推理内容,摘要不忠实会让一层摘要与一层 history 混在一起后出现拼接段越权。

容易被忽视的点

拼接之后还要看产出,输入 tokenizer 逐字校验和回复、输出前缀校验同样要建在 content 上,而不是只校验 content-disposition。论文里还提到 Anthropic 自己的摘摘率:Claude 泄漏历史的 ~1/5,历史被有选择地暴露、多进到模板里——到那时,模板拼接漏洞测试真正命中检测的概率已经取决于模型厂商的自我保护强度和平台版本号。

通用建议如果硬要理出可操作短名单:把 messages 存储去敏和 拼接边界上同时做 。

大多数拼接漏洞是版本迭代出的脚手架没有演化成约束流程。漏洞能长期存在,往往不是新增团队借 OSS 快速叠出来、调试完就上。定位 root cause 时定期看下发出去的 prompt byte 串和某一条 messages 装配代码的覆盖检测,往往能快速看清是不是手管理不清边界——最后一种做法频繁出现:正常拼接被切成“短字符串”再拼回去,而在这段代码停留的那一公里内仍没有人会记得。

转载请注明出处: 皮哈皮阿

本文的链接地址: https://blog.phpat.com/ai-frontier/663.html

手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

您可能对以下文章感兴趣
1 / 1
预览图