FlawOpen

flawopen.com/Teardowns/cve-2026-25592-semantic-kernel-agent-file-write

● CVE-2026-25592 · CVSS 9.9[2], [4] · Critical
FlawOpen Security Research

CVE-2026-25592: Semantic Kernel Agent File Write

CVE-2026-25592 exposed Semantic Kernel’s download helper as an AI tool, enabling host file writes. Remove model access and upgrade to 1.71.0.[2]

💡 Plain English Explainer (ELI5)

A courier can move a package from a locked test room to a company office. The courier was meant to take requests only from staff, but a name badge made the courier obey the AI assistant too. A malicious note could then persuade the assistant to choose the office drawer. The fix removes the badge that makes this helper callable by the model; host-side callers still need a restricted destination rule.[1], [2]

Core Concepts & Subsystem Terms

KernelFunction
Semantic Kernel’s attribute that advertises a method to the model as a callable tool.[1], [2]
SessionsPythonPlugin
A Semantic Kernel plugin that lets an agent interact with code running in an isolated remote Python session.[1], [2]
localFilePath
The optional host-side destination path supplied to DownloadFileAsync.[1], [2]
Path allowlist
A policy that permits writes only beneath explicitly configured, canonicalized directories.[1], [2], [5]

Framework mappings

  • CWE reference for the weakness described in this guide: CWE-22

Root Cause Analysis

Semantic Kernel’s .NET SessionsPythonPlugin bridges a remote Python session and the application host. DownloadFileAsync fetches a file from the session and can optionally save the returned bytes at localFilePath on the host. The method was decorated with KernelFunction, which exposed its arguments to model tool selection. An attacker who could influence the agent’s prompt could try to make it invoke this helper with an unintended destination. This is a tool-authorization and path-boundary failure, not a flaw in the language model or a sandbox escape inside the remote Python session. Microsoft’s patch removes KernelFunction from DownloadFileAsync so the model cannot call it. If application code still calls the helper, configure and enforce an explicit allowed-directory policy; the upstream helper is permissive when its allowed-directory list is empty. GHSA-2ww3-72rp-wpp4 lists NuGet Microsoft.SemanticKernel.Plugins.Core versions before 1.71.0 and also lists PyPI semantic-kernel versions before 1.39.3; this teardown focuses on Microsoft’s documented .NET SessionsPythonPlugin chain.[1], [2], [3]

Package scope and fixed versions

Package / scopeAffected and fixed versionsWhat this article covers
.NET Microsoft.SemanticKernel.Plugins.CoreAffected: < 1.71.0; fixed: 1.71.0 and later.The documented SessionsPythonPlugin chain: model-callable DownloadFileAsync could write session data to a host path.
Python semantic-kernelAffected: < 1.39.3; fixed: 1.39.3 and later.The advisory lists this package too. This page does not analyze a Python-specific exploit path; upgrade the Python package independently.
Applications that intentionally save session files on the hostKeep the destination constrained even after removing model reachability.Use an explicit canonical-path allowlist in a Function Invocation Filter or equivalent authorization layer. An empty AllowedDownloadDirectories list is permissive in the upstream implementation.

Step-by-Step Attack Flow

Step 1

Untrusted content influences the agent

An attacker needs a way to influence the agent’s input, such as content it is asked to process. In Microsoft’s documented chain, the first tool call places a file in the isolated remote Python session; that file remains contained at this stage.[1], [2]

Step 2

The model sees a host-side helper

In affected .NET deployments, KernelFunction made DownloadFileAsync part of the model’s callable tool surface.[1], [2]

Step 3

Tool arguments cross the trust boundary

The model could select localFilePath while requesting a file from its remote session. The helper then handled that path in the host process.[1], [2]

Step 4

Host write becomes possible

A host write requires the model to call this helper with a localFilePath influenced by untrusted input and outside any enforced allowed directory. Microsoft describes a controlled research chain, not widespread exploitation.[1], [2]

Source Code: Flaw vs. Secure Implementation

The upstream patch removes the KernelFunction attribute from DownloadFileAsync, breaking model reachability at the tool-registration boundary. The signature is retained for intentional application-side use. The advisory separately recommends validating DownloadFileAsync and UploadFileAsync arguments with a Function Invocation Filter and an explicit path allowlist. Do not treat Path.GetFullPath alone as an authorization policy, and note that an empty AllowedDownloadDirectories collection is permissive in the upstream implementation.[2], [3]

Source excerpt: dotnet/src/Plugins/Plugins.Core/CodeInterpreter/SessionsPythonPlugin.cs — DownloadFileAsync

UNPATCHED FLAW
[KernelFunction, Description("Downloads a file from the current session.")]
public abstract Task<byte[]> DownloadFileAsync(
    string remoteFileName,
    string? localFilePath = null,
    CancellationToken cancellationToken = default);
HARDENED SECURE PATCH
[Description("Downloads a file from the current session.")]
public abstract Task<byte[]> DownloadFileAsync(
    string remoteFileName,
    string? localFilePath = null,
    CancellationToken cancellationToken = default);

Engineering & System Hardening Checklist

Sources