executeDeployment extra vars による OS コマンドインジェクションspawn(cmd[0], cmd.slice(1), { shell: true }) は、引数配列をエスケープせずに単一の /bin/sh -c 文字列へ再結合するため、executeDeployment MCP ツールに渡された extraVars 値内のシェルメタキャラクターが、サーバーが実行されているホスト上で実行されてしまいます。
この問題は修正済みです。2.0.3 以降にアップグレードしてください。
MCP ツールの引数は攻撃者の影響を受けます。これらはエージェントが処理するコンテンツ(ドキュメント、Web ページ、ツール出力)から LLM によって生成されるため、間接的なプロンプトインジェクションにより、攻撃者はツールハンドラーが受け取る値を制御できます。それらの値のいずれかをシェルに渡すハンドラーは、その影響を MCP サーバーが実行されているホスト上でのコード実行へと変えます。これは、先行事例である aws-mcp-server / CVE-2026-5058 と同じモデルです。
その結果、「呼び出し元は信頼できる LLM である」ということは緩和策にはなりません。ツールの引数は信頼できない入力です。
2.0.0 の src/helpers/runAnsible.ts は引数配列を構築し、シェルを有効にして実行していました:
const proc = spawn(ansibleCmd[0], ansibleCmd.slice(1), { shell: true });
shell: true の場合、Node は残りの要素を argv として ansibleCmd[0] を実行しません。配列全体を 1 つの文字列に結合し、要素にクォートやエスケープを適用せずに /bin/sh -c へ渡します。したがって、;、&&、|、バッククォート、$() を含む要素は、意図されたコマンドから抜け出してしまいます。
到達可能な経路は executeDeployment MCP ツール(src/tools/executeDeployment.ts)です。このツールは、呼び出し元が指定した extraVars を --extra-vars key=value として配列に転送します。; touch /tmp/marker ; という値は次のようになります:
/bin/sh -c "ansible-playbook -i inv.ini play.yml ... --extra-vars deploy_env=; touch /tmp/marker ; echo INJECTED"
同じバージョンの別のシンクは、projectRoot を execSync('ansible-vault encrypt ' + vaultPath) に補間していました。
poc/driver.mjs は、細工された extraVars 値で runAnsible を直接呼び出し、マーカーファイルを確認します。ansible-playbook がインストールされている必要はありません。先頭のバイナリが解決されるかどうかに関係なく、インジェクションされたコマンドは同じ /bin/sh -c 文字列内で実行されるためです。
npm pack @webfer/[email protected] && tar xf webfer-mcp-ansible-drupal-2.0.0.tgz
node poc/driver.mjs
影響を受けるバージョンでの期待される出力:
{"target":"@webfer/mcp-ansible-drupal 2.0.0","sink":"runAnsible -> spawn(cmd[0], cmd.slice(1), {shell:true})","vector":"executeDeployment extraVars value","marker":"/tmp/PWNED_ansible","created":true,"verdict":"CONFIRMED - command injection executed"}
2026-06-01 に隔離されたコンテナで検証し、2026-06-13 に無害な touch マーカーで再検証しました。テストを許可されたインフラストラクチャに対してのみ実行してください。
;、&&、||、|、バッククォート、$( のいずれかを含む、ansible-playbook に到達する --extra-vars 値。正当な Ansible 変数値にこれらが含まれることはほぼありません。ansible-playbook と、セパレーターに続く 2 番目のコマンドを含む sh -c プロセス — アプリケーションのログに依存しないプロセスツリーのシグナル(auditd、eBPF、Falco、EDR)ansible-playbook、git、ansible-vault は想定されますが、シェル、インタープリター、ネットワーククライアントは想定されません。executeDeployment の引数にシェルメタキャラクターが含まれる MCP ツール呼び出しログ。ツールの引数をログに記録してください — ほとんどの MCP デプロイメントは記録しておらず、アプリケーション上でインジェクションされた値が見える唯一の場所です。MITRE ATT&CK T1059.004 コマンドおよびスクリプトインタープリター: Unix シェル。
@webfer/mcp-ansible-drupal 2.0.3 以降にアップグレードしてください。 現在のソースは shell オプションなしで spawn(ansibleCmd[0], ansibleCmd.slice(1), { … }) を呼び出すため、配列は argv として渡され、メタキャラクターはその意味を失います。
MCP ツールハンドラーに関する一般則、そして今回の修正が適用している内容は次のとおりです:
shell: true を有効にしないでください。配列形式はまさにシェルを回避するために存在します。execFile/spawn を使用してください。z.string() は値が文字列であることを証明するだけで、その中身については何も証明しません。値のセットが既知の場合は許可リストを使用し、既知でない場合はシェルメタキャラクターを拒否してください。NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; CWE-78 の緩和策 M1 および M2。
| 日付 | 内容 |
|---|---|
| 2026-06-01 | 脆弱性を 2.0.0 に対して動的に検証 |
aws-mcp-server)同じ調査パスからの関連アドバイザリ: CVE-2026-52616、CVE-2026-52617。
MIT — LICENSE を参照してください。
| CVE | CVE-2026-52618 |
| CWE | CWE-78 (OS コマンドに使用される特殊要素の不適切な無害化) |
| Package | @webfer/mcp-ansible-drupal (npm) |
| Affected | 2.0.0 |
| Fixed in | 2.0.3 (公開日: 2026-06-01) |
| CVSS v3.1 | AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 7.8 High (stdio トランスポート)。サーバーがネットワークトランスポートでラップされている場合、AV:N → 9.8 Critical。 |
| Reported by | s1ko (github.com/s1ko, [email protected]) |
| CVE assigned | 2026-07-13、MITRE CNA-LR |
| 2026-06-01 |
shell: true を削除した 2.0.3 を npm に公開 |
| 2026-06-13 | 2 台目のホストで再検証 |
| 2026-07-13 | MITRE CNA-LR が CVE-2026-52618 を割り当て、発見者として s1ko をクレジット |
| 2026-08-22 | 本レポートを公開 |