DEV Community

With Nate
With Nate

Posted on Edited on Originally published at nasdigital.co.uk

Semantic Kernel CVE-2026-25592: What You Need to Know

Correction (July 2026): an earlier version of this post gave the CVSS score as 10.0 and the disclosure date as 7 May 2026. Both were wrong — the score is 9.9 and the advisory was published on 6 February 2026. That earlier version also described only DownloadFileAsync; the advisory covers UploadFileAsync as well, and the hardening advice below has been corrected accordingly. Apologies to anyone who acted on the original.

Microsoft disclosed CVE-2026-25592, an arbitrary-file-write vulnerability in Semantic Kernel — the .NET framework used to build AI agents and LLM-powered applications. The GitHub Security Advisory (GHSA-2ww3-72rp-wpp4) was published on 6 February 2026 with a CVSS 3.1 base score of 9.9 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H).

If you've upgraded to Semantic Kernel 1.71.0, you've applied Microsoft's official fix. Many teams considered the issue closed at that point.

From a CVE perspective, they're correct.

However, the vulnerability highlights a broader security problem that can still exist in many Semantic Kernel deployments: allowing AI-controlled values to flow into privileged operations without strict validation.

This post explains what CVE-2026-25592 was, how it worked in a real .NET application, why the underlying pattern remains relevant, and what developers should be doing to secure their Semantic Kernel implementations.

Why Semantic Kernel Matters

Semantic Kernel is Microsoft's open-source orchestration framework for integrating Large Language Models into .NET applications. It provides abstractions for prompts, plugins, memory, planning, tool invocation, and agent workflows.

It is increasingly being used to power:

  • Enterprise customer support systems
  • AI-assisted business workflow automation
  • Internal knowledge management platforms
  • Intelligent data processing pipelines
  • Agentic applications connected to enterprise systems

The framework works by exposing application functionality to the LLM through "kernel functions" — methods decorated with the [KernelFunction] attribute that the model can invoke when it determines they are needed.

This capability is what makes Semantic Kernel powerful.

It is also what makes mistakes extremely dangerous.


CVE-2026-25592: The Sandbox That Wasn't

The vulnerability centered around the SessionsPythonPlugin component within Semantic Kernel's .NET SDK.

The plugin exists to allow agents to execute Python code inside an Azure Container Apps sandbox. The intended security model is straightforward: code runs inside the isolated environment and cannot directly impact the host system.

The problem was insufficient path validation in two helper methods: DownloadFileAsync and UploadFileAsync. Both were exposed to the LLM through a [KernelFunction] attribute, which turned internal helpers into AI-callable tools — and made their path parameters AI-controlled.

Path traversal sequences (../) or absolute paths could escape the intended directory and reach arbitrary locations writable by the application process.

This is the detail that matters most for remediation: fixing only DownloadFileAsync leaves you exposed. If you wrote your own mitigation based on early write-ups (including the first version of this post), check UploadFileAsync too.

An attacker who can influence any prompt consumed by the agent — a support ticket, uploaded document, SharePoint file, Teams message, RAG source, or direct user interaction — could potentially persuade the model to invoke either function with an attacker-chosen path.

For example, a path pointing at the current user's startup folder:

C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\evil.exe
Enter fullscreen mode Exit fullscreen mode

If a malicious payload is written to a startup directory, the next user login may result in code execution. That escalation from "write a file" to "run code on the host" is why the score is 9.9 rather than something lower — the scope change (S:C) reflects escaping the sandbox boundary.

Affected and fixed versions:

SDK Vulnerable Fixed in
.NET (Microsoft.SemanticKernel.Plugins.Core) < 1.71.0 1.71.0
Python < 1.39.3 1.39.3

The Broader Lesson

Microsoft's fix addresses the specific vulnerability that was reported.

However, the broader lesson extends beyond two methods.

The root problem was allowing AI-generated values to reach privileged operations without appropriate validation.

Although the reported vulnerability has been remediated, developers can unintentionally recreate the same class of issue in custom implementations.

Examples include:

  • Custom kernel functions that accept file paths
  • Functions that construct URLs
  • Database query generation
  • Command execution wrappers
  • Reflection-based operations
  • Network-access plugins
  • Internal API integrations

If a custom [KernelFunction] accepts AI-controlled input and passes it directly into operating system, database, filesystem, or network operations, the same trust-boundary problem can reappear regardless of Semantic Kernel version.

The important question is not:

"Am I running 1.71.0?"

The important question is:

"Do any of my kernel functions trust values generated by an LLM?"


Hardened Implementation Pattern

The safest approach is to avoid automatic execution of sensitive functions wherever possible.

var executionSettings = new OpenAIPromptExecutionSettings
{
    ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions
    // Avoid AutoInvokeKernelFunctions for privileged operations
};
Enter fullscreen mode Exit fullscreen mode

When functions must accept paths, validate against an allowlist rather than trying to block dangerous values. Note this pattern applies to any path-taking kernel function — upload as well as download.

