暗い紺色の背景に描かれた抽象的なテクニカルイラスト:半透明の箱の左壁にある光る入力ポートが、バッジもキーも持たない一本の細い淡い線を受け入れている。箱の内部で、その線は小さな角丸パネルの積み重なりに合流し、角張ったコマンド風の短い一連のストロークへと分岐して、光る鍵形トークンの集まりを収める下段の区画へと下っていく。入力ポートのそばには、淡い青で輪郭を描かれたもう一つの閉じたゲートがある。文字、人物、組織のロゴはない。
AI Safety Incidents

BifrostのManagement APIへの未認証POST 1回で、ゲートウェイユーザーとしてコマンドが起動された

著者

Magnus Corvin

公開日

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

2026年9月14日、JFrog Security Researchが公開したCVE-2026-90898は、Bifrostにおけるコマンド実行の脆弱性で、10点満点中9.8と採点された。攻撃はHTTPリクエスト1回だけで成立する。認証を必要としないPOST /api/mcp/clientがstdio MCPクライアントを登録すると、Bifrostはそれをプログラム名と引数リストとして解釈し、MCPハンドシェイクを待つことなく、ゲートウェイを実行しているユーザーとして直ちに起動してしまう。公式イメージではそのユーザーはappuserである。またゲートウェイは、事業者のプロバイダーキーや仮想キーが置かれる場所でもあるため、そこで動くプロセスは認証情報に到達できてしまう。このリクエストを匿名で通してしまったのは、出荷時のデフォルト設定だった。governance.auth_config.is_enabledがfalseであり、JFrogの表現を借りれば「認証がオフなら、すべての呼び出し元がローカル管理者である」。この脆弱性が実際に悪用されたと報じる情報源は確認されていない。この記録自体の情報源、深刻度の格付け、信頼度評価はAIインシデントアーカイブにあり、過去1年間に記録された他のAIゲートウェイやMCPの脆弱性と並んで掲載されている。

Bifrostは、アプリケーションと呼び出し先の言語モデルとの間に位置する単一のサービスです。そのリポジトリでは、オープンソースでApache-2.0ライセンスのゲートウェイであり、「23以上のプロバイダーへのアクセスを…単一のOpenAI互換APIを通じて統合する」と説明され、機能にはMCPプロキシ、仮想キー、予算、プロバイダーごとの負荷分散が含まれ、2026年10月28日時点で約9,150個のGitHubスターを獲得していました。その組み合わせこそが、この特定のホスト上のシェルがクリティカルスコアに値するまさに理由です。リクエストをルーティングするプロセスは、ルーティング先のすべてのアップストリームの認証情報を保持するプロセスでもあるからです。Hacker Newsは9月22日にこの欠陥を報じ、その結果を端的に示しました。ゲートウェイは接続されたすべてのプロバイダーのAPIキーを保存しているため、ゲートウェイプロセス上でコマンドを実行すると、攻撃者にそれらの認証情報へのアクセスが与えられます。

攻撃全体は単一のPOSTでした

JFrogのアドバイザリ(参照番号 JFSA-2026-001686326)は、管理者がMCPサーバーを追加できるようにするために存在するエンドポイントについて説明している。MCP仕様におけるstdioクライアントはURLではなく、コマンドとその引数であり、ホストプログラムがそれを起動することが想定されている。Bifrostは管理API経由でその設定を受け入れ、クライアントが追加されるとすぐにプログラムを起動する。機能ネゴシエーションも、サーバーIDの確認も、事前に成功しなければならないハンドシェイクもない。アドバイザリは、プロセスを起動するのはハンドシェイクではないと明言している。

アドバイザリ内の概念実証は、認証をデフォルトのままにしたゲートウェイに投稿される短いJSONボディです。これは、コマンドが/bin/shで、引数がマーカーファイルを書き込むクライアントを登録し、その後マーカーを読み戻します。JFrogは、インシデント対応時に重要となる運用上の詳細を付け加えています。Bifrostが決して来ないハンドシェイクを待っている間にHTTPリクエストがタイムアウトすることがあり、ログにタイムアウトが記録されてもコマンドの起動に失敗したわけではありません。その時点ではプロセスはすでに実行中です。

