2つの経路が1つの密閉された金庫に到達する、抽象的な技術イラスト。上側の経路は赤い半透明の許可膜に突き当たり、そこで止まる。下側の経路は小さな六角形ノードの連なりを通って下へ曲がり、膜の下をすり抜け、緑の糸に沿って金庫の側扉に到達する。金庫の内側では、すりガラスの奥に真鍮の鍵が置かれている。暗いグラファイトの配色、文字なし、ロゴなし、人物なし。
AI Safety Incidents

MaxKB: エージェントのディスパッチ経路では、ツールを拒否されたユーザーでも、そのツールを呼び出して認証情報を読み取ることができます

著者

Rowan Sterling

公開日

最新モデル · 20すべてのモデルを見る →
ベンチマーク:Artificial Analysis · 毎日更新
すべての記事に戻る

1Panel-dev が保守するオープンソースのエンタープライズ AI アシスタント MaxKB は、ユーザー単位・ツール単位の権限リストを提供しており、管理者はワークスペースのメンバーに一方のツールを許可し、他方を拒否できます。2026年9月2日に公開されたセキュリティアドバイザリによると、その拒否はツール自体のルートでは有効でしたが、エージェントやワークフローが同じツールを呼び出す際の経路では有効ではありませんでした。最下位のロールを持つワークスペースメンバーは、ワークフローを構築する際に拒否されたツールの識別子を指定し、そのワークフローを実行することで、ツールの出力だけでなく、MaxKB がそれを実行するためにサーバー側で復号する認証情報も受け取ることができました。バージョン 2.0.0 から 2.9.2 が影響を受け、アドバイザリでは修正済みバージョンは示されていません。この記録——MaxKB のツールディスパッチ認可バイパス——は、アーカイブに収録された1件のエントリです: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 は、単にツールを実行することに最も近いルートであり、ゲートされています。

エージェントおよびワークフローのディスパッチ経路では、そのチェックが再適用されません。アドバイザリは、それが欠落している3つの別個の箇所を追跡しています。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で復号し、アプリケーションの識別情報の下で実行します。ツールごとの付与チェックは行いません。

勧告はこの結果を confused-deputy 実行と呼んでいる:ワークフローのディスパッチは、同じ呼び出し元がツール自身のルートでは拒否されるツールを、その保存されたシークレットとともに実行する。認証情報の露出は、通常の不正なツール使用を超える部分である。ツールの 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.

研究者自身の数字で示す実証

このアドバイザリは、公式のオールインワンイメージ 1panel/maxkb:v2.9.2 から実行した v2.9.2 における動的確認を報告しています。構成は、1つのワークスペース、1人の管理者、および USER ロールを持つ2人目のメンバーでした。管理者は Tool A と Tool B を作成し、Tool B の init_params に新たに生成したランダムなシークレットを設定し、実行時にそのシークレットを返すように Tool B のボディを記述しました。その後、メンバーには Tool A のみに対するツール単位の権限が付与され、アドバイザリによると、実行後に Tool B の権限が付与されていない状態がデータベースで再確認されました。

テストの拒否側は、製品が約束する通りの結果を返した。メンバーとして、Tool B のデバッグルートは403を返し、更新ルートは403、エクスポートルートは403を返し、許可された Tool A は健全性確認として200を返した。続くバイパス側では、ツールライブラリノードを通じて Tool B をワークフローアプリケーションにバインドした — バインドはHTTP 200で受け入れられ、ツールごとのチェックはなく、ワークフローを実行するとHTTP 200が返り、その本文にはツール名、センチネル秘密、キー一覧 ["api_key"] が含まれていた。

勧告では、この秘密情報が三つの層で表面化したと述べられている。ワークフローAPIの応答、状態がSUCCESSのツール実行レコード、そしてデータベースの行で、そこではTool Bの init_paramsが344バイトのRSA暗号文として存在している。これにより研究者は、その値が呼び出し元から提供されたのではなく、アプリケーションの識別情報の下でサーバー側で復号されたと主張している。ツールの実行ルートで拒否された同じメンバーが、それをワークフローにバインドすることで、そのツールの復号済み秘密情報を入手した。

公表されたスコアは1つ、より高いスコアは主張されている

