一个可复现的概念验证,展示了一种可绕过文本内容扫描器的隐写式提示注入向量,以及一种在解码边界处将其遏制的防御机制——解码时来源绑定。
仅用于教育/防御性安全研究。 本仓库中的所有密钥均为伪造。仅可在你拥有或获授权测试的系统上使用。
攻击者向受害者发送一封外观普通的电子邮件。邮件签名中的品牌徽标通过隐写术(LSB、DCT 或元数据)隐藏了一条指令。该图像与原始图像在视觉上完全相同,且不包含任何可疑文本,因此内容扫描器无法察觉任何异常,受害者也不会点击任何东西。但受害者日常使用的收件箱摘要代理会处理该签名,其流水线中的某个工具会解码该图像,隐藏的指令便进入代理的上下文——在多代理 MCP 流水线中,它作为可信的对等输出在代理之间传递,并驱动一次关键工具调用。这就是跨模态信任洗白。该防御机制——解码时来源绑定——在反转隐藏内容的工具运行的那一刻铸造一个经 HMAC 签名的 UNTRUSTED 标签,并让 MCP 层自行维护来源谱系,从而阻止任何谱系不可信的关键工具调用——即使某个被攻陷的代理为无关的可信值出示了有效标签。它遏制而非检测,因此与载荷措辞和载体无关。
攻击成功率(ASR)——24 个载荷(三种载体 × 八种规避方式:明文、良性措辞、Base64、令牌拆分、西里尔同形字、零宽字符、Unicode 混淆字符、HTML 注释);越低越好。进程内的污点基线是一种信息流控制,它将解码输出标记为不可信,但不携带跨域密码学绑定:
| 防御 | 泄露数 | n | ASR |
|---|---|---|---|
| 无防御(无检查) | 24 | 24 | 100% |
| 内容扫描器(关键字/DLP) | 15 | 24 | 62.5% |
| 正则意图解析器 | 15 | 24 | 62.5% |
| 数据流污点(IFC 基线) | 0 | 24 | 0% |
| 解码时来源绑定(本文方法) | 0 | 24 | 0% |
污点与来源绑定在单域 ASR 上持平;它们在对抗性中继下出现分歧(见下文),而这正是密码学绑定的意义所在。
有效标签替换——一个被攻陷的代理出示来自良性工具的合法签名 TRUSTED 绑定,同时省略实际驱动该调用的 UNTRUSTED 解码来源。修复方案是MCP 层自行维护谱系,并依据自己的账本而非代理提供的绑定做出决策:
| 执行方式 | 决策 |
|---|---|
| 仅依赖代理提供的绑定(朴素做法) | 允许(泄露) |
| 层维护,省略依赖 | 阻止 |
| 层维护,依赖在参数中 | 阻止 |
| 层维护,上下文干净 | 允许 |
组件消融——四个组件,各自防御一种不同的攻击。一次禁用一个;substitution 属于域内攻击,forged relay 是一个伪造的 TRUSTED 标签跨越不可信中继到达仅持有所出示绑定的远程验证器。关键在于,仅靠 HMAC 不能阻止替换(靠的是账本),而仅靠账本不能在跨域中继中存活(靠的是 HMAC):
| 配置 | 诚实 | 替换 | 伪造中继 |
|---|---|---|---|
| 完整机制 | 已阻止 | 已阻止 | 已阻止 |
| − 解码标记 | 泄露 | 泄露 | 泄露 |
| − 密码学认证(HMAC) | 已阻止 | 已阻止 | 泄露 |
| − 可信谱系追踪 | 已阻止 | 泄露 | 已阻止 |
| − 汇聚点中介 | 泄露 | 泄露 | 泄露 |
跨上下文传播 — 污点能够跨越代理间消息边界存活,而不仅仅是工具返回句柄。Agent A 中一次不受信任的解码会到达 Agent B 独立上下文中的关键调用,而在受中介的通道上(威胁模型已要求代理间通信使用此类通道),污点会传播,B 被阻止。该层不进行中介的通道在构造上就处于模型之外——不属于范围内的泄露:
| 通道 A → B | B 的关键调用 |
|---|---|
| 受中介的代理间消息(范围内) | 阻止(污点已传播) |
| 未中介的侧信道(模型之外) | 不覆盖 |
开销扩展性 — MintBinding 约为 O(1)(无论深度如何,约 10–14 µs);EnforceCritical 与其遍历的依赖闭包呈线性关系(深度 1 时约 10 µs → 深度 100 时约 0.66 ms → 深度 1000 时约 6.7 ms),并且在并发受污染上下文数量上保持平坦(约 6–7 µs)。现实中的闭包(深度在数十级别)保持在约 0.1 ms 以下。
合法任务效用 — 一条经过审计的可信提升路径(在授权下对特定解码值重新标记,例如 OCR 识别出的发票号码)消除了误阻止,同时攻击仍被阻止:
| 机制 | 完成情况 | 误阻止 | 攻击被阻止 |
|---|---|---|---|
| 无提升 | 2/3 (67%) | 1 | 是 |
| 可信提升 | 3/3 (100%) | 0 | 是 |
解码集完备性 — 直接对注册假设进行压力测试:
| 解码集 | 隐写攻击 | 合法关键调用 |
|---|---|---|
| 正确 | 已阻止 | 允许 |
| 缺少解码器 | 泄露 | 允许 |
| 范围过宽 | 已阻止 | 误阻止 |
跨交接的标签完整性 — 绑定在诚实中继下能够存活,并抵御被攻陷的工作节点:
| 中继场景 | 验证器决策 |
|---|---|
| 诚实中继,1 / 3 / 5 / 10 跳 | 验证通过;已阻止 |
| 被攻陷:重写载荷,保留 HMAC | 阻止(HMAC 不匹配) |
被攻陷:伪造 TRUSTED | 阻止(HMAC 不匹配) |
| 被攻陷:剥离绑定 | 阻止(无有效标签) |
开销 — 在决策点实际上几乎无成本:生成和验证一个绑定各约 8–9 µs(合计约 17 µs),而一次解码工具调用约 11 ms——增加不到约 0.2%。载体失真较低(LSB ≈ 76 dB PSNR,元数据无损;DCT ≈ 18 dB——这是一个失真度量,并非对感知不可察觉性的断言)。
stego_provenance_defense_poc.ipynb # the full PoC (run top-to-bottom)
requirements.txt # dependencies (mcp pinned <2)
运行 notebook 会将所有图表、表格和 CSV 写入 Colab 中的
MyDrive/stego_provenance_poc/{figures,tables,data}(或在本地写入
./stego_provenance_poc/)。每个图表和表格都由一个单元格生成,
因此整个流程可以从一次干净的运行中完全复现。
stego_provenance_defense_poc.ipynb。MyDrive/stego_provenance_poc/{figures,tables,data} 下。pip install -r requirements.txt
jupyter notebook stego_provenance_defense_poc.ipynb
输出结果位于 ./stego_provenance_poc/。GPU 是可选的(智能体模型很小);安全结果不依赖于该模型。
它结合了通常被混为一谈的两项保证,而正是二者的结合——而非单独的 HMAC——构成了本工作的贡献:
在 MCP 层执行两项确定性操作,该层自身维护血缘关系:
{payload, tool, trust, provenance, deps} 打上标记,当且仅当该工具
逆转了隐藏变换或任一输入为 UNTRUSTED(传染性)时,令 trust = UNTRUSTED,
记录解析后的输入依赖 deps,对其签名
HMAC_k(payload‖tool‖trust‖provenance‖deps),将其写入该层的账本,并且
(若为不受信任)将其加入上下文的污点集合。UNTRUSTED 数据来源或非空
上下文污点时予以阻止;否则放行。由于持有血缘关系的是该层——而非智能体——被攻陷的
智能体无法通过省略不受信任的依赖来将其隐藏。安全不变量。 在以下条件下:(i) 密钥仅限 MCP 层持有,(ii) 解码工具
完整注册,(iii) 每次关键调用均被中介,(iv) 该层记录每次调用的完整血缘关系
(解析后的参数依赖 + 进入每个上下文的解码来源):任何关键工具调用都不会
执行,只要其传递血缘——数据或上下文——包含 UNTRUSTED 解码
来源,除非经过审计的可信提升已清除该特定来源。
为教育和防御性安全研究而发布。参见 LICENSE。