一幅抽象技术插图:两条路径通向同一个密闭金库。上方路径遇到一层红色半透明权限膜,并在其前停下。下方路径向下弯折,穿过一串小六边形节点,从膜下方滑过,并沿一条绿色细线抵达金库的侧门。金库内,一把黄铜钥匙置于磨砂玻璃之后。深石墨色调,无文字、无标识、无人物。
AI Safety Incidents

MaxKB:智能体调度路径使被拒绝使用某工具的用户仍能调用该工具并读取其凭据

作者

Rowan Sterling

发布日期

最新模型 · 20查看全部模型 →
基准测试:Artificial Analysis · 每日更新
返回全部文章

由 1Panel-dev 维护的开源企业级 AI 助手 MaxKB 提供了按用户、按工具的权限列表,使管理员可以为工作区成员授予某个工具的权限,并拒绝另一个工具的权限。根据 2026 年 9 月 2 日发布的安全公告,该拒绝在工具自身的路由上有效,但在智能体或工作流调用同一工具所使用的路径上无效。拥有最低角色的工作区成员在构建工作流时可以指定被拒绝工具的标识符,运行该工作流,并不仅收到该工具的输出,还收到 MaxKB 为运行该工具而在服务端解密出的凭据。2.0.0 至 2.9.2 版本受到影响,且公告未指明任何修复版本。本记录——MaxKB 工具调度授权绕过——是OrcaRouter AI Incident Archive中的一条记录,该档案收录了完整记录集以及本事件的相邻条目。

让这个案例值得仔细阅读的并不是评分,而是该产品已经具备正确的检查,并将其应用在显而易见的那扇门上,却让通往同一能力的第二扇门无人看管。该公告 GHSA-383v-fx78-pphm 由发现它的研究人员撰写,并于 2026 年 9 月 2 日 07:43 UTC 通过 GitHub 的公告系统发布,致谢 Matteo Panzeri(@matte1782)。CVE 记录 CVE-2026-77516 随后于 2026 年 9 月 21 日发布。

该公告所确立的内容

MaxKB 的按工具授权模型是 WorkspaceUserResourcePermission,该公告将其描述为在请求时解析的默认拒绝允许列表。专用的工具路由会强制执行该权限。公告列出了 apps/tools/views/tool.py 中的执行情况,其中 Operate.put、Operate.get、Debug.post、Export.get 和 Delete 各自都会针对调用方的工作区工具权限进行视图权限检查。Debug.post 是最接近直接运行工具的路由,并且它受到了权限门控。

Agent 和工作流调度路径不会重新应用该检查。安全公告梳理出三个会遗漏该检查的不同位置。在 apps/application/serializers/application.py 中,应用序列化器从请求输入中直接绑定 tool_ids、skill_tool_ids 和 mcp_tool_ids,且没有按工具进行授权——公告指出,同一文件中这种不对称很明显,因为 knowledge_id_list 在下方几行会针对用户可访问的知识库进行校验,而工具则不会。在 apps/common/utils/shared_resource_auth.py 中,filter_authorized_ids 会无条件放行调用者自身工作区中的每个工具;它所依赖的跨工作区门禁是仅企业版才有的钩子,社区版中不存在,而且它从不查询 WorkspaceUserResourcePermission。而在最终执行点,apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py 会以应用的身份运行工具存储的代码,其 init_params 由 rsa_long_decrypt 解密,且没有按工具进行授权检查。

该公告将这一结果称为混淆代理执行:工作流分派会运行一个工具及其存储的机密,而同一调用方在工具自身的路由上却被拒绝使用该工具。凭据暴露是超出普通未授权工具使用的部分。工具的 init_params使用 RSA 进行静态加密,并且仅在执行时在服务器端解密,因此触发该执行的调用方会收到其从未持有且无法提供的值。

Diagram titled 'Two doors to the same tool'. A dedicated tool route passes a WorkspaceUserResourcePermission gate and returns 403. The agent and workflow dispatch route bypasses the gate, binds tool_ids without a per-tool check, and returns 200 with the tool's decrypted secret.

这场演示,用研究者自己的数字来说明