CVE-2026-77516 に付与されたスコアは CVSS 3.1 の 5.4、Medium(中)で、ベクターは AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N です。NVD のレコードによると、このスコアは NVD 自身の分析ではなく GitHub のアドバイザリフィードに由来しており、エントリのステータスは Deferred(保留)となっています。これは NVD がこの項目を拡充していないことを意味します。アーカイブ自体の分類もこの公開スコアに従っており、重大度は中で、現実世界での被害は記録されていません。

このアドバイザリ自身の影響セクションは、さらに高い評価を主張している。機密性への影響を高に引き上げるベクター上で深刻度は 7.1(High)であり、ディスパッチされたツールがアプリケーション ID で特権書き込みを行う場合にはこの数値は 8.1 に上がると述べている。これは認証情報の露出をどう数えるかについての不一致であり、バイパスが存在するかどうかについてではない——同じ文書が脆弱性を示しつつ、過小評価されていると主張しているのだ。公開記録の中にはどちらの数値が正しいかを決着させるものはなく、アーカイブの中評価はアドバイザリの主張ではなく、公開された CVE スコアに従っている。

さらに2件の評価が記録に残っている。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日に公開され、アドバイザリの4週間前でした。同じタグは、base_tool_lib_node.py にユーザーごとのツールチェックを追加しており、WorkspaceUserResourcePermissionを利用しています。また、shared_resource_auth.py にユーザーを考慮したフィルターを追加しています。つまり、アドバイザリが後に推奨する3つの修復手順を概略的に実装していることになります。

その関連性を公に述べた人は誰もいない。v2.10.5-lts のリリースノートにはツール権限の修正についての言及はなく、無関係なセキュリティ項目4件と、機能およびバグ対応の一連の作業が列挙されている。アドバイザリには 2.10.5 の記載がなく、その影響範囲は単に 2.9 系最後のリリースである 2.9.2 で止まっている。リリース履歴を見ても、アドバイザリ以降に 2.9.x のパッチはないため、2.9.2 でのデプロイには同一系列内に修正済みビルドが存在しない。最新リリースは 2026年10月22日に公開された v2.10.8-lts であり、そのノートはコミュニティ版のディスパッチ経路ではなく、共有ツール認可に対する 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.

確立されていないものは何か

このデモンストレーションから切り離して考えるべき点が3つある。第一に、このバイパス手法が誰かに対して実際に使用されたという公開報告はない。記録されているのは、調査された侵入ではなく、発見された脆弱性である。そこには被害者も、帰属された行為者も、実害もなく、アドバイザリの概念実証は研究者が管理された作業環境で実行したものだ。第二に、報道機関、規制当局、あるいは別の研究チームがこの欠陥を分析した形跡はない。存在する報道・掲載は脆弱性データベースとアグリゲーターに限られており、その中には VulDB、Rapid7 のデータベース、Armis、SOCRadar、openCVE などが含まれる。これらは CVE を列挙し、アドバイザリの説明を掲載しているが、いずれもコードについて独立した評価を示していない。したがって、ここで説明されている仕組みは、1件のアドバイザリとベンダー自身のソースコードに依拠している。第三に、影響を受ける範囲にどの程度の MaxKB 導入環境があるかを示す数字は存在せず、ベンダーも研究者もそれを公表していない。

リスクにさらされる対象は狭いが、数えるのは容易ではない。すなわち、2.0.0から2.9.2のセルフホスト型コミュニティエディションMaxKBインストールで、ワークスペースメンバーが複数おり、管理者がツールごとの権限を使って認証情報を伴うツールを付与していない場合である。この脆弱性はリモートコード実行ではなく、有効な低権限アカウントを必要とする。そのため、スコアを左右するのは攻撃経路ではなく機密性への影響である。攻撃者が得られるものは、拒否されたツールが保持するもの、つまりAPIキー、トークン、およびそれらによって解錠されるものによって限定される。アドバイザリの著者が、影響は低い機密性評価が示唆するより大きいと主張しているのも、同じ理由からである。

オペレーターにできること

このアドバイザリの是正措置は、運用者ではなくメンテナに向けられたものであり、その3つの手順は 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系で欠けていたのは、あらゆる入口で同じ問いを立てる習慣だった。