FlawOpen

flawopen.com/AI Security/semantic-kernel-inmemory-vector-filter-cve-2026-26030

● CVE-2026-26030 · CVSS 9.9[1] · 緊急
セキュリティ研究 · FlawOpen

Semantic Kernel CVE-2026-26030:フィルターのコード注入

プロンプトの影響を受けるベクトルフィルターがAST検査を回避し、Python evalに到達しました。1.39.4以降へ更新してください。[1], [4]

CVSS ベクトルCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H[1]
💡 わかりやすい解説 (ELI5)

検索規則のカードを受け取った司書が、見慣れた語を確認してからカード全体を小さなプログラムとして実行するようコンピューターに頼む場面を想像してください。カードに影響を与えられる人は検査の抜け道を利用できます。CVE-2026-26030では、モデルの影響を受けたフィルターが検索からアプリケーション内のコード実行へ進む可能性がありました。[4]

主要な概念と専門用語

InMemoryVectorStore
Semantic Kernelプロセス内のベクトルストア。検索結果を返す前にレコードを絞り込めます。[4]
Filter expression
ベクトル検索結果にレコードを含めるか決める条件式。影響を受けたPython経路では文字列をPython式として解析・評価していました。[4]
Abstract Syntax Tree (AST)
解析したコードの構造化表現です。不完全なAST検査はPythonオブジェクトのイントロスペクション経路を残すことがあります。[2], [4]
Prompt injection
信頼できないテキストがAIモデルに影響し、意図しない操作を促します。アプリケーションがモデル入力を脆弱なフィルターへ渡す場合にリスクが生じます。[4]

フレームワーク対応

  • このガイドで説明する弱点の CWE 参照: CWE-94

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

ステップ 1

脆弱なフィルター経路をデプロイ

Semantic Kernel Python 1.39.4未満とInMemoryVectorStoreフィルター機能が対象です。MicrosoftはCritical(CVSS 3.1 9.9、CWE-94)と評価し、1.39.4以降への更新を案内しています。[1], [4]

ステップ 2

信頼できない内容がモデル選択フィルターに影響

攻撃にはエージェント入力に影響するプロンプトインジェクション経路と、既定フィルターを使うSearch Pluginが必要です。型付きツール呼び出しでもモデル生成フィルターは信頼できません。[4]

ステップ 3

フィルターがPythonコードになる

修正前はフィルターをASTとして解析し、builtinsを除いて評価していましたが、オブジェクトモデルの走査を十分に制限できていませんでした。1.39.4ではレコード項目へのアクセス用にast.Subscriptを残しつつ、ASTノードの許可リスト、危険な属性の拒否、単独名をlambda引数に限定する検査、呼び出し関数の許可リストを組み合わせます。上流コードは添字を単独では拒否しません。builtinsを除いたevalもサンドボックスではありません。[2], [4]

ステップ 4

実行がアプリケーションプロセスへ到達

検証を回避した式はエージェントのPythonプロセスで実行される可能性があります。影響はOS権限、環境、資格情報、ネットワーク到達性に左右されます。[4]

ステップ 5

パーサー境界を修正して露出を調査

semantic-kernelを1.39.4以降へ更新してください。パッチは危険な属性を検査し、名前をlambda引数に制限します。対象期間のプロセス、ネットワーク、資格情報の異常も調査します。[1], [2], [3], [4]

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

脆弱な側は製品の実ソースではなく代表例です。モデル制御の値がeval前にPython構文へ補間されます。修正版はupstream 1.39.4の検査を抜粋しています。設定されたAST許可リストにはレコード項目へのアクセス用にast.Subscriptが含まれ、危険な属性の拒否、単独名をlambda引数に限定する検査、許可された呼び出しの確認と組み合わせます。builtinsを除いてもevalはサンドボックスになりません。パッケージを更新し、この抜粋を単独のバリデーターとしてコピーしないでください。[2], [6], [4]

脆弱な実装
# 修正前の代表例:モデル制御テキストが式を変えてしまいます。
filter_text = f"lambda x: x.city == '{model_selected_city}'"
tree = ast.parse(filter_text, mode="eval")
code = compile(tree, filename="<filter>", mode="eval")
filter_fn = eval(code, {"__builtins__": {}}, {})  # nosec
堅牢化されたセキュアパッチ
def validate_filter(self, tree):
    # upstream 1.39.4の主要な検査。例外メッセージは短縮しています。
    # トップレベルのフィルターはlambda式である必要があります。
    if not (isinstance(tree, ast.Expression) and isinstance(tree.body, ast.Lambda)):
        raise VectorStoreOperationException("Filter must be a lambda expression")

    lambda_param_names = {arg.arg for arg in tree.body.args.args}
    for node in ast.walk(tree):
        if type(node) not in self.allowed_filter_ast_nodes:
            raise VectorStoreOperationException("AST node type is not allowed")

        if isinstance(node, ast.Attribute) and node.attr in self.blocked_filter_attributes:
            raise VectorStoreOperationException("Dangerous attribute is not allowed")

        if isinstance(node, ast.Name) and node.id not in lambda_param_names:
            raise VectorStoreOperationException("Only lambda parameter names are allowed")

        if isinstance(node, ast.Call):
            if isinstance(node.func, ast.Name):
                func_name = node.func.id
            elif isinstance(node.func, ast.Attribute):
                func_name = node.func.attr
            else:
                func_name = None
            if func_name and func_name not in self.allowed_filter_functions:
                raise VectorStoreOperationException("Function is not allowed")

    code = compile(tree, filename="<filter>", mode="eval")
    func = eval(code, {"__builtins__": {}}, {})  # nosec

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

参考資料

← AI Security Directory →