CVEレコードは、JFrogがCVE Numbering Authorityとして割り当てたもので、この欠陥をCWE-306(重要な機能に対する認証の欠如)およびCWE-284(不適切なアクセス制御)に対応付け、ハンドラーとそのミドルウェアを含む2つのファイル、transports/bifrost-http/handlers/mcp.go と transports/bifrost-http/handlers/middlewares.go を明示しています。影響を受けるモジュールは github.com/maximhq/bifrost/transports で、LinuxおよびmacOS上、2.1.0未満のすべてのバージョンが該当します。

リクエストを匿名にしたデフォルト

そのいずれも、2つ目の条件がなければ悪用できません。そしてその2つ目の条件とは、製品自身のデフォルト設定です。Bifrostの管理認証ミドルウェアは governance.auth_config.is_enabled によって制御されており、これは false で出荷されています。これがオフの場合、ミドルウェアはすべての呼び出し元をローカル管理者として扱います——アドバイザリ自身の要約にあるとおり、認証がオフならすべての呼び出し元がローカル管理者になる——ため、リクエストを止めるはずだったチェックは経路に存在しませんでした。

修正はプルリクエスト #6757 として2026年9月2日にプロジェクトへマージされた。CVEが公開される12日前、そのCVEを含むリリースの6日前のことである。その説明は問題の形について異例なほど率直で、このプルリクエストは同じ登録APIにおける未認証アクセスのプリミティブを1つではなく2つ塞ぐものだと述べている。1つ目はstdioクライアント。2つ目はループバックアドレスやプライベートネットワークのアドレスを指すhttpまたはsseのMCPクライアントで、これは内部サービスに対するSSRFプリミティブであり、「169.254.169.254のクラウドメタデータエンドポイントを含む」と説明されている。どちらも現在は、正規の資格情報チェックを経ずにリクエストがハンドラーに到達した場合、HTTP 403で拒否される。認証済みの管理者は両方の機能を引き続き利用でき、運用者はconfig.jsonを通じてstdioクライアントを引き続きプロビジョニングできる。

その2番目のプリミティブはCVEのテキストには現れない。それはパッチの中にあり、修正が削除ではなくゲートになっている理由でもある。問題だったのは機能そのものでは決してなく、未認証の呼び出し元を管理者として扱っていたことだった。

管理 API が実際にリッスンしていた場所

到達性は、情報源が最も一貫して説明している一方で、最も測定していない記録の部分である。JFrogのアドバイザリでは、標準バイナリのデフォルトはlocalhost:8080とされており、これにより攻撃者はホスト自体に限定される。同じチームによる関連脆弱性のアドバイザリでは、公式Dockerイメージは代わりに0.0.0.0にバインドされると述べており、The Hacker Newsもそれを繰り返している。すなわち、ポートが公開されていれば、このイメージによって管理APIがコンテナ外から到達可能になる。Bifrost自身のREADMEクイックスタートでは「docker run -p 8080:8080 maximhq/bifrost」を実行しており、Dockerの-pはアドレスを指定しない限りコンテナポートをすべてのホストインターフェースで公開する。この脆弱性に関するGitHubアドバイザリには、報告された経路が公開済みのmaximhq/bifrost:latestイメージに対して検証されたと記録されている。そこでは、未認証のリクエストが/bin/shを起動し、appuserとしてマーカーを書き込んだ。

どの情報源も示していないのは、数字だ。インターネットに露出したBifrostインスタンスの数も、スキャン結果も、テレメトリも、被害者も存在しない。記録には実際の被害が含まれておらず、その不在は安心材料ではなく、報告に関する事実である——この脆弱性クラスが危険となるのは、露出したリスナーと未変更のデフォルトという二つの条件が重なる場合だけであり、それらがどの程度の頻度で重なったかを公表した者は誰もいない。

1つのエンドポイント、2つの欠陥、1つの根本原因

