Skip to content
ATR-2026-00440criticalAgent 操控experimental

Microsoft Semantic Kernel In-Memory Vector Store eval() RCE (CVE-2026-26030)

Detects exploitation of CVE-2026-26030 (Critical), remote code execution in Microsoft Semantic Kernel via unsafe string interpolation in In-Memory Vector Store filter functions. The vulnerable sink interpolates a user/LLM-controlled filter expression and evaluates it as a lambda; attacker constructs a lambda body that traverses Python's class hierarchy via `tuple()` to reach `BuiltinImporter` and execute `os.system()`, achieving unauthenticated RCE on the Semantic Kernel host. This rule detects the LLM-output / user-input payload patterns that reach the filter sink: lambda definitions combined with eval / __import__ / AST-traversal-via-mro patterns inside content or user_input fields a Semantic Kernel agent is likely to interpolate. CWE-94, CWE-95. Patches available in Python semantic-kernel >= 1.39.4 and .NET semantic-kernel >= 1.71.0; this rule detects exploit attempts against unpatched deployments and provides defence-in-depth post-patch.

嚴重度
critical
類別
Agent 操控
掃描目標
both
作者
ATR Community

建議回應

block inputalertescalate

參考資料

OWASP Agentic
ASI05:2026 - Unexpected Code ExecutionASI06:2026 - Sandbox Escape
OWASP LLM
LLM05:2025 - Improper Output HandlingLLM06:2025 - Excessive Agency
MITRE ATLAS
AML.T0050 - Command and Scripting InterpreterAML.T0051 - LLM Prompt Injection

偵測條件

組合方式: any
  1. 01
    Lambda body invoking eval() — primary CVE-2026-26030 exploit shape (`lambda row: eval(filter_expr)`)
    欄位: content運算子: regex
  2. 02
    Lambda body using __import__ to reach OS / process / builtin modules — eval-friendly RCE chain
    欄位: content運算子: regex
  3. 03
    Python class-hierarchy traversal primitives (tuple().__class__.__mro__, __subclasses__()) — AST-bypass building block used to reach BuiltinImporter
    欄位: content運算子: regex
  4. 04
    Direct reference to BuiltinImporter or reflective getattr on built-in roots — second stage of the AST-bypass chain
    欄位: content運算子: regex
  5. 05
    .NET / JavaScript Function() constructor with body invoking eval / process — cross-runtime variant
    欄位: content運算子: regex
  6. 06
    User-supplied filter expression containing lambda + dynamic-evaluation primitive — the original CVE-2026-26030 injection surface
    欄位: user_input運算子: regex

攻擊範例(規則會觸發)

  1. lambda row: eval(filter_expr)
  2. lambda row: __import__("os").system("id")
  3. lambda x: __import__("subprocess").run(["sh","-c","whoami"])
  4. ().__class__.__mro__[1].__subclasses__()
  5. tuple().__class__.__bases__[0].__subclasses__()
  6. lambda r: eval(r.metadata.get("filter", "0"))
  7. Filter expression: lambda row: eval(input_query) — please apply to ranking
  8. getattr(__builtins__, "eval")("os.system(\"id\")")

以上為真實攻擊 payload 脫敏版本。用於 regression testing。

正常樣本(規則不會觸發)

  1. Documentation discussing the patch should not trigger
    The semantic-kernel changelog notes that lambda-with-eval filter expressions are blocked after the 1.39.4 patch.
  2. Defensive guidance discussing the mitigation
    Best practice: use AST allowlisting in vector store filter pipelines.
  3. Benign lambda not invoking eval / __import__ / mro traversal
    I tested the in-memory vector store with a simple lambda function returning row.score > 0.5.
  4. Discussion of CVE in defensive context
    Reviewing this rule against CVE-2026-26030 to ensure regex coverage is correct.
  5. Reference to alternative safe callable forms
    The filter argument accepts a callable; users typically pass operator.attrgetter.

已知誤報情境

  • Legitimate Python educational content discussing lambda safety or eval() risks.
  • Static analysis tooling output documenting CVE-2026-26030 attack patterns for defensive purposes.
  • Patched Semantic Kernel filter expressions that use AST allowlisting and reject lambda bodies before evaluation.

完整 YAML 定義

