FlawOpen

flawopen.com/Teardowns/cve-2026-97662-aws-security-agent-mcp-git-argument-injection

● CVE-2026-97662 · CVSS v4 6.9 · 中
セキュリティ研究 · FlawOpen

CVE-2026-97662:AWS セキュリティエージェント MCPのGit引数インジェクション

CVE-2026-97662では、AWS Security Agent MCPの差分スキャンで呼び出し元が影響できるGit参照がコマンドオプションとして解釈され、workspaceの制約を回避してホスト上のファイルを書き換えられる可能性がありました。0.2.0以降へ更新してください。[1], [2]

CVSS ベクトルCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N
💡 わかりやすい解説 (ELI5)

係員がラベルを頼りに書類を探しますが、制御指示で始まるラベルも受け付けてしまいます。保管システムは書類を探す代わりに、その指示を実行します。この問題では、ハイフンで始まるGit参照がオプションとして扱われる可能性がありました。Gitを起動する前に空の参照やオプションに見える参照を拒否すれば、この入力境界を閉じられます。 これは Git によるオプション解析であり、任意のシェルコマンド実行ではありません。[2]

主要な概念と専門用語

MCPサーバー
Model Context Protocolを介してAIアプリケーションにツールを提供するローカルプロセスです。ツール引数は信頼できないデータとして受け取ります。
引数インジェクション(CWE-88)
コマンドラインプログラムが信頼できない入力をオプションや区切りとして解釈する問題です。シェル文字列ではなく引数配列を使っても発生します。[2], [4]
Git参照
mainやHEAD~1のようにコミットやツリーを示す名前または式です。-で始まる値はオプションとして解析される可能性があります。[2], [3]
workspaceの制約
ツールのファイル操作を選択したプロジェクトディレクトリ内に保つ境界です。入力によってサブプロセスコマンドの意味が変わると、この境界は不完全です。[1], [3]

フレームワーク対応

根本原因の分析 (Root Cause)

AWSはdiff scan操作における条件付きの引数インジェクションを説明しています。スキャンに渡した参照がGitのリビジョンではなくコマンドラインオプションとして解釈される可能性がありました。上流PRによると、start_diff_scanはbase_refをgit diff <base_ref> --とgit archiveに渡しており、空の値やハイフンで始まる値が誤解釈され得ました。これはシェルメタ文字のインジェクションではありません。引数配列はシェルによる解析を防ぎますが、呼び出されたプログラムは引き続きオプションを解析します。AWSの説明では、プロセスのOS権限の範囲で、意図したworkspace外のファイルを作成、上書き、切り詰める可能性がありました。マージ済みの修正はGit呼び出し前にbase_refを検証し、空白値と、空白除去後に-で始まる値を拒否します。テストでは拒否時にサブプロセスもアップロードも起きないことを確認しています。対象は>=0.1.1かつ<0.2.0で、0.2.0で修正されました。CVE記録はCVSS 4.0 6.9(中)、GitHub AdvisoryはCVSS 3.1 8.2(高)も掲載しています。ここでは実行可能な攻撃ペイロードを示しません。[1], [2], [3], [4]

ステップ・バイ・ステップの攻撃フロー

ステップ 1

エージェントがdiff scanツールを呼び出す

ローカルMCPサーバーは呼び出し元が影響できるbase_refを受け取ります。信頼できないリポジトリ、コンテンツ、ユーザーがこの値を決められるワークフローでリスクが生じます。プロンプトインジェクションだけで自動的にこのコード経路へ到達するわけではありません。[2]

ステップ 2

値が位置引数としてGitに渡る

影響を受けるコードはその参照をGitのdiffとarchiveコマンドへ渡します。Pythonがシェルを使わなくても、先頭のハイフンをGitがオプションと解釈する可能性があります。[2], [3]

ステップ 3

Gitのオプション解析が想定境界を越える

この状況に適したオプションによりworkspace外へ書き込まれる可能性があります。公表された影響はプロセスが書き込み可能なファイルの作成、上書き、切り詰めであり、範囲は権限とワークフローによります。[1], [3]

ステップ 4

副作用の前に危険な参照を拒否する

0.2.0はGit、S3アップロード、Agent Space確認の前にbase_refを検証します。更新し、MCPプロセスを最小権限と隔離環境で実行してください。[1], [3], [6]

境界トレース:リビジョン文字列と Git オプション

概念的なデータフローであり、コマンド列や exploit の再現ではありません。

2つのパーサー、別々の境界

Shell の解析
引数配列を使うと、shell が値を shell 構文として解釈するのを防ぎ、この境界を閉じられます。[3]
Git オプションの解析
Git は独自のコマンドライン文法を解析します。引数配列でも、呼び出し元が制御する ref がオプションとして解釈されることは防げません。Git の実行前に検証してください。[2], [3]
1

呼び出し元がリビジョンに影響する

diff scan ツールはワークフローから base_ref を受け取ります。信頼できない入力元がこの値に影響できる場合に限り、リスクが生じます。[2], [3]

2

引数配列でも Git の解析器には届く

Python は値を個別に渡して shell parsing を避けられますが、Git は独自のコマンドラインオプションを解析します。[3], [2]

3

workspace 内に留まるという前提が崩れる

Git が値をオプションとして扱うと、ファイル出力が意図した workspace の外に及ぶ可能性があります。範囲は MCP プロセスの OS 権限に制限されます。[1], [2]

4

検証で入力境界を閉じる

0.2.0 は Git の実行や後続の副作用より前に、空またはオプション形式の ref を拒否します。呼び出し元の入力で Git のオプション動作を選べなくなりますが、有効な ref は要求されたリビジョンを引き続き選択します。[3], [6]

ソースコード比較:脆弱 vs 堅牢化

上流の呼び出し境界に絞った比較であり、scanner全体のコピーではありません。マージ済み修正はGitの前に参照を検証し、空値とハイフンで始まる値をサブプロセスやアップロードなしで拒否するテストを追加しています。引数配列はシェル解析を防ぎますが、Gitによるオプション解析は防ぎません。 この抜粋は git diff の呼び出しだけを示します。git archive を含め、base_ref を使うすべての箇所で同じ検証を行う必要があります。[3]

脆弱な実装
def start_diff_scan(path: str, base_ref: str):
    # オプションのような ref 値が検証前に Git に渡されます。
    return subprocess.run(
        ["git", "diff", base_ref, "--"],
        cwd=path,
        check=False,
    )
堅牢化されたセキュアパッチ
def _validate_git_ref(base_ref: str) -> None:
    if not base_ref or not base_ref.strip():
        raise ValueError("base_ref must not be empty.")
    if base_ref.strip().startswith("-"):
        raise ValueError("base_ref must not start with '-'.")

def start_diff_scan(path: str, base_ref: str):
    _validate_git_ref(base_ref)  # サブプロセスの起動やアップロードより前に拒否します。
    return subprocess.run(
        ["git", "diff", base_ref, "--"],
        cwd=path,
        check=False,
    )

エンジニアリング&システム堅牢化チェックリスト

参考資料