CVSS 10.0 в Flowise: архитектурный долг low-code платформ
NVD опубликовала CVE-2025-59528 полгода назад. CVSS 10.0... максимум из возможного. Уязвимость в Flowise, open-source-платформе для визуальной сборки LLM-агентов на 52 тысячах звёзд GitHub. Shodan показывает 12 000+ публичных инстансов. По сообщениям независимых исследователей, эксплойт уже в активной работе.
Проблема в Custom Function Node (блоке, куда пользователь вписывает JavaScript для дополнительной обработки данных). Flowise парсит этот код и передаёт его прямо в конструктор Function(), который выполняет его на сервере с правами основного процесса. Нет песочницы. Нет контроля над доступом к модулям типа fs, child_process, http. Кто может редактировать функцию - фактически имеет shell на хосте.
Для low-code-стека это не исключение, а системный паттерн. Скорость сборки достигается тем, что платформа запускает ваш код как свой собственный. В прототипе это удобно. В production, подключённом к интернету, это 10.0 по умолчанию. Flowise первым попал в заголовки. Архитектурно рядом стоят Langflow, Dify и ещё десяток аналогов с той же механикой.
Как работает уязвимость: от прототипа к RCE
Представьте: вы собираете LLM-пайплайн в Flowise. На этапе интеграции нужно обогатить данные - перед отправкой в модель пропустить ответ ассистента через свою логику. Вы кликаете на Custom Function Node и пишете:
Это работает. Возвращает содержимое /etc/passwd. Потому что Flowise не валидирует, что вы пишете. Он берёт строку, помещает её в конструктор Function(), и она исполняется в контексте Node.js основного процесса. Доступ неограничен.
Это не баг кода. Это дизайн. Вспомните, как работает eval() в Python или eval() в JavaScript - они выполняют код со всеми правами текущего процесса. Flowise неявно сделал это по умолчанию, потому что для быстрой сборки прототипов удобнее всего дать пользователю полный доступ к Node.js API.
Вектор атаки прямой: если у вас есть доступ к редактированию Custom Function Node (а это может быть любой член команды с правом DevOps), вы можете:
- читать переменные окружения (API-ключи, DB пароли, auth tokens)
- писать на диск (закидывать бэкдоры, логировать трафик)
- запускать внешние команды (child_process.exec())
- открывать сетевые соединения (reverse shell, data exfil)
- всё это незаметно для логов основного приложения
Почему CVSS ровно 10.0? Потому что вектор атаки сетевой (AV:N), сложность минимальна (AC:L), привилегии не требуются (PR:N), взаимодействие пользователя не требуется (UI:N), воздействие охватывает систему (S:C), и impact максимален по всем трём осям: confidentiality:H, integrity:H, availability:H. Это определение критичности по стандарту CVSS v3.1.
Патч вышел в версии 3.0.6: Flowise добавил валидацию синтаксиса и ограничил доступ к опасным модулям. Но это остановило только отсутствие - защиту от произвольного кода в Custom Function Node. Архитектурный долг остался.
Почему это структурная проблема low-code платформ
Low-code-платформы дают x10 прирост скорости разработки: вместо дня интеграции - 15 минут в редакторе. Плата за это - архитектурный компромисс: платформа запускает ваш код как свой собственный.
Проприетарные игроки отвалили ресурсы на sandbox. N8n запускает JavaScript-ноды в изолированной среде (V8 контекст, отдельный от основного процесса). Zapier добавил сигнатуры и rate-limiting. Минус: 10-15% медленнее. Плюс: безопаснее.
Open-source не может себе это позволить. Sandbox требует инфры (контейнеры, VM, процесс-изоляция), security-инженеров (постоянный аудит, каждый releasе), отказ от 5-10% производительности. Ресурсов нет.
Flowise выбрал по-другому: скорость прототипирования > безопасность по умолчанию. Честный выбор. До версии 3.0.6 об этом не было ни слова. После CVE вдруг появился в документации (и то мелким шрифтом).
Langflow и Dify архитектурно в той же позе. Оба позволяют писать код прямо в ноды, оба выполняют его без изоляции, если ноды работают на сервере. У них нет контейнеров с sandbox'ом на уровне облака.
Вывод не в том, что все они небезопасны. Вывод в том, что небезопасность - дефолт. Её нужно явно отключить через развёртывание: VPN, private network, ограничение редактирования.
Что проверить за час
Если у вас есть Flowise в production или в near-production, вот пять проверок, которые уменьшат risk на две трети.
Проверка доступа: кто может редактировать функции
Первое: на какой сети сидит Flowise? Если на публичном IP - это уже сценарий, где каждый может попытаться войти. Проверьте: есть ли аутентификация перед редактором? Flowise имеет встроенную auth, но она не включена по умолчанию. Зайдите на /admin - если не просит пароль, немедленно включите auth через переменную окружения FLOWISE_USERNAME и FLOWISE_PASSWORD.
Второе: кто именно имеет доступ редактировать Custom Function Node? Должен быть список из одного-двух человек, не вся DevOps-команда. Проверьте роли в Flowise (если используется). Если ролей нет - это означает, что любой, кто зашёл в админ-панель, может поменять код. Зафиксируйте это в риск-реестре.
Третье: поставьте Flowise за VPN или приватный endpoint облака (AWS PrivateLink, Cloudflare Tunnel, локальный балансер с базовой auth). Это затрёт risk-profile с публичного интернета. Даже если уязвимость выловят боты, они не смогут добраться до инстанса.
Проверка содержимого: что скрывается в функциях
Откройте каждую Custom Function Node и посмотрите на код. Ищите:
- process.env без явной список whitelistнованных переменных. Если функция имеет доступ ко всем env, а там лежат API-ключи, это тихая бомба.
- require('fs'), require('child_process'), require('http'). Эти модули - пути к данным и к командам. Они должны использоваться редко и явно задокументированы.
- eval(), Function() (хотя сам Flowise их использует, пользовательский код не должен их переизобретать).
- External require() - код вроде require('/path/to/local/script.js') или npm-модули, которые не в package.json.
Если нашли опасный код, переместите его в dedicated сервис вне Flowise. Используйте Flowise как оркестратор, а опасные операции пустите через отдельный API с изоляцией.
Четвёртое: логирование. Flowise 3.0.6+ имеет встроенный audit log. Проверьте уровень детализации: должны быть timestamp, user, IP, что изменилось. Нет логов? Добавьте прокси-слой (nginx/haproxy) с логированием POST-запросов к /api/v1/nodes.
Три стратегии
Прямо сейчас
Обновитесь на 3.0.6+. Патч уже в npm, не нужно компилировать. Скажите DevOps: обновление не опциональное, критичное.
Заодно проверьте Shodan: есть ли ваш домен в индексе как Flowise. Если да, ваш инстанс светит на весь интернет. Это первый шаг к RCE - убрать из публичного доступа.
Потом 30 минут на audit Custom Function Nodes. Не переписывать, просто понять: что там живёт?
На неделе
Переведите инстанс за VPN (или AWS PrivateLink, если есть). Cloudflare Tunnel - 20 минут, стоит ноль денег. После этого хотя бы ввести пароль надо будет, прежде чем трогать код.
Ограничьте edit-доступ максимум двум людям. Если Flowise не даёт roles, просто записьте: «только DevLead трогает функции». Остальные могут смотреть и запускать, но не редактировать. Один скомпрометированный GitHub-аккаунт не должен сломать весь инстанс.
Логирование. Если встроенный audit log (3.0.6+), включите на maximum. Если нет, добавьте прокси (nginx/haproxy). Минимум: знайте когда и кто менял код.
Месячный план
Если Flowise - core production (критично для бизнеса), начните планировать побег. Переход на LangChain + FastAPI, где функции выполняются в isolated containers. Дольше, чем low-code, но безопаснее.
Если Flowise - для прототипирования и нет критичных данных, можете оставить. При условии: актуальная версия + за VPN + двое редакторов + логирование. Это разумный компромисс.
Что это значит для отрасли
Low-code решает настоящую проблему: x10 скорость против кода. Это ценность, не маркетинг.
Плата за эту скорость: архитектурный долг. Платформа запускает ваш код как свой собственный. Flowise об этом не кричит, и вот результат: 12 тысяч инстансов на публичном IP без пароля = 12 тысяч потенциальных RCE.
Проблема не в Flowise конкретно, а в целом классе инструментов. Любая low-code/no-code платформа с функцией «выполнить произвольный код» (Langflow, Dify, Make, webhook-платформы) по дизайну небезопасна по умолчанию.
Два вопроса, которые надо задать о любом таком инструменте:
- Может ли выполнять произвольный код?
- Сидит на публичном IP?
Если да на оба - безопасность полностью зависит от трёх контролей: пароль, кто редактирует, логи. Если забыли хотя бы один - готовьтесь к неприятности.
Действие на эту неделю
Если у вас есть Flowise в production, ближайший час стоит посвятить проверке: версия ≥ 3.0.6? Сидит за VPN или в private network? Кто имеет доступ редактировать функции?
Три простых ответа на эти вопросы снизят risk on an order of magnitude. И после этого вы можете вернуться к сборке. Потому что для прототипирования LLM-интеграций Flowise остаётся удобным инструментом. Просто не доверяйте ему production без защиты.
Источники
- NVD CVE-2025-59528 (Tier 1)
- Flowise GitHub Repository (Tier 1)
- HackerNews дискуссия по CVE (Tier 2)
- Bruteforce Labs security report (Tier 2)
Больше разборов AI для бизнеса - в Telegram: Telegram