MCP アドバイザリの8日前、2026年9月6日に、同じ研究チームが公開したCVE-2026-86242は、同じプロセスへの2つ目の未認証経路です。Or Peles によって発見され、8.1 と採点されたこの脆弱性は、POST /api/pluginsを悪用します。Bifrost は、パスが HTTP URL である有効なカスタムプラグインを受け入れ、共有オブジェクトローダーは http で始まるパスをダウンロードとして扱い、本文を一時的な .so ファイルに書き込み、そのファイルを Go の plugin.Open に渡します。読み込みが成功すると、オプションの Init 関数が攻撃者の設定で、ゲートウェイユーザーとして直ちに実行されます。

ビルドフレーバーによって、攻撃者が得られるものが決まる。プロジェクトがカスタム Go プラグイン向けに文書化している動的リンクビルドでは、読み込みが成功することが想定されており、アドバイザリではこれを未認証のリモートコード実行と呼んでいる。公開されている静的リンクの Docker イメージでは、plugin.Open が「Dynamic loading not supported」で失敗するため、同じリクエストはサーバーサイドリクエストフォージェリに格下げされる。読み込み可能なプラグインは、ホストの Go バージョン、オペレーティングシステム、アーキテクチャ、リンケージにも一致している必要があり、これは形式的な条件ではなく実際の制約である。修正は pull request #5763 による transports/v2.0.0 で、影響範囲はそれ未満のすべてである。

罠はリリース順序にある。v2.0.0はプラグイン経路を修正するが、MCP経路は修正しない。The Hacker Newsもそう明言しており、JFrogのMCPアドバイザリは、v2.0.0が依然として未認証のstdio登録を許可していることを確認している。9月6日のアドバイザリ後すぐにパッチを適用した運用者でも、その点だけを見れば、9月8日にtransports/v2.1.0が出荷されるまで依然として露出していた。両方の欠陥は、両方のアドバイザリとベンダー自身のプルリクエストにおいて同じ一文に帰着する。「認証無効がデフォルトである」。

資料が立証していること、そして立証していないこと

メカニズム、バージョン範囲、修正、クレジットは、アドバイザリ、JFrogが割り当てたCVEレコード、プロジェクト自身のプルリクエストとリリースノート、およびThe Hacker Newsの間で一致している。残る意見の相違は深刻度についてであり、それは現実のものである。

9.8 というスコアは、割り当てを行った CNA としての JFrog のスコアであり、NVD が採用しているスコアでもある — NVD のレコードではメトリクスのソースとして reefs@jfrog.com が記載されており、2026年10月28日時点でも、その項目は「Awaiting Analysis」ステータスのまま表示されている。これは、NVD がそれに関する独自の分析ではなく、割り当て者のベクトルを公開していることを意味する。同じレコードに添付された CISA コーディネーターの SSVC 評価は、2026年9月14日のタイムスタンプで、悪用(exploitation)は「none」、自動化可能(automatable)は「yes」、技術的影響(technical impact)は「total」と記している。FIRST の EPSS モデルは、2026年10月27日時点で、今後30日以内に悪用される確率を 2.3 パーセント、スコアリング対象の全 CVE の中で 83 パーセンタイルと算出しており、この CVE も CVE-2026-86242 も、2026年10月27日付の CISA Known Exploited Vulnerabilities カタログには掲載されていない。

それに対して、Maximは評価に異議を唱えている。同社の最高技術責任者(CTO)兼共同創業者であるAkshay Deo氏はThe Hacker Newsへの声明で、実用的なリスクはクリティカルスコアが示すよりも低いと述べた。悪用には、管理インターフェースが信頼できないネットワークから到達可能であること、および運用者が認証を未設定のままにしていることが必要だからだという。同氏によると、デフォルトかつ文書化された配備では、ゲートウェイはプライベートネットワーク内に置かれる。The Hacker Newsは、Maximがこの脆弱性を低深刻度と考えており、CVEを割り当てたJFrogと評価の改訂に取り組んでいると報じている。その声明はその媒体にのみ掲載されている。Maximの立場を引用した第二の報道は見つかっておらず、2026年10月28日時点で改訂は公開されていなかった。CVEレコードは9月14日に、NVDエントリは9月18日に最終更新されており、いずれも依然9.8のままだ。

