認証されていない1件のPOSTリクエストだけで、GitHub上で最も広く導入されているAIエージェント・オーケストレーションプラットフォームの一つにコマンドシェルを開くことができました。この足がかりを得た攻撃者は、OpenAIやAnthropicのAPIキーを窃取し、ユーザーの会話履歴を読み取り、攻撃者の支配下にあるエージェント群を新たに生成し、さらにシステムの永続メモリに悪意ある指示を埋め込むことさえ可能でした。パスワードもトークンも、いかなる形の本人確認も必要としません。
脆弱性の詳細:Rufloに存在するCVE-2026-59726
Noma Labsの研究者たちは、オープンソースのRufloプラットフォームに存在するこの重大な欠陥を発見しました。彼らは詳細な技術解説の中でこれを「RufRoot」と名付け、CVE-2026-59726として追跡しています。この脆弱性にはCVSSスコア10.0という最高評価が付けられ、バージョン3.16.3より前のすべてのRufloリリースが影響を受けます。
Rufloは、開発者が複数のAIエージェントを連携させたグループを構築し、セッションをまたいでコンテキストを維持し、Model Context Protocol経由で外部ツールと接続できるようにするプラットフォームです。今回の研究成果が公開された時点で、このプロジェクトはGitHub上で67,000件を超えるスターを獲得していました。
MCP Bridge:233の関数、認証はゼロ
このプラットフォームの中核をなすのがMCP Bridgeです。これはExpress.jsサーバーであり、すべてのツール呼び出しとエージェントの動作はここを経由します。この一つのコンポーネントだけで、エージェント管理、メモリ操作、データベースクエリ、コンテナ内でのコマンド実行にまたがる233種類の関数が公開されていました。
デフォルトのDocker Compose設定では、ポート3001がすべてのネットワークインターフェースにバインドされていました。パブリックインターネットから到達可能かどうかはファイアウォールのルールやクラウドのセキュリティグループ設定に左右されるものの、MCP Bridgeにネットワークアクセスできる者であれば誰でも、トークンやAPIキーなど一切の認証情報を提示することなくコマンドを発行できました。
脆弱なエンドポイント
POST /mcpエンドポイントはJSON-RPCリクエストを受け付け、それをそのままexecuteTool()関数へ転送していました。Rufloは危険なコマンドを禁止するためのブロックリストを維持していましたが、この制限はオートパイロットモードにのみ適用されるものでした。MCP Bridgeへの直接呼び出しは、この保護機構を完全に迂回してしまいます。
公開されていた関数の中には、コンテナ内でUID 1000のnodeユーザー権限のもと任意のOSコマンドを起動するruflo__terminal_executeも含まれていました。コード実行を達成するには、たった1件のHTTPリクエストで十分だったのです。このプロセスはすでに環境変数、エージェントのインターフェース、永続メモリ、データベースへのアクセス権を保持していたため、権限昇格すら不要でした。
攻撃者が窃取できたもの
コンテナ内部に保存されていた環境変数には、接続されているあらゆる外部サービスのAPIキーが含まれていました。窃取される可能性があった認証情報には、OpenAI、Anthropic、Google、OpenRouterの各キーが含まれます。盗まれたキーは、被害者の費用負担で攻撃者が支配するエージェント群をただちに稼働させるために転用できました。
AWS上で検証された8段階の攻撃チェーン
Noma Labsは、AWS EC2上で稼働する標準的なRufloデプロイメントに対して、自動化された8段階の攻撃チェーンを構築し検証しました。その手順は次のように進みます。利用可能なツールを列挙する、任意のコマンドを実行する、AIプロバイダーのキーを抽出する、攻撃者が制御するエージェントを作成する、そしてMongoDBから会話履歴を窃取する、という流れです。
MongoDBインスタンスは、必須の認証を設けないままDocker内部ネットワーク上で稼働していました。シェルを取得した攻撃者は、一時ディレクトリにデータベースクライアントをインストールし、メッセージ内容や会話タイトル、関連するメタデータをコピーした上で、外部サーバーへ送信できました。
永続メモリの汚染
SynackによるRufRoot攻撃対象領域の分析では、この脆弱性が持つとりわけ厄介な側面として、Rufloの永続メモリストアであるAgentDBの汚染が指摘されています。
攻撃者は、エージェントのメモリに悪意あるルールを書き込むことができました。たとえば、エージェントが生成するあらゆるデプロイメントスクリプトに攻撃者が制御するアドレスを追記させる、といった指示です。この注入された指令は、以降のエージェントの応答すべてに影響を及ぼし、コンテナが更新されても検知されないまま生き残ります。
重要なのは、コードにパッチを当てても、すでに侵害されたメモリストアの完全性は回復しないという点です。悪意あるエントリは処理の過程で形を変えられていたり、他のテンプレートへ伝播していたり、複数の場所に複製されていたりする可能性があります。管理者は、ソフトウェアの修正を適用するのとは別に、AgentDBを独自に監査し浄化する必要があります。
/appディレクトリを介したバックドアの設置
研究者たちはまた、保護されたファイルに一切手を加えることなく、永続的なバックドアを設置できることも実証しました。主要なindex.jsファイルは書き込み保護されていたものの、/appディレクトリでは新規ファイルの作成が許可されていました。攻撃者はそこに悪意あるスクリプトを書き込み、コンテナの起動シーケンスに組み込んだ上で、主要プロセスを終了させることができます。すると、Dockerのrestart: unless-stoppedポリシーによってRufloが自動的に再起動され、埋め込まれたバックドアも一緒に呼び戻されてしまいます。
修正:バージョン3.16.3
Coinkiteはこの脆弱性をRuflo 3.16.3で修正しました。更新後の設定では、MCP Bridgeはデフォルトでlocalhostにのみバインドされます。外部への公開には明示的なMCP_AUTH_TOKENの設定が必須となり、terminal_execute経由のコマンド実行は、MCP_ENABLE_TERMINAL=trueが意図的に設定されない限り無効化されたままとなります。
これに伴うADR-166パッチでは、MongoDBの認証が必須化され、コンテナは読み取り専用モードに切り替えられ、tmpfsによる一時ファイルシステムがマウントされ、CORSのオリジン制限が強化されたほか、安全性を欠く設定をデプロイ前に検出する自動テストも追加されました。
外部公開されている環境が今すぐ取るべき対応
ネットワーク経由でアクセス可能なRufloインスタンスを運用している事業者は、直ちに以下の対応を取るべきです。第一に、ネットワーク境界でポート3001と27017を閉塞します。第二に、バージョン3.16.3以上へアップグレードします。第三に、コンテナ環境に存在していたすべてのAPIキーをローテーションします。第四に、MongoDBに対する不正なデータアクセスがなかったか監査します。第五に、AgentDBを点検し、正規に作成されたものではないエントリをすべて削除します。
AIインフラのセキュリティが示す教訓
RufRootは、言語モデルそのものを悪用したわけでも、安全フィルターを回避したわけでも、巧妙に細工したユーザープロンプトでエージェントを操ったわけでもありません。この攻撃が狙ったのは、エージェントを取り巻くインフラそのもの――ネットワークサービス、ツールのインターフェース、コンテナ、認証情報、データベース、そして永続メモリ層――でした。
パッチを適用した後でも、すでに侵害されていたインスタンスの所有者は、新しいコンテナをデプロイし直すだけで十分な対策と見なすことはできません。修正版は脆弱な侵入口を塞ぎますが、侵害が発覚する前に流出したキーや、コピーされた会話、エージェントのメモリに書き込まれた悪意ある指示までは取り戻してくれないのです。
翻訳元: https://meterpreter.org/rufroot-cve-2026-59726-ruflo-mcp-bridge/