The Incident
On 2026-05-07, Microsoft published a coordinated retrospective on two prompt-injection-to-RCE vulnerabilities in Semantic Kernel, its open-source agent framework. CVE-2026-26030 (CVSS 9.9, CWE-94) affected the Python SDK’s InMemoryVectorStore filter, which fed an LLM-influenced filter expression into eval() inside a generated lambda; CVE-2026-25592 (CVSS 9.9, CWE-22) affected the .NET SDK’s SessionsPythonPlugin, where DownloadFileAsync and UploadFileAsync accepted attacker-controlled paths and were reachable from the model as [KernelFunction]-decorated tools. The Python flaw is patched in semantic-kernel 1.39.4 and the .NET flaw in Microsoft.SemanticKernel.Plugins.Core 1.71.0; the GitHub Security Advisories (GHSA-xjw9-4gw8-4rqx and GHSA-2ww3-72rp-wpp4) were published 2026-02-19 and 2026-02-06, with discovery credited to doredry, amiteliahu, and urioren.
The Python exploit chains a classic Python sandbox escape: a prompt-injected filter string walks ().__class__.__bases__[0].__subclasses__() to reach BuiltinImporter and from there os.system, executing arbitrary commands in the host process running the agent. The .NET exploit uses the path-traversal sink directly: a prompt that asks the agent to “save this file” can write attacker-controlled content into the host filesystem, including the user’s Startup folder, achieving persistence on the next login. There is no public evidence of in-the-wild exploitation; both findings were responsibly disclosed and patched before the May write-up.
MITRE ATT&CK coverage: T1059.006 (Command and Scripting Interpreter: Python), T1547.001 (Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder), T1059 (Command and Scripting Interpreter).
The Authority Path That Failed
The identity carrying execution authority at the moment of failure is the Semantic Kernel agent process — a non-human identity running with the host application’s full OS, filesystem, and network permissions. In CVE-2026-25592, the agent held every method the SDK had decorated [KernelFunction] plus whatever the host permitted; it exercised a write into the user’s Startup folder because DownloadFileAsync was advertised to the model as a callable tool with no path canonicalization or directory allowlist. In CVE-2026-26030, the agent held permission to evaluate filter strings inside its own Python process; it exercised eval() on an attacker-shaped expression because the default InMemoryVectorStore filter treated user-influenced strings as code, not data.
The trust anchor that failed first in both CVEs is the framework default. [KernelFunction] is a one-way gate from “internal helper” to “model-callable tool” with no second authorization layer between the developer’s annotation and the LLM’s reach. The Python filter pipeline assumes a “filter expression” is a benign DSL, not an eval argument. In each case, the gap between held scope (everything the host process can do) and exercised scope (write to Startup, spawn a shell) was statically inspectable: a tool registry diff would have shown DownloadFileAsync becoming model-callable, and a code-execution-sink inventory would have flagged a default-on plugin path that routed user input into eval.
SecurityV0 Perspective
This fits unproven_execution / ASI05. The defect is not that prompt injection happened; it is that the framework attached code-execution and filesystem-write tools to the agent that the deploying operator never explicitly authorized. The Microsoft fix patches the two specific sinks. The pattern — framework defaults that promote internal helpers into model-callable tools — outlasts the CVEs.
The evidence pack for this finding would enumerate, per Semantic Kernel agent in the environment: every [KernelFunction]-decorated method reachable from the model, the source file and commit that introduced the decorator, the host-process identity under which the agent runs, every default-loaded plugin whose code path routes user-influenced input into a code-execution sink (eval, exec, Invoke, dynamic loaders), and the package hash of each Semantic Kernel artifact. Before exfiltration, that pack answers: which [KernelFunction]s does this agent expose today, and did anyone explicitly approve them? After the fact, it answers the forensic question: which model calls reached which decorated method during the exposure window, with what arguments, and against which version of the SDK?
What To Do
- Upgrade and pin Semantic Kernel to the patched releases. Move every Python deployment to
semantic-kernel1.39.4 or later (CVE-2026-26030) and every .NET deployment toMicrosoft.SemanticKernel.Plugins.Core1.71.0 or later (CVE-2026-25592). Pin exact versions in your lock files; do not rely on a floating minor-version range to pull the patch. - Inventory every
[KernelFunction]your agents expose. Walk each agent’s plugin registration code and produce a list of the methods the SDK has advertised to the model — file path, commit, parameter types, and whether path or shell input is involved. Treat any decorated method that touches the filesystem, process spawning, or network outbound as model-callable until proven otherwise. - Block default code-execution sinks in agent data paths. Audit any plugin that routes user-influenced strings into
eval,exec,Invoke, dynamic class loading, or template engines that execute. The PythonInMemoryVectorStorefilter pattern is one example; comparable defaults exist across other agent frameworks. Replace dynamic evaluation with parsed AST whitelists or static dispatch. - Run agents under a dedicated low-privilege OS identity. A Semantic Kernel host that loads third-party plugins should not run with cloud credentials, production tokens, write access to the user’s Startup folder, or filesystem reach beyond its stated function. Move long-lived secrets out of the agent’s environment and into per-call, scope-limited issuers.
- Alert on
[KernelFunction]registry diffs andeval-adjacent sink calls. Per-build baselines of which methods are[KernelFunction]-decorated, plus EDR rules that flagpython.exe(ordotnet.exe) child processes spawning shells under a Semantic Kernel parent, turn novel tool exposure into actionable signal. A new decorated method appearing in a release diff should require operator review, not implicit acceptance.
Sources
- Microsoft Security Blog — When prompts become shells: RCE vulnerabilities in AI agent frameworks
- GitHub Security Advisory — GHSA-xjw9-4gw8-4rqx (CVE-2026-26030, Python eval RCE)
- GitHub Security Advisory — GHSA-2ww3-72rp-wpp4 (CVE-2026-25592, .NET path traversal)
- GitLab Advisory Database — CVE-2026-26030
- SentinelOne — CVE-2026-25592 vulnerability database entry
- Windows Forum — Semantic Kernel prompt-injection bugs let attackers run code or write files
- AIAgentCTF — CVE-2026-26030 reproducer (amiteliahu)
- MITRE ATT&CK: T1059, T1059.006, T1547.001