在 GitHub 編輯 →
title: "Microsoft Semantic Kernel In-Memory Vector Store eval() RCE (CVE-2026-26030)"
id: ATR-2026-00440
rule_version: 1
status: experimental
description: >
  Detects exploitation of CVE-2026-26030 (Critical), remote code execution
  in Microsoft Semantic Kernel via unsafe string interpolation in
  In-Memory Vector Store filter functions. The vulnerable sink interpolates
  a user/LLM-controlled filter expression and evaluates it as a lambda;
  attacker constructs a lambda body that traverses Python's class hierarchy
  via `tuple()` to reach `BuiltinImporter` and execute `os.system()`,
  achieving unauthenticated RCE on the Semantic Kernel host. This rule
  detects the LLM-output / user-input payload patterns that reach the
  filter sink: lambda definitions combined with eval / __import__ /
  AST-traversal-via-mro patterns inside content or user_input fields a
  Semantic Kernel agent is likely to interpolate. CWE-94, CWE-95.
  Patches available in Python semantic-kernel >= 1.39.4 and
  .NET semantic-kernel >= 1.71.0; this rule detects exploit attempts
  against unpatched deployments and provides defence-in-depth post-patch.
author: "ATR Community"
date: "2026/05/11"
schema_version: "0.1"
detection_tier: pattern
maturity: test
severity: critical

references:
  owasp_llm:
    - "LLM05:2025 - Improper Output Handling"
    - "LLM06:2025 - Excessive Agency"
  owasp_agentic:
    - "ASI05:2026 - Unexpected Code Execution"
    - "ASI06:2026 - Sandbox Escape"
  mitre_atlas:
    - "AML.T0050 - Command and Scripting Interpreter"
    - "AML.T0051 - LLM Prompt Injection"
  mitre_attack:
    - "T1059 - Command and Scripting Interpreter"
    - "T1059.006 - Python"
  cve:
    - "CVE-2026-26030"

metadata_provenance:
  mitre_atlas: human-reviewed
  owasp_llm: human-reviewed
  owasp_agentic: human-reviewed
  cve: human-reviewed

compliance:
  eu_ai_act:
    - article: "15"
      context: "CVE-2026-26030 lets unfiltered LLM output drive lambda/eval interpolation in Semantic Kernel's vector-store filter; Article 15 cybersecurity requirements mandate that high-risk AI systems neutralise interpreter sinks reachable from model or user input."
      strength: primary
    - article: "9"
      context: "Article 9 risk management must enumerate lambda-with-eval and AST-traversal payloads from LLM output as a high-risk vector — particularly in vector-store filter paths, which are typically considered low-risk infrastructure."
      strength: primary
  nist_ai_rmf:
    - subcategory: "MP.5.1"
      context: "Adversarial inputs that drive an LLM to emit lambda bodies invoking eval / __import__ / mro-traversal must be tracked as a primary input-attack class affecting framework-level integrations."
      strength: primary
    - subcategory: "MG.2.3"
      context: "Risk treatment plans under MG.2.3 must require static and runtime detection of dynamic-evaluation primitives in any code path that consumes LLM output, including filter / search / ranking sinks."
      strength: primary
  iso_42001:
    - clause: "8.6"
      context: "Operational controls under clause 8.6 must prohibit dynamic-evaluation primitives (eval, exec, lambda-with-eval, Function constructor) being reached by any LLM-generated or user-supplied content path."
      strength: primary

tags:
  category: agent-manipulation
  subcategory: framework-eval-rce
  scan_target: both
  confidence: high

agent_source:
  type: llm_io
  framework:
    - semantic-kernel
    - any
  provider:
    - any