该公告报告了在 v2.9.2 上进行的动态确认,使用官方一体化镜像 1panel/maxkb:v2.9.2 运行。环境包含一个工作空间、一名管理员,以及另一名拥有 USER 角色的成员。管理员创建了 Tool A 和 Tool B,并将一个新的随机密钥放入 Tool B 的 init_params中,还编写了 Tool B 的主体,使其在执行时返回该密钥。随后,该成员仅被授予了针对 Tool A 的工具级权限;公告称,运行后在数据库中重新检查了 Tool B 的零授权状态。

测试中被拒绝的那一半返回了产品所承诺的结果。作为该成员,工具 B 的调试路由返回 403,更新路由返回 403,导出路由返回 403,而被授予权限的工具 A 返回 200,作为基本校验。随后,绕过的那一半通过一个工具库节点将工具 B 绑定到一个工作流应用中——该绑定被接受,返回 HTTP 200,且没有任何针对单个工具的检查——运行该工作流返回 HTTP 200,响应体中包含该工具的名称、哨兵密钥,以及键列表 ["api_key"]。

该安全公告称,该机密在三个层面暴露:工作流 API 响应中、状态为 SUCCESS 的工具执行记录中,以及数据库行中——Tool B 的 init_params以 344 字节的 RSA 密文形式存在——研究者正是据此论证,该值是在应用身份下于服务端解密得到的,而不是由调用方提供的。同一个在工具运行路由上被拒绝的成员,通过将其绑定到工作流中,获得了该工具解密后的机密。

公布了一个分数,另一个更高的分数则存在争议

CVE-2026-77516 附带的评分为 CVSS 3.1 5.4,中危,向量为 AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N。NVD 的记录显示,该评分来自 GitHub 的公告源,而非 NVD 自身的分析;该条目状态为 Deferred(已推迟),意味着 NVD 尚未对其进行补充完善。该存档自身的分类沿用了这一已发布的评分:中危,未记录到现实世界中的实际危害。

该公告自己的影响部分主张更高。它指出,在将机密性影响提升为高的向量上,严重性为 7.1(高),并表示当被调用的工具以应用程序身份执行特权写入时,该数值会升至 8.1。这是关于如何计算凭据暴露程度的分歧,而不是关于绕过是否存在——同一份文档既展示了该缺陷,又主张其被低估。公开记录中没有任何内容能确定哪个数值是正确的,而该档案的中等评级跟踪的是已发布的 CVE 评分,而非该公告的论点。

另有两项评估已记录在案。CISA 的 SSVC 决策点于2026年9月28日添加到 NVD 条目中,将利用状态记为“poc”,可自动化记为“no”,技术影响记为“partial”——“poc”值反映的是存在概念验证,而该公告本身确实包含概念验证;这并不表示发现其在野利用。FIRST 的 EPSS 模型在日期为2026年10月27日的估计中,将未来30天内被利用的概率定为0.242%,处于第15.2百分位。

Score card comparing three figures: published CVSS base score 5.4 medium with vector AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N; 7.1 high argued in the advisory's impact section, rising to 8.1 for privileged writes; and FIRST EPSS 0.242 percent at the 15.2nd percentile, dated 27 October 2026.

修复早于安全公告就已存在,而受影响范围内则没有任何修复

安全公告的版本表显示受影响版本为 2.0.0 至 2.9.2,已修复版本为无;其正文称截至审查时没有可用修复版本,并补充说,若在带标签的发布版本中提供修复,便可让 CVE 锚定到该版本。厂商的代码仓库则呈现出略有不同的情况,而这一差异对任何要决定运行哪个版本的人来说都很重要。

在 MaxKB 仓库中,用于关闭该调度路径的函数——validate_bound_tool_permissions 和 get_authorized_tool_ids(位于 apps/application/serializers/application.py)——在 v2.9.2 标签以及 v2.10.2-lts、v2.10.3-lts 和 v2.10.4-lts 中均不存在,而从 v2.10.5-lts 起开始存在。该版本于 2026 年 8 月 6 日发布,比公告早四周。同一标签还为 base_tool_lib_node.py 增加了基于 WorkspaceUserResourcePermission 的按用户工具检查,并为 shared_resource_auth.py 增加了用户感知过滤器——也就是说,它大致实现了公告随后建议的三项修复步骤。

