flawopen.com/Teardowns/cve-2026-105697-langflow-mcp-stdio-command-injection
CVE-2026-105697:Langflow MCP コマンドインジェクション
1.10.3 より前の Langflow は、MCP stdio 設定をシェル経由で起動するプロセスに渡していました。ネットワークから到達可能で LANGFLOW_AUTO_LOGIN=true のインスタンスでは、攻撃者は認証情報なしでトークンを取得できました。自動ログインを無効にしても、認証済みの非管理者ユーザーはこの脆弱性を悪用してホスト上でコマンドを実行できます。1.10.3 では全経路と起動直前に検証し、シェルを介さず起動します。[1], [2], [3]
句読点によって仕事の内容が変わる文を受け取る係員を想像してください。ある記号が配送指示を別の命令に変えてしまうことがあります。Langflow は設定されたコマンドをシェルに渡し、実行ファイルと引数を別々のデータとして扱わず、構文を制御指示として解釈させていました。修正では許可されたコマンドを検証し、シェルを介さずにプログラムを起動します。[1], [2]
主要な概念と専門用語
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-78
根本原因の分析 (Root Cause)
1.10.3 より前は、MCP stdio 設定でコマンドと引数を文字列にまとめ、bash -c で起動していました。1.9.0 では設定 API に許可リストと引数・環境の検査が追加されましたが、flow や tweak に埋め込まれた MCP Tools 設定は、実行箇所に共通ポリシーがなかったためモデル検証を回避できました。Langflow 1.10.3 は lfx.base.mcp.security.validate_mcp_stdio_config に検証を集約し、API、flow、tweak、旧コンポーネント、起動直前のすべてで適用して、シェルを介さず起動します。CVE-2026-105697 は CWE-78、CVSS 3.1 で 9.9 です。自動ログインを無効にしていても、該当する MCP 経路を設定または実行できる認証済み非管理者ユーザーが必要です。既定の自動ログインは、公開された開発環境を認証なしで到達可能にする場合があります。[1], [2], [4], [5]
ステップ・バイ・ステップの攻撃フロー
ユーザーが MCP 設定経路に到達
アドバイザリでは、MCP サーバー設定または MCP Tools コンポーネントを使う flow 経由のアクセスが説明されています。ネットワークから到達可能で開発用の既定値 LANGFLOW_AUTO_LOGIN=true のインスタンスでは、認証情報なしでトークンを取得できました。自動ログインを無効にしても、認証済みの非管理者ユーザーで成立する場合があります。[1]
設定がプロセス準備へ進む
MCP stdio 接続の準備中に、コマンドと引数が command_str になります。[1]
シェルが文字列を解釈
1.10.3 より前の起動経路は bash -c を使用し、MCP handshake 成功前の接続試行時に実行されます。[1]
入口検査が不十分
1.9.0 は REST 設定を検証しますが、flow や tweak の設定はモデル検証を迂回できます。[1]
ホストプロセスは Langflow の権限で動作
コマンドは Langflow サービスのユーザーとして実行されます。画面上では MCP サーバーの起動失敗と表示される場合があります。[1]
ソースコード比較:脆弱 vs 堅牢化
脆弱な抜粋はアドバイザリに記載された shell 経由の起動方法を示すもので、実行可能な exploit ではありません。修正後の抜粋は 1.10.3 の設計を要約しています。共通ポリシーが各入口とプロセス生成直前に設定を検証し、API は実行ファイルと引数を分けて渡します。直接起動により shell の解釈はなくなりますが、許可された実行ファイルやパッケージがすべて安全になるわけではありません。運用環境に応じたパッケージソース制限と隔離も必要です。[1], [2]
ソース抜粋: lfx/base/mcp/util.py — 該当箇所の抜粋
# アドバイザリに記載された影響を受ける起動形式(抜粋):
server_params = StdioServerParameters(
command="bash",
args=["-c", f"exec {command_str}"],
env=env_data,
)
# 1.10.3 のソースに基づく簡略例: ポリシーを検証してから直接プロセスを起動する。
command_parts = shlex.split(command_str)
if not command_parts:
raise ValueError("MCP stdio command is required")
command, args = command_parts[0], command_parts[1:]
validate_mcp_stdio_config(command, args, env_data) # Repeat at the execution boundary.
server_params = StdioServerParameters(
command=command,
args=args,
env=env_data,
) # No shell wrapper. The shared validator rejects disallowed configurations.
エンジニアリング&システム堅牢化チェックリスト
- ✓
langflowを 1.10.3 以降、langflow-baseを 0.10.3 以降、lfxを 1.10.3 以降へ更新し、デプロイ済みのパッケージ版を確認します。[1], [3] - ✓1.9.0 の REST モデル検査を完全な修正と見なさず、旧版の flow/tweak に埋め込まれた MCP 設定を確認します。[1]
- ✓すべての入口とプロセス生成直前で、コマンド、引数、環境、パッケージソース、分離ポリシーを検証します。[1], [2]
- ✓プロセス API には実行ファイルと引数配列を分けて渡し、shell コマンド文字列の構築を避けます。[2]
- ✓マルチテナント環境では
npx/uvxの許可パッケージを固定し、文書化されたインタープリターおよび Docker の保護設定を有効にします。[1] - ✓FlawOpen のインシデント対応に関する推奨事項:影響期間中に MCP stdio 接続を設定・実行できたユーザーを確認し、ホストのテレメトリーから不審な Langflow 子プロセスを調査します。[1]
- ✓REST API、flow、tweak、旧コンポーネント、起動前経路の回帰テストを追加し、拒否された設定がプロセスを作らないことを確認します。[2]