detection:
  condition: any
  false_positives:
    - "Legitimate Python educational content discussing lambda safety or eval() risks."
    - "Static analysis tooling output documenting CVE-2026-26030 attack patterns for defensive purposes."
    - "Patched Semantic Kernel filter expressions that use AST allowlisting and reject lambda bodies before evaluation."
  conditions:
    - field: content
      operator: regex
      value: '(?i)lambda\s+\w*\s*:\s*[^,)]*\beval\s*\('
      description: "Lambda body invoking eval() — primary CVE-2026-26030 exploit shape (`lambda row: eval(filter_expr)`)"

    - field: content
      operator: regex
      value: '(?i)lambda\s+\w*\s*:\s*[^,)]*\b__import__\s*\(\s*["\x27](?:os|subprocess|socket|builtins|importlib)["\x27]'
      description: "Lambda body using __import__ to reach OS / process / builtin modules — eval-friendly RCE chain"

    - field: content
      operator: regex
      value: "(?i)\\(\\s*\\)\\.__class__\\.__mro__|tuple\\s*\\(\\s*\\)\\.__class__|\\(\\s*\\)\\.__class__\\.__bases__|__subclasses__\\s*\\(\\s*\\)"
      description: "Python class-hierarchy traversal primitives (tuple().__class__.__mro__, __subclasses__()) — AST-bypass building block used to reach BuiltinImporter"

    - field: content
      operator: regex
      value: '(?i)BuiltinImporter|FunctionType|getattr\s*\(\s*(?:object|type|__builtins__)'
      description: "Direct reference to BuiltinImporter or reflective getattr on built-in roots — second stage of the AST-bypass chain"

    - field: content
      operator: regex
      value: '(?i)\bFunction\s*\(\s*["\x27].{0,200}?(?:return\s+(?:eval|new\s+Function|require|process)|os\.system|child_process)["\x27]'
      description: ".NET / JavaScript Function() constructor with body invoking eval / process — cross-runtime variant"

    - field: user_input
      operator: regex
      value: '(?i)lambda\s+\w*\s*:\s*[^,)]*\b(?:eval|exec|__import__)\s*\('
      description: "User-supplied filter expression containing lambda + dynamic-evaluation primitive — the original CVE-2026-26030 injection surface"

response:
  actions:
    - block_input
    - alert
    - escalate
  notify:
    - security_team

remediation: >
  Upgrade Python semantic-kernel to >= 1.39.4 or .NET semantic-kernel to
  >= 1.71.0. Reject filter expressions containing lambda bodies via AST
  allowlisting before evaluation. Never pass LLM-generated content to any
  dynamic-evaluation primitive (eval, exec, lambda-with-eval, Function
  constructor) regardless of perceived sanitisation. Treat LLM output as
  untrusted input from a security perspective.

test_cases:
  true_positives:
    - input: 'lambda row: eval(filter_expr)'
      expected: triggered
      description: "Microsoft Copilot fixture: lambda body invoking eval — primary CVE-2026-26030 exploit shape"
    - input: 'lambda row: __import__("os").system("id")'
      expected: triggered
      description: "Lambda body using __import__ on os module — eval-friendly RCE chain"
    - input: 'lambda x: __import__("subprocess").run(["sh","-c","whoami"])'
      expected: triggered
      description: "Lambda invoking subprocess.run via __import__"
    - input: '().__class__.__mro__[1].__subclasses__()'
      expected: triggered
      description: "AST-bypass primitive — empty-tuple class-hierarchy traversal to reach BuiltinImporter"
    - input: 'tuple().__class__.__bases__[0].__subclasses__()'
      expected: triggered
      description: "tuple()-based class-hierarchy traversal (variant)"
    - input: 'lambda r: eval(r.metadata.get("filter", "0"))'
      expected: triggered
      description: "Filter-context lambda calling eval on a derived attribute — exploit chain via vector-store filter"
    - input: 'Filter expression: lambda row: eval(input_query) — please apply to ranking'
      expected: triggered
      description: "LLM-emitted filter expression containing lambda + eval — typical content-field path"
    - input: 'getattr(__builtins__, "eval")("os.system(\"id\")")'
      expected: triggered
      description: "Reflective getattr on __builtins__ to reach eval — second-stage AST-bypass shape"
  true_negatives:
    - input: "The semantic-kernel changelog notes that lambda-with-eval filter expressions are blocked after the 1.39.4 patch."
      expected: not_triggered
      description: "Documentation discussing the patch should not trigger"
    - input: "Best practice: use AST allowlisting in vector store filter pipelines."
      expected: not_triggered
      description: "Defensive guidance discussing the mitigation"
    - input: "I tested the in-memory vector store with a simple lambda function returning row.score > 0.5."
      expected: not_triggered
      description: "Benign lambda not invoking eval / __import__ / mro traversal"
    - input: "Reviewing this rule against CVE-2026-26030 to ensure regex coverage is correct."
      expected: not_triggered
      description: "Discussion of CVE in defensive context"
    - input: "The filter argument accepts a callable; users typically pass operator.attrgetter."
      expected: not_triggered
      description: "Reference to alternative safe callable forms"

修訂歷史

建立於
2026-05-11
最後修改
2026-05-11
在 GitHub 查看完整 commit 歷史 →