flawopen.com/Teardowns/cve-2026-25592-semantic-kernel-agent-file-write
CVE-2026-25592:Semantic Kernel のファイル書き込み
CVE-2026-25592 は Semantic Kernel のダウンロード機能を AI ツールとして公開し、ホストへの書き込みを可能にしました。モデルのアクセスを外し、1.71.0 以降へ更新してください。[2]
宅配係は、施錠された試験室から会社のオフィスへ荷物を運べます。本来は社員からの依頼だけを受けるはずですが、AI アシスタントの指示にも従う名札を付けていました。悪意あるメモで、アシスタントにオフィスの引き出しを配送先として選ばせることができます。修正では、モデルがこのヘルパーを呼び出せる名札を外します。アプリケーションから呼び出す場合も、保存先を制限する必要があります。[1], [2]
主要な概念と専門用語
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-22
根本原因の分析 (Root Cause)
.NET 版 Semantic Kernel の SessionsPythonPlugin は、リモート Python セッションとアプリケーションのホストを接続します。DownloadFileAsync はセッションからファイルを取得し、返されたバイト列をホスト上の localFilePath に保存できます。このメソッドには KernelFunction 属性が付いており、モデルがツールを選ぶ際に引数も公開されていました。攻撃者がエージェントへの入力に影響できる場合、意図しない保存先でヘルパーを呼び出させようとする可能性があります。これはツール認可とパス境界の不備であり、言語モデル自体の欠陥でも、リモート Python セッションの sandbox 脱出でもありません。Microsoft の修正は DownloadFileAsync から KernelFunction を削除し、モデルが呼び出せないようにします。アプリケーションコードがこのヘルパーを使う場合は、許可ディレクトリの明示的なポリシーを設定して強制してください。許可ディレクトリ一覧が空の場合、upstream 実装は制限なしです。GHSA-2ww3-72rp-wpp4 は NuGet の Microsoft.SemanticKernel.Plugins.Core 1.71.0 未満に加え、PyPI の semantic-kernel 1.39.3 未満も列挙しています。本記事は Microsoft が説明した .NET の攻撃経路に焦点を当てます。[1], [2], [3]
パッケージの対象範囲と修正済みバージョン
| パッケージ / 対象範囲 | 影響を受けるバージョンと修正済みバージョン | この記事で扱う内容 |
|---|---|---|
.NET Microsoft.SemanticKernel.Plugins.Core | 影響あり: < 1.71.0、修正済み: 1.71.0 以降。 | 文書化された SessionsPythonPlugin の連鎖です。モデルから呼び出せる DownloadFileAsync が、セッションデータをホスト上のパスに書き込む可能性がありました。 |
Python semantic-kernel | 影響あり: < 1.39.3、修正済み: 1.39.3 以降。 | アドバイザリにはこのパッケージも記載されています。この記事では Python 固有の攻撃経路は分析しません。Python パッケージも個別に更新してください。 |
| セッションファイルを意図的にホストへ保存するアプリ | モデルからの呼び出しをなくした後も保存先を制限します。 | Function Invocation Filter または同等の認可レイヤーで、正規化したパスの明示的な許可リストを使います。上流実装では AllowedDownloadDirectories が空だと任意の絶対パスが許可されます。 |
ステップ・バイ・ステップの攻撃フロー
ソースコード比較:脆弱 vs 堅牢化
upstream 修正では DownloadFileAsync から KernelFunction 属性を削除し、ツール登録の境界でモデルからの到達性を断ちます。メソッドのシグネチャはアプリケーションが意図的に使うために残ります。advisory は Function Invocation Filter と明示的なパス許可リストで DownloadFileAsync および UploadFileAsync の引数を検証することも推奨しています。Path.GetFullPath だけでは認可になりません。また、upstream 実装では AllowedDownloadDirectories が空だと制限がありません。[2], [3]
ソース抜粋: 対象メソッド:`SessionsPythonPlugin` の `DownloadFileAsync`
[KernelFunction, Description("Downloads a file from the current session.")]
public abstract Task<byte[]> DownloadFileAsync(
string remoteFileName,
string? localFilePath = null,
CancellationToken cancellationToken = default);
[Description("Downloads a file from the current session.")]
public abstract Task<byte[]> DownloadFileAsync(
string remoteFileName,
string? localFilePath = null,
CancellationToken cancellationToken = default);
エンジニアリング&システム堅牢化チェックリスト
- ✓Microsoft.SemanticKernel.Plugins.Core を 1.71.0 以降に更新し、プロジェクトファイルだけでなく lockfile と実行時のアセンブリも確認します。[2]
- ✓SessionsPythonPlugin を登録するエージェントを一覧化し、モデル向けツール schema に DownloadFileAsync が含まれていないことを確認します。[1], [2]
- ✓アプリケーションコードが DownloadFileAsync または UploadFileAsync を呼ぶ場合、Function Invocation Filter などで正規化済みのパス許可リストを強制します。[2]
- ✓保存先を制限する必要がある場合、AllowedDownloadDirectories を空のままにしません。upstream 実装では空のリストはすべての絶対パスを許可します。[3]
- ✓脆弱な期間のホスト上のファイル書き込み telemetry を確認し、承認ディレクトリ外へのエージェントプロセスの書き込みを調査します。露出の証拠がある場合に限り認証情報をローテーションします。
- ✓モデルに公開される登録済みツール schema とホスト権限を確認し、明示的に許可したディレクトリ外へ書き込めるエージェントツールがないことを検証してください。[1]