さらに二つの食い違いは、覆い隠すのではなく、はっきり指摘する価値がある。このプロジェクトのGitHubアドバイザリは、2026年9月23日に公開され、JFrogの研究者を報告者としてクレジットしており、MCPの脆弱性については依然として9.8、プラグインの脆弱性については8.1を記載していて、Maximが説明した改訂の兆候は見られない。また、これらのアドバイザリの影響範囲は、JFrogのアドバイザリが用いるtransportsのリリースタグではなく、Goモジュールのバージョン(1.5.27未満と1.6.3未満)に基づいて書かれている。そのため、運用担当者が一方の文書を他方と突き合わせる際には、ビルドが影響を受けるかどうかを判断する前に、2つの番号体系を整合させる必要がある。

Rendered two-column card with the kicker 'BIFROST · CVE-2026-90898' and the title 'What the sources establish — and what they do not', subtitled 'Sources: JFrog JFSA-2026-001686326 (14 September 2026), the CVE record assigned by JFrog, NVD, FIRST EPSS, the CISA KEV catalogue, and the project's pull request 6757 and release tags.' The left column, headed 'ESTABLISHED' in blue, lists eight items: score 9.8 with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H supplied by the CNA; CWE-306 missing authentication with CWE-284 access control; unauthenticated POST /api/mcp/client starting a program as the gateway user; affected below transports 2.1.0 when management auth is disabled, the default; fixed in transports 2.1.0, PR 6757 merged 2 September, released 8 September 2026; CISA SSVC of 14 September 2026 with exploitation none, automatable yes, impact total; EPSS 2.3 percent at the 83rd percentile on 27 October 2026; and not in the CISA KEV catalogue dated 27 October 2026. The right column, headed 'NOT ESTABLISHED, OR CONTESTED' in amber, lists eight items: no exploitation reported, and the archive records real harm as false; no count of exposed or affected deployments in any cited source; severity contested, the vendor's CTO telling The Hacker News it is low; no published revision to the score as of 28 October 2026; NVD still Awaiting Analysis, so the 9.8 is the assigner's and not NVD's; affected ranges stated in two numbering schemes across the advisories; no detection or triage guidance in either advisory; and no evidence tying the flaw to any intrusion. A footer reads 'Card rendered by OrcaRouter'. The OrcaRouter logo is composited in the bottom-right corner.

何が変わり、オペレーターは何をするよう指示されたのか

時系列は開示から遡って進んでおり、これは記録の中で最も直感に反する部分だ。プルリクエスト #6757 は2026年9月2日にマージされた。transports/v2.1.0 は、勧告が修正を含む最初のリリースとして挙げているものだが、9月8日に公開された——CVE-2026-90898 が9月14日に公開される6日前である。プロジェクトのプラグイン修正も同じように独自の勧告に先行した。transports/v2.0.0 は8月26日に出荷され、9月6日のCVEの11日前だった。フィードではなくリリースを追う運用担当者は、警告を受け取る前にパッチを手にしていた。

アップグレードで得られるものは限定的かつ具体的である。2.1.0以降では、未認証のstdio登録は403を返し、コマンドは起動しない。認証済みの管理者は引き続きこの機能を利用でき、config.jsonによるプロビジョニングも引き続き機能する。移行できない人向けのアドバイザリの暫定策は、governance.auth_config.is_enabledをtrueに設定し、強力な管理者資格情報を使用し、管理リスナーを信頼できないネットワークから遠ざけることだ。認証を無効にした状態で外部に露出して稼働していたインスタンスに対するJFrogの指示は、調査して様子を見るのではなく、侵害されたものとして扱い、仮想キーとプロバイダー資格情報をローテーションすることだ。