private static string ResolveWithinAllowedRoot(string requested)
{
    var allowedRoot = Path.GetFullPath("/app/downloads")
        .TrimEnd(Path.DirectorySeparatorChar)
        + Path.DirectorySeparatorChar;

    // GetFileName strips any directory component, so "../../etc/passwd"
    // collapses to "passwd" before it is ever combined with the root.
    var resolved = Path.GetFullPath(
        Path.Combine(allowedRoot, Path.GetFileName(requested)));

    if (!resolved.StartsWith(allowedRoot, StringComparison.Ordinal))
    {
        throw new SecurityException($"Path traversal attempt: {requested}");
    }

    return resolved;
}

[KernelFunction]
public async Task<string> DownloadFileAsync(string localFilePath)
{
    var safePath = ResolveWithinAllowedRoot(localFilePath);
    await using var stream = File.Create(safePath);
    // ... write the downloaded content to stream ...
    return safePath;
}
Enter fullscreen mode Exit fullscreen mode

A note on the comparison: use StringComparison.Ordinal rather than OrdinalIgnoreCase unless you are certain the filesystem is case-insensitive. Getting this wrong on Linux containers can accept paths you meant to reject.

The key principle is simple:

Never trust AI-generated input simply because it originated from your own application.


Audit Every AI-Initiated Action

One of the most effective defensive controls is auditing all AI-triggered function calls.

kernel.FunctionInvocationFilters.Add(new SecurityAuditFilter());
Enter fullscreen mode Exit fullscreen mode

A security-focused invocation filter should:

  • Log every tool invocation
  • Capture relevant arguments
  • Alert on filesystem access
  • Alert on network operations
  • Alert on database modifications
  • Generate audit events for investigation

If you cannot see what your agent is doing, you cannot detect when it has been manipulated.


Human Approval Controls

Many enterprise teams rely on human-in-the-loop controls before allowing agents to perform sensitive actions.

Semantic Kernel includes mechanisms intended to support these workflows. However, developers have reported scenarios where confirmation behaviour did not align with their expectations.

For that reason, organizations with strict approval requirements should consider implementing confirmation logic explicitly at the application layer rather than relying solely on framework-level controls.

public class ConfirmationRequiredFilter : IFunctionInvocationFilter
{
    private readonly IConfirmationService _confirmationService;

    public ConfirmationRequiredFilter(IConfirmationService confirmationService)
        => _confirmationService = confirmationService;

    public async Task OnFunctionInvocationAsync(
        FunctionInvocationContext context,
        Func<FunctionInvocationContext, Task> next)
    {
        var approved = await _confirmationService
            .RequestApprovalAsync(context.Function.Name, context.Arguments);

        if (!approved)
        {
            throw new OperationCanceledException("Human approval denied.");
        }

        await next(context);
    }
}
Enter fullscreen mode Exit fullscreen mode

Immediate Actions for Production Deployments

If you're currently running Semantic Kernel in production:

1. Upgrade

.NET: 1.71.0 or later. Python: 1.39.3 or later.

2. Audit Every Kernel Function

Review every [KernelFunction] implementation and identify:

  • Filesystem operations (both read and write paths)
  • Network requests
  • Database access
  • Process execution
  • Reflection usage
  • Dynamic code generation

Treat all parameters as untrusted input.

3. Disable AutoInvoke for Sensitive Operations

Only allow automatic invocation for low-risk, read-only functions. Require explicit approval for anything that modifies systems or data.

4. Implement Allowlist Validation

Validate paths, URLs, queries, commands, and resource identifiers. Do not rely on blocklists.

5. Run With Least Privilege

Minimal filesystem permissions, restricted network access, limited IAM permissions, regular credential rotation, strong isolation where practical.

6. Monitor for Exploitation Attempts

Look for unexpected tool invocations, unusual filesystem activity, unexpected outbound traffic, and repeated failed function calls followed by success.

7. Review Historical Activity

If vulnerable versions were previously deployed: review audit logs, investigate unusual agent behaviour, check for unauthorized file modifications, and rotate secrets where appropriate.


The Bigger Picture

CVE-2026-25592 highlights a challenge facing every AI framework today.

Developers want agents that can take meaningful action. Security teams want systems that cannot be manipulated. Those goals are often in tension.

Semantic Kernel is not unique here. Similar patterns can emerge in any framework where an LLM is allowed to invoke application functionality. Whenever model-generated output crosses into privileged operations, the trust boundary becomes a security-critical control.

The industry is still learning how to secure these systems properly.


What I'm Looking At Next

These issues are only part of a much larger attack surface. Future research will focus on:

  • Azure AI Search index poisoning through SharePoint and Teams content
  • Text-to-SQL injection chains in Azure OpenAI applications
  • Secure patterns for agentic workflows
  • Building Roslyn analyzers that detect dangerous Semantic Kernel patterns at compile time

AI agents are becoming increasingly capable. The security controls protecting them need to mature just as quickly.

Until then, treat every AI-generated action as untrusted input and design your systems accordingly.


Sources: GitHub Security Advisory GHSA-2ww3-72rp-wpp4 · GitLab Advisory Database


Working with Semantic Kernel in production? The Semantic Kernel Security Audit Prompt Pack walks through the attack surfaces covered in this series, with 20 ready-to-use audit prompts for the vulnerability classes Microsoft hasn't fully addressed.

Top comments (0)