没有人公开说明过这种关联。v2.10.5-lts 的发布说明没有提到工具权限修复;其中列出了四项互不相关的安全事项,以及一批功能与缺陷相关工作。该公告没有点名 2.10.5,其受影响范围仅止于 2.9.2,也就是 2.9 系列的最后一个版本。发布历史显示,该公告之后没有 2.9.x 补丁,因此部署在 2.9.2 上的实例在其自身系列内没有已修复的构建。当前版本是 v2.10.8-lts,发布于 2026 年 10 月 22 日,其说明描述的是 X-Pack 对共享工具授权的修复,而不是社区版调度路径中的任何内容。

Timeline card. 6 August 2026, v2.10.5-lts published with the per-user tool check present in tagged source. 2 September 2026, advisory GHSA-383v-fx78-pphm published, credited to Matteo Panzeri. 21 September 2026, CVE-2026-77516 published to NVD. 22 October 2026, v2.10.8-lts is the current release.

什么尚未确立?

有三点值得与这次演示区分开来。第一,没有任何公开报告称该绕过手法曾被用于针对任何人。现有记录是一项被发现漏洞,而不是一起经过调查的入侵;它不涉及受害者、未被归因的行为者,也没有造成损害,而公告中的概念验证是由研究者在受控工作区内运行的。第二,似乎没有任何新闻机构、监管机构或第二支研究团队分析过该缺陷:现有的报道仅限于漏洞数据库和聚合平台——其中包括 VulDB、Rapid7 的数据库、Armis、SOCRadar 和 openCVE——它们列出该 CVE 并转载公告中的描述,但没有任何一家对相关代码提供独立评估。因此,这里描述的机制仅依据一份公告和厂商自己的源代码。第三,目前没有关于有多少 MaxKB 部署处于受影响范围内的数字,厂商和研究者均未公布相关数据。

面临风险的范围较窄,但统计起来并不简单:运行 2.0.0 至 2.9.2 的自托管社区版 MaxKB 安装,且拥有不止一个工作区成员,并且管理员已使用按工具权限来拒绝某个携带凭据的工具。该缺陷不是远程代码执行,且需要有效的低权限账户,因此决定评分的是机密性影响,而不是攻击路径。攻击者能获得什么受限于被拒绝工具所持有的内容——API 密钥、令牌以及这些内容所能解锁的东西——这也是为什么该公告的作者认为其影响大于低机密性评级所暗示的程度。

操作员可以做什么

该公告的修复建议面向维护者而非运维人员,其三个步骤对应 v2.10.5-lts 中出现的代码:在工具库和工具节点实现中执行工具之前应用按工具授权,并校验每个绑定的 tool_ids、skill_tool_ids 和 mcp_tool_ids,方式是在绑定时就像 knowledge_id_list 已经做的那样,并让 filter_authorized_ids 参考按工具授权,而不是仅参考工作区成员资格。

对于运行受影响构建的团队,根据该公告自身的描述,可采取的实际步骤如下。

• 将工具的 init_params 中存储的每个密钥,在受影响的部署上都视为任何工作区成员(包括最低角色)均可访问,并轮换这些凭据,而不是假定按工具进行的拒绝已保护它们。

• 审计工作区成员资格。该绕过需要工作区内有一个已认证账户,因此移除休眠或不受信任的成员可以减少暴露面,即使代码无法修补也是如此。

• 审查哪些工作流和智能体绑定了携带凭据的工具,因为该公告指出,正是这一绑定步骤会在没有逐工具检查的情况下被接受。

• 若进行升级,请注意:按用户检查自 v2.10.5-lts 起便已出现在代码仓库中,且该公告并未指定任何发布版本为修复版本——依赖此次升级的操作者所依据的是带标签的源代码,而非厂商的补丁声明。

这一切都没有让这个缺陷显得戏剧化,反而以一种具体且有启发性的方式让它变得寻常:授权模型的设计是正确的,文档也是正确的,并且被强制执行在那些有人记得要加权限校验的路由上。调度路径是由那些思考“一个工作流应该能做什么”的人编写的,而不是思考“是谁在发起请求”的人——而在一个智能体平台中,大多数请求实际走的正是这条路径。

这条记录带来的教训是结构性的,而非数字上的。按资源授予的权限,其强度只取决于防护最薄弱的入口点,而智能体平台会迅速积累入口点:调试路由、导出路由、工作流节点、聊天触发器。MaxKB 有授权列表,也有检查;对于 2.0 到 2.9 这条产品线来说,它缺少的是在每一扇门前都问同一个问题的习惯。