バージョンの算術は、最も誤読されやすい部分です。v2.0.0 はこの欠陥を修正していません。1.6.x 系は 1.6.11 まで含めても修正が入っておらず、プロジェクトの最新の 1.6 系タグは 2026年8月14日公開の transports/v1.6.11 で、2026年10月28日時点でリポジトリに 1.7 系は存在しません。したがってこの系列内に修正版リリースはなく、1.6.x の運用者はバックポートを待つのではなく 2.1.0 以降へ移行する必要があります。現在のリリース系列はその地点をはるかに超えており、transports/v2.3.2 は 2026年10月20日に公開されています。

Rendered release-timeline card with the kicker 'BIFROST · RELEASE TIMELINE', the title 'The fix shipped six days before the advisory' and the subtitle 'Dates from the project's release tags and pull request metadata, the JFrog advisories and The Hacker News. Every date below is a single day.' A horizontal timeline carries seven dated markers: 26 Aug 2026, transports 2.0.0 published; 2 Sep 2026, PR 6757 merged; 6 Sep 2026, CVE-2026-86242 published, 8.1; 8 Sep 2026, transports 2.1.0, the fix; 14 Sep 2026, CVE-2026-90898 published, 9.8; 22 Sep 2026, vendor statement reported; 23 Sep 2026, GitHub advisories published. Below it, three bars show release lines: a hatched amber bar labelled '1.6.x line' reading 'affected — no patched release in the series; newest tag 1.6.11, 14 August 2026'; a bar labelled '2.0.0' split between a pale blue segment reading 'plugin flaw fixed' and a red segment reading 'MCP flaw still open'; and a solid blue bar labelled '2.1.0 and later' reading 'MCP fix — unauthenticated stdio registration returns 403'. A foot band headed 'THE PART THAT IS EASY TO GET WRONG' notes that 2.0.0 was the patched release on 6 September and did not close the MCP path, that for the two days before 2.1.0 an operator who patched on the day of the warning was still exposed, and that the 1.6.x series has no fixed release at all. A footer reads 'Card rendered by OrcaRouter'. The OrcaRouter logo is composited in the bottom-right corner.

公開後に、防御側が活用できることが2つ起きた。プロジェクトのGitHubセキュリティアドバイザリ——MCPの脆弱性(Critical)に対するGHSA-86gf-xh3g-rvxqと、プラグインの脆弱性(High)に対するGHSA-2qp8-4xgm-fw6g——は2026年9月23日に公開され、依存関係フィードとアドバイザリフィードに照合に使える2つ目の識別子を与えた。また、2026年10月13日には、CVE-2026-90898の検出テンプレートが公開のnuclei-templatesリポジトリにマージされた。つまり、未認証の登録試行に対するチェックは、各チームが自ら書くものではなく、スキャンパイプラインが実行できるものになった。

Abstract illustration on a dark navy field: a wide translucent slab representing a credential store, filled with evenly spaced glowing key-shaped tokens, stands behind a low wall. A narrow gateway aperture in the wall holds a fresh, brighter set of tokens, a blank card-shaped slip lies pushed aside on the ground in front of it, and a thin amber arc sweeps from the aperture around to the store. A second gateway aperture in the background remains closed and unlit. No text, no people, no organisation logos.

未解決のまま残っているのは深刻度であり、それが決着するかどうかは、なお協議を続けている2組織にかかっている。報じられているところによれば、Maximの立場は、9.8という評価は、問題となるために公開されたリスナーとデフォルト未設定を必要とする脆弱性を過大評価しているというものだ。これは原則として検証可能な主張だが、公には検証されていない。なぜなら、その2条件を満たした展開が何件あったかを誰も公表していないからだ。JFrogの立場は、CNAとして付与したスコアであり、CVEレコードおよびNVDにおいて今も有効だ。どちらかが改訂を公表するまで、運用上の解釈はいずれにせよ同じだ。すなわち、この脆弱性は実在し、公開されたコンテナイメージ上でエンドツーエンドに検証された。修正は警告より前に出荷され、1.6系には修正がまったくない。そして、到達可能なリスナー上で認証を無効にして実行されたインスタンスは、パッチ適用を予定する案件ではなく、資格情報インシデントとして扱うべきだ。