AI工具业务参数合并与服务端信任重建的两段归一化示意图

工具可以提交业务意图,但身份、设备和内部调用资格必须由服务端重新构造。

摘要| 一个AI工具接口同时接收JSON、Query和Form时,同名字段听谁的只是第一道题;更关键的是,业务参数合并完以后,调用方能不能借机伪造当前用户、设备或内部任务身份。本文结合Microi吾码当前源码和6项本地测试,拆解“两段归一化”:先稳定合并业务字段,再删除并恢复服务端信任上下文。

① 同一个字段从三个入口进来,必须只有一个答案

AI工具调用很容易同时拥有几种参数来源:SDK把主体放进JSON,网关把租户或版本放进Query,浏览器表单又提交Form。假设三处都出现 `temperature`、`page` 或 `action`,如果没有固定优先级,结果就取决于框架绑定顺序和客户端组合。

这种不确定性不是“小概率兼容问题”。它会直接破坏重放、审计和幂等:日志里看见一份JSON,实际执行的却可能是另一份Query值。

第一条原则| 同名业务字段必须有公开、稳定、可测试的优先级;不能把“最后被框架读到的值”当成协议。

② 第一段归一化:Form覆盖Query,原始JSON只补缺失

JSON Query Form业务参数按稳定优先级合并的流程图

控制器从已绑定参数开始,依次写入Query和Form;重新读取原始JSON时只补还不存在的属性。

Microi吾码当前 `DefaultParam` 先保留控制器已经拿到的JObject,随后写入Query,再写入Form。因为后写覆盖前写,同名业务字段形成稳定顺序:Form高于Query,Query高于初始绑定值

部分动态路由里,框架可能没有把JSON Body完整绑定进参数对象。源码会重新读取已经启用缓冲的请求体,但恢复时逐项检查:只有目标参数袋里还不存在这个属性,才深拷贝进去。因此修复“漏绑定”不会顺手推翻已经生效的Query或Form。

初始JObject → 写入Query → 写入Form → 原始JSON只补缺失项
同名字段:Form获胜
仅JSON存在:恢复进入参数袋
已有Query/Form:JSON恢复不得覆盖

兼容不等于改语义| 恢复请求体的目标是补齐丢失字段,不是重新定义旧客户端已经依赖的优先级。

③ 为什么不能在业务参数合并前写入当前用户

假如服务端一开始把 `_CurrentUser` 放进参数袋,随后又合并请求体,那么攻击者只需要提交同名字段,就可能覆盖服务端值。即使下游最终还有权限校验,这个伪造对象也可能先污染日志、条件判断或分支选择。

更稳的办法是先让所有不可信业务输入到齐,再进行第二段归一化:删除调用方不该控制的字段,然后从当前会话和真实请求上下文重建。顺序本身就是安全边界。

业务字段和当前用户设备标识调用信任分轨矩阵

提示词、分页和筛选可以合并;当前用户、设备来源与内部调用资格不能由同一参数袋自证。

第二条原则| 不可信输入先完成,可信上下文后重建。任何可能影响授权的服务端事实,都不能参加普通“谁后写谁赢”的合并。

④ 第二段归一化:用户、设备和调用类型各自回到真实来源

  1. 当前用户:登录态存在时,从DiyToken解析的CurrentUser重新写入;匿名状态下直接删除请求中的伪造值。
  2. 设备标识:先删除参数袋中的 `_DeviceId`,再只读取真实HTTP请求头里的 `did`,并限制最大长度。
  3. 可信调用:无条件删除HTTP输入中的 `_TrustedServerInvocation`,不让业务JSON把自己升级成内部请求。
  4. 调用类型:HTTP路径最终固定为 `Client`,即使请求体写了 `Server` 也不会保留。
// 调用方提交的业务意图可以留下
param.prompt = request.prompt;

// 信任字段必须删除并从服务端来源重建
param._CurrentUser = token.currentUser;
param._DeviceId = realDidHeader;
delete param._TrustedServerInvocation;
param._InvokeType = 'Client';

字段名不是权限| 调用方能猜出 `_TrustedServerInvocation` 这个名字,不代表它就能获得服务器来源。真正的边界是绑定路径和重建顺序。

⑤ 内部后台任务为什么不能只看一个true

平台内部确实需要例外:持久化后台任务可能以Client语义继续执行,但又必须保留可信当前用户。若只检查一个布尔标记,任何能够构造参数的人都会尝试把它设成true。

可信后台任务需要服务端保留内部标记任务身份信封一致和有效租约

完整信任是多个条件的交集:服务端保留、内部标记、任务Id、信封一致和正数租约令牌缺一不可。

当前安全判断要求服务端明确允许保留可信用户、内部标记成立、外层任务Id存在、嵌套任务信封的Id与外层一致,并且 fencing token 是正整数。任何一项缺失,StopHttp仍然把它当作普通外部Client阻止。

trusted = serverPreserved
       AND internalMarker
       AND taskIdExists
       AND envelope.id == taskId
       AND fencingToken > 0

第三条原则| 内部例外应该是完整信封的交集,不应该是参数袋里一个可以被猜到的布尔开关。

⑥ 对AI工具协议的直接启发:参数和值的来源要分开设计

大模型函数调用经常输出一个结构完整的JSON,这种完整感很容易让人误以为每个字段都可信。实际上,模型只是在表达业务意图;账号、租户、角色、设备、内部调用资格、授权策略和幂等租约都必须来自平台。

  • 工具schema只暴露业务需要的字段,不把服务端信任字段包装成隐藏参数。
  • 多来源业务字段在网关层完成一次确定性合并,下游不再自行猜优先级。
  • 身份和授权上下文在合并之后注入,并覆盖或删除所有同名输入。
  • 内部作业使用不可由普通JSON绑定的类型、构造器或服务器信封。
  • 日志同时记录最终业务参数来源和信任上下文来源,避免只看最终值。

模型的职责边界| 模型可以决定“要查什么、要生成什么”,不能决定“我是谁、我属于哪个可信作业、我是否绕过外部访问限制”。

⑦ 六项测试分别证明了什么

AI工具参数与信任边界六项本地测试证据图

本轮选定测试6项全部通过,失败0、跳过0;原始TRX与相关源码哈希均已留档。

四项 `ApiEngineInvocationSecurityTests` 覆盖普通Client阻断、完整后台信封、任务Id或租约异常、Server与关闭策略不受影响。另两项边界测试验证:浏览器JSON不能绑定可信调用或授权策略;服务器构造的MCP可信写可以保留标记,而结构相同的JSON伪造值会被丢弃。

total 6   executed 6   passed 6
failed 0  skipped 0    exitCode 0
duration 309 ms
.NET SDK 10.0.300

证据边界| 这组结果证明当前本地源码中的选定参数与信任边界;它不自动证明某个线上租户、公开接口或全部授权路径。

⑧ 结论:先统一业务语义,再恢复服务器事实

这套设计可以浓缩成两段:第一段只解决业务字段冲突,让JSON、Query和Form得到一个可重放答案;第二段只解决信任,让当前用户、设备和调用资格回到服务器掌控。

顺序不能交换。信任字段过早注入会被后续输入覆盖;业务参数过晚合并又可能绕过校验。把两段边界写进公共入口,并用伪造用例固定下来,AI工具调用才不会因为参数越来越多而把权限语义越搅越乱。

最终判断| 业务字段可以比较优先级,信任字段只能追溯来源;前者要确定性合并,后者要删除后重建。

Logo

宁波官方开源宣传和活动阵地,欢迎各位和我们共建开源生态体系!

更多推荐