Как RufRoot позволял захватить Ruflo без пароля?

Уязвимость CVE-2026-59726 с кодовым именем RufRoot получила максимальную оценку 10,0 по шкале CVSS. Она затрагивает все версии Ruflo до 3.16.3 и позволяет доступному по сети злоумышленнику без учётной записи удалённо выполнять произвольные команды. Ошибку обнаружила исследовательская команда Noma Labs компании Noma Security. Конкретная дата публикации или раскрытия уязвимости не указана.
Ruflo, первоначально выпущенный под названием Claude Flow, представляет собой открытую платформу для оркестрации нескольких ИИ-агентов и метаобвязку для Anthropic Claude Code и OpenAI Codex. С её помощью разворачивают многоагентные рои, координируют автономные рабочие процессы и создают диалоговые ИИ-системы. У проекта больше 66 500 звёзд на GitHub, поэтому небезопасная стандартная конфигурация могла попасть в довольно большое число установок.
Источником проблемы стал мост Model Context Protocol (MCP), открывавший доступ сразу к 233 инструментам. Среди них находились выполнение команд оболочки, операции с базой данных, управление агентами и сохранение памяти. Аутентификации у моста не было, а файл docker-compose.yml, точнее ruflo/docker-compose.yml, по умолчанию привязывал порт 3001 к адресу 0.0.0.0. Это означало прослушивание всех сетевых интерфейсов. Реальная доступность извне зависела от межсетевых экранов, security groups и сегментации сети, но любой достижимый по сети уязвимый экземпляр можно было атаковать без пароля.
До версии 3.16.3 стандартное развёртывание Docker Compose оставляло открытыми конечные точки POST /mcp и POST /mcp/:group. Через метод tools/call атакующий мог вызвать инструмент terminal_execute, также зарегистрированный под именем ruflo__terminal_execute, и получить оболочку внутри контейнера MCP-моста. Исследователь Эли Айнхорн (Eli Ainhorn) показал, что для этого хватало одного HTTP POST-запроса на порт 3001: команда curl обращалась к https://<target>:3001/mcp, передавала JSON с версией JSON-RPC 2.0, методом tools/call и именем ruflo__terminal_execute. В аргументе command использовалась строка id && hostname, запускавшая обе команды в уязвимой среде.
В National Vulnerability Database (NVD) Национального института стандартов и технологий США, NIST, проблема описана так: «До версии 3.16.3 стандартное развёртывание Ruflo через docker-compose открывало конечные точки MCP-моста POST /mcp и POST /mcp/:group без аутентификации, позволяя неаутентифицированному сетевому злоумышленнику вызвать tools/call для terminal_execute, получить оболочку в контейнере моста, прочитать API-ключи провайдеров и отравить шаблоны хранилища обучения AgentDB». Цепочка атаки была короткой: добраться до MCP-моста, отправить запрос без проверки личности, вызвать tools/call, запустить terminal_execute и перейти к краже данных либо изменению памяти.
После получения оболочки атакующий мог прочитать из переменных окружения контейнера все API-ключи, которыми Ruflo обращался к поставщикам больших языковых моделей. Под угрозой оказывались пользовательские разговоры и содержимое MongoDB, если база также была опубликована без аутентификации. Похищенные ключи давали возможность создавать подконтрольные атакующему рои агентов и оплачивать их работу за счёт владельца взломанной установки. Сами агенты при этом выполняли бы выбранные злоумышленником действия.
Отдельная опасность связана с постоянной памятью платформы. Получив доступ к AgentDB learning store, атакующий мог добавлять вредоносные записи agentdb_pattern-store. Сохранённые там шаблоны способны менять последующие ответы и поведение агентов для будущих пользователей, причём влияние сохраняется после завершения первоначального вторжения. Noma Security сформулировала риск прямо: «Уязвимость Ruflo позволяла развернуть рой агентов, способных делать всё, что хотел атакующий, и даже вмешиваться в память ИИ». Ещё одно предупреждение компании звучит так: «Возможность записывать вредоносные инструкции в постоянную память ИИ-платформы означает, что атакующий может воздействовать на ответы, которые ИИ будет давать каждому будущему пользователю платформы, ещё долго после окончания первоначального вторжения».
Компрометация могла пережить обычный перезапуск сервиса. Злоумышленник имел возможность записать вредоносную нагрузку в каталог /app и оставить постоянный бэкдор. Полный набор последствий включал удалённое выполнение кода, кражу LLM API-ключей, использование агентов в чужих целях, отравление памяти ИИ, выгрузку разговоров и закрепление в системе. Поэтому простая установка обновления не устраняет украденные секреты, изменённые данные MongoDB, подмешанные шаблоны AgentDB или уже размещённые файлы.
Человек, указанный в материалах только как Cohen, без полного имени и должности, описал небезопасные настройки следующим образом: «MCP-мост, поставлявшийся в ruflo/docker-compose.yml, открывал POST /mcp без аутентификации. Стандартные настройки docker-compose привязывали мост и MongoDB ко всем интерфейсам». По его словам, сочетание этих настроек позволяло вызвать tools/call → terminal_execute, получить оболочку в контейнере, прочитать каждый ключ провайдера из окружения, запустить рои на средства жертвы и внедрить отравленный шаблон в хранилище обучения AgentDB для изменения будущих ответов ИИ.
В Ruflo 3.16.3 разработчики изменили стандартную привязку MCP-моста: теперь он слушает loopback-интерфейс, а не все сетевые интерфейсы. Инструмент terminal_execute ограничен серверными механизмами executeTool. Для MongoDB включена аутентификация, чтобы снизить риск кражи разговоров. В выпуск также вошли другие изменения безопасности, подробности которых не перечислены.
Владельцам доступных по сети установок следует обновиться до 3.16.3 или более новой версии, закрыть внешние подключения к портам 3001 и 27017, а все API-ключи LLM-провайдеров считать скомпрометированными и заменить. Нужно проверить MongoDB на чтение, изменение и хищение разговоров, просмотреть AgentDB и записи agentdb_pattern-store, а также исследовать постоянную память на внедрённые инструкции. Контейнеры безопаснее пересобрать из доверенного чистого образа, отдельно проверив каталог /app и другие доступные для записи места на наличие полезной нагрузки и бэкдоров.


Новое на сайте

Ссылка