FlawOpen

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

● CVE-2026-25592 · CVSS 9.9[2], [4] · Критический
Исследования · FlawOpen

CVE-2026-25592: запись файлов в Semantic Kernel

CVE-2026-25592 открыла модели хостовую функцию загрузки Semantic Kernel и позволила писать на хост. Удалите доступ модели и обновите пакет.[2]

💡 Простыми словами (ELI5)

Курьер может перенести посылку из закрытой тестовой комнаты в офис компании. По правилам он должен принимать поручения только от сотрудников, но его пропуск заставлял его слушаться и ИИ-помощника. Вредоносная записка могла убедить помощника выбрать офисный ящик. Исправление убирает пропуск, который позволял модели вызывать эту функцию; для вызовов из приложения всё равно нужно ограничить допустимое место назначения.[1], [2]

Ключевые понятия и термины

KernelFunction
Атрибут Semantic Kernel, который объявляет метод модели как вызываемый инструмент.[1], [2]
SessionsPythonPlugin
Плагин Semantic Kernel для взаимодействия агента с кодом в изолированном удалённом сеансе Python.[1], [2]
localFilePath
Необязательный путь назначения на хосте, передаваемый в DownloadFileAsync.[1], [2]
Список разрешённых путей
Политика, допускающая запись только внутри явно заданных канонических каталогов.[1], [2], [5]

Связи со стандартами

  • Ссылка CWE для слабого места, описанного в этом руководстве: CWE-22

Анализ первопричины

SessionsPythonPlugin в Semantic Kernel для .NET связывает удалённый сеанс Python с хостом приложения. DownloadFileAsync получает файл из сеанса и может сохранить возвращённые байты на хосте по пути localFilePath. Метод имел атрибут KernelFunction, который показывал его аргументы модели при выборе инструмента. Если злоумышленник мог повлиять на вход агента, он мог попытаться заставить его вызвать эту функцию с нежелательным путём. Это ошибка авторизации инструмента и границы файлового пути, а не дефект языковой модели и не выход из sandbox удалённого Python-сеанса. Исправление Microsoft удаляет KernelFunction из DownloadFileAsync, поэтому модель больше не может вызвать метод. Если код приложения продолжает использовать функцию, настройте и применяйте явную политику разрешённых каталогов; upstream-реализация разрешает любые пути, если список пуст. GHSA-2ww3-72rp-wpp4 указывает версии NuGet Microsoft.SemanticKernel.Plugins.Core ниже 1.71.0, а также версии PyPI semantic-kernel ниже 1.39.3; эта статья разбирает описанную Microsoft цепочку .NET.[1], [2], [3]

Область пакетов и исправленные версии

Пакет / областьЗатронутые и исправленные версииЧто рассматривает статья
.NET Microsoft.SemanticKernel.Plugins.CoreЗатронуты версии < 1.71.0; исправлено в 1.71.0 и новее.Документированная цепочка SessionsPythonPlugin: доступный модели DownloadFileAsync мог записать данные сессии по пути на хосте.
Python semantic-kernelЗатронуты версии < 1.39.3; исправлено в 1.39.3 и новее.В рекомендации также указан этот пакет. В статье не разбирается отдельная цепочка эксплуатации Python; обновите пакет Python независимо.
Приложения, намеренно сохраняющие файлы сессии на хостеОграничьте путь назначения и после удаления доступа модели.Задайте явный список разрешённых канонических путей в Function Invocation Filter или эквивалентном слое авторизации. Пустой список AllowedDownloadDirectories в upstream-реализации разрешает любой полный путь.

Пошаговый сценарий атаки

Шаг 1

Недоверенное содержимое влияет на агента

Атакующему нужен способ повлиять на входные данные агента, например через обрабатываемое содержимое. В цепочке, описанной Microsoft, первый вызов инструмента помещает файл в изолированную удалённую сессию Python; на этом этапе файл остаётся внутри неё.[1], [2]

Шаг 2

Модель видит хостовую функцию

В уязвимых развертываниях .NET атрибут KernelFunction добавлял DownloadFileAsync в перечень инструментов, доступных модели.[1], [2]

Шаг 3

Аргументы пересекают границу доверия

Запрашивая файл из удалённого сеанса, модель могла выбрать localFilePath. Функция обрабатывала этот путь в процессе хоста.[1], [2]

Шаг 4

Становится возможна запись на хост

Запись на хост возможна, только если модель вызывает этот помощник с localFilePath, на который повлияли недоверенные данные, и путь не ограничен действующим списком разрешённых каталогов. Microsoft описывает контролируемую исследовательскую цепочку, а не массовую эксплуатацию.[1], [2]

Исходный код: Уязвимый vs Защищённый вариант

Upstream-исправление удаляет атрибут KernelFunction из DownloadFileAsync и закрывает доступ модели на уровне регистрации инструментов. Сигнатура остаётся для преднамеренного вызова из кода приложения. Advisory также рекомендует проверять аргументы DownloadFileAsync и UploadFileAsync через Function Invocation Filter и явный список разрешённых путей. Одного Path.GetFullPath недостаточно для авторизации; пустой список AllowedDownloadDirectories в upstream-реализации разрешает любой полный путь.[2], [3]

Фрагмент исходного кода: Исходный метод: `DownloadFileAsync` в `SessionsPythonPlugin`

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
[KernelFunction, Description("Downloads a file from the current session.")]
public abstract Task<byte[]> DownloadFileAsync(
    string remoteFileName,
    string? localFilePath = null,
    CancellationToken cancellationToken = default);
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
[Description("Downloads a file from the current session.")]
public abstract Task<byte[]> DownloadFileAsync(
    string remoteFileName,
    string? localFilePath = null,
    CancellationToken cancellationToken = default);

Чек-лист по защите системы для инженеров

Источники