Skip to content

Back to the catalog

When Prompts Become Shells: RCE Vulnerabilities in AI Agent Frameworks (Semantic Kernel)
microsoft.comwriteup

When Prompts Become Shells: RCE Vulnerabilities in AI Agent Frameworks (Semantic Kernel)

Microsoft discloses two CVEs in its Semantic Kernel AI agent framework: CVE-2026-26030, where AI-model-controlled input into an eval()-executed Python lambda filter (used by the In-Memory Vector Store's Search Plugin) bypasses an AST-based blocklist via class-hierarchy traversal to BuiltinImporter.load_module, achieving arbitrary code execution from a single injected prompt; and CVE-2026-25592, where the .NET SessionsPythonPlugin's DownloadFileAsync was accidentally exposed as a callable AI tool with an unsanitized file path, letting an attacker escape the Azure Container Apps sandbox and write a payload into the host's Startup folder for persistence/RCE. The post details the exploit chains (mapped to MITRE ATLAS AML.T0051→AML.T0016), Microsoft's four-layer AST allowlist fix and path-validation patch, affected version ranges, KQL hunting queries for post-exploitation detection, and a public CTF challenge to practice exploiting CVE-2026-26030.

TL;DR Microsoft found two RCE-chain CVEs in Semantic Kernel (eval() lambda-filter injection and an accidentally exposed file-write plugin) where prompt injection alone pops calc.exe on the host, plus fixes, hunting queries, and a public CTF.
Document

What it is

Two CVEs in Microsoft Semantic Kernel, disclosed as part of a new Microsoft research series probing RCE paths in AI agent frameworks (Semantic Kernel, with LangChain/CrewAI flagged for future posts). CVE-2026-26030 is a Python eval() sandbox-escape in the In-Memory Vector Store's default filter function; CVE-2026-25592 is a .NET SessionsPythonPlugin method accidentally exposed as an AI-callable tool, enabling a sandbox escape from Azure Container Apps to the host.

How it works

CVE-2026-26030: The Search Plugin's default filter is built as a Python lambda string (e.g. lambda x: x.city == 'Paris') and run through eval(). The city value is AI-model-controlled and unsanitized, so closing the quote injects arbitrary logic. The framework's AST-based guard only checked ast.Name/ast.Attribute nodes against a blocklist (eval, exec, open, __import__, etc.) and stripped __builtins__. The disclosed bypass starts from tuple() — which needs no builtins — then walks Python's class hierarchy (__class__, __subclasses__-style traversal) to reach BuiltinImporter, calls load_module to pull in os, and invokes system(). None of __name__, load_module, system, or BuiltinImporter were on the blocklist, and the check never inspected ast.Subscript nodes, so bracket-notation access (obj['__class__']) would have been an alternate bypass even if names were blocked.

CVE-2026-25592: DownloadFileAsync in the .NET SDK was tagged with [KernelFunction], exposing it as an AI-invocable tool whose localFilePath parameter (passed straight to File.WriteAllBytes()) had no path validation. Chained with ExecuteCode (writes a payload inside the sandbox) and the exposed download tool (pulls that payload to an attacker-chosen host path), a single prompt injection sequence can place a script in the host's Windows\Start Menu\Programs\Startup folder, giving code execution on next sign-in — fully escaping the Azure Container Apps isolation boundary. The page also notes a reverse arbitrary-file-read issue: upload_file() in both SDKs took unvalidated local paths, letting injected prompts exfiltrate host files (e.g., SSH keys) into the sandbox.

flowchart LR
    A[Prompt injection] --> B[ExecuteCode: write payload in sandbox]
    B --> C[DownloadFileAsync: unsanitized localFilePath]
    C --> D[Write to host Startup folder]
    D --> E[Next sign-in: RCE on host]
    F[Fix: remove KernelFunction attr] -.cuts chain at.-> C

Preconditions / Affected

  • CVE-2026-26030: semantic-kernel Python package, version prior to 1.39.4, using the In-Memory Vector Store's filter functionality as the Search Plugin backend with default configuration, plus a prompt-injection vector into agent input.
  • CVE-2026-25592: Semantic Kernel .NET SDK older than 1.71.0 using SessionsPythonPlugin.

What to do

  • Upgrade Python semantic-kernel to 1.39.4+ (no agent rewrite needed).
  • Upgrade the .NET SDK to 1.71.0+; this removes AI-model access to DownloadFileAsync (the [KernelFunction] attribute was removed) and adds ValidateLocalPathForDownload() using Path.GetFullPath() canonicalization plus directory allowlisting for developers still calling it programmatically.
  • To check for prior exploitation, bound the "vulnerable window" (deployment of an affected version until patch) and hunt endpoint telemetry in that window. Two KQL queries are given against DeviceProcessEvents: one flags Semantic Kernel–linked processes spawning cmd.exe, powershell.exe, certutil.exe, wscript.exe, bitsadmin.exe, nslookup.exe, etc.; the other filters specifically for dotnet.exe processes matching semantic[\s_\-]?kernel|SKAgent|kernel\.run spawning similar suspicious children.
  • A public CTF reproducing CVE-2026-26030 (the "hotel finder" agent, prompt-injection to calc.exe) is available at https://github.com/amiteliahu/AIAgentCTF/tree/main/CVE-2026-26030, explicitly for sandboxed/educational use only.

Caveats

The AST allowlist fix (node-type allowlist, function-call allowlist, dangerous-attribute blocklist, name-node restriction) is described as closing this specific exploit chain, but the post itself frames blocklist/allowlist approaches in dynamic languages as inherently fragile — it doesn't claim the fix is proven exhaustive against all eval-based bypasses, only that it eliminates the escape primitives used in the disclosed payload.

Organisations named here

  • BuiltinImporter

CVEs named here

  • CVE-2026-26030
  • CVE-2026-25592

Technologies named here

  • Microsoft Semantic Kernel
  • Semantic Kernel
  • LangChain
  • CrewAI
  • SessionsPythonPlugin
  • Azure Container Apps dynamic sessions
  • AIAgentCTF
  • Microsoft Defender
  • Copilot Studio Agent Builder
  • .NET
  • Python
  • Azure

Techniques named here

  • Prompt injection to tool-parameter code execution
  • AML.T0051
  • AML.T0016
  • Unsafe string interpolation into eval
  • AST blocklist bypass
  • Sandbox escape via over-exposed helper function
  • Arbitrary file read for exfiltration
  • LLM Prompt Injection
  • Obtain Capabilities