КИБЕРБЕЗОПАСНОСТЬ

Node2Shell: вредоносный Brotli-поток запускает код в Node.js

Node.js исправил CVE-2026-111497: специально сформированные Brotli-данные позволяли выполнить код в официальной Linux arm64-сборке.

✍️ Редакция iTech News | 24.10.2026 | ⏱ 4 мин | Источник: The Hacker News
Node2Shell: вредоносный Brotli-поток запускает код в Node.js

Исследователи Imperva добились выполнения произвольного кода в официальном образе Node.js 24.22.0 для Linux arm64, передав приложению специально сформированные данные Brotli. Уязвимость Node.js получила идентификатор CVE-2026-111497 и касается не экспериментальной сборки, а штатного рантайма — неприятная новость для команд, которые распаковывают недоверенный HTTP-трафик на бэкенде.

Проблему уже закрыли в релизе Node.js 24.22.1, выпущенном 21 октября. О демонстрации Imperva сообщает The Hacker News: исследователи назвали технику Node2Shell и показали два реалистичных пути до декодера — сжатое тело входящего HTTP-запроса и Brotli-ответ, который приложение получает через встроенный fetch().

Эксплойт не выглядит как кнопка «получить shell»: в лабораторной конфигурации Linux arm64 выполнение кода удавалось не на каждой попытке и требовало нескольких запусков. Но ключевой результат в другом. Ранее публичный proof of concept работал лишь на намеренно ослабленной тестовой сборке; на обычном Node.js автор сообщал о падении процесса и ограниченном чтении памяти, но не о рабочем RCE. Imperva смогла перейти эту границу без отладчика и без собственной сборки Node.js.

Где возникает риск

Проблемный код находится во встроенном Brotli-декодере, поэтому уязвимость Node.js затрагивает поддерживаемые ветки 22.x, 24.x и 26.x, а не только образ, на котором Imperva поставила демонстрацию. Само по себе получение HTTP-запроса обычным сервером Node.js не означает автоматическую распаковку Brotli. Опасный участок появляется, когда приложение явно вызывает декодер или подключает middleware, готовое принять сжатое тело.

Практический пример — Express 5. Его парсеры express.json(), express.urlencoded(), express.text() и express.raw() умеют обрабатывать Brotli наряду с gzip и deflate, если применены к маршруту. Imperva воспроизвела выполнение кода по пути входящего запроса в Express версий 5.0.0–5.3.0 и body-parser 2.0.0–2.3.0 при зафиксированных версиях зависимостей. Это не означает, что проверен каждый промежуточный релиз, но даёт разработчикам вполне узнаваемый сценарий: API принимает сжатый JSON от клиента, а уязвимый декодер оказывается прямо на периметре сервиса.

Второй сценарий легко недооценить. Сервис может не принимать Brotli от пользователей, но выполнять запросы к внешним API через встроенный fetch(). Если удалённый сервер или скомпрометированный промежуточный узел вернёт вредоносный Brotli-ответ, приложение всё равно дойдёт до того же декодера. Защита на входном прокси в таком случае не заменяет обновление рантайма: она видит другой участок обмена и не контролирует все исходящие запросы приложения.

Почему декодер приводит к RCE

По разбору Imperva, подготовленный поток Brotli объявлял типы блоков, которые будут использоваться при распаковке, а затем переходил к состоянию, невозможному по структуре самого потока. Уязвимый декодер принимал это не за ошибку формата, а за необходимость дочитать входные данные и продолжал работу в некорректном состоянии. В отдельном тесте с санитайзером памяти исследователи увидели запись за границы ожидаемого буфера — именно она лежит в основе дефекта.

Исправление Node.js импортирует патч из upstream-проекта Brotli: при таком недопустимом переходе декодер теперь останавливается с ошибкой формата, а не продолжает обработку. На Node.js 24.22.1 тот же набор данных был отвергнут, выполнения кода не произошло. Для инженерных команд это хороший повод проверить не только версию в package.json, но и фактический бинарник рантайма в контейнерах, базовых образах, CI-артефактах и self-hosted-окружениях. Инвентаризация npm-пакетов сама по себе может не заметить уязвимый Node binary.

Ветки Node.js 20.x и более старые уже сняты с поддержки и исправления не получат. В advisory не указан обходной путь внутри рантайма: если обновление невозможно немедленно, можно лишь сократить обработку недоверенного Brotli там, где это не ломает API. Imperva добавила сигнатуры в свой WAF, а Vercel сообщила, что 21 октября включила правила для блокировки атак во входящих запросах. Это полезный временный слой, но он не защищает от вредоносных Brotli-ответов во внешних запросах и не устраняет уязвимость Node.js.

Публичных подтверждений эксплуатации CVE-2026-111497 на 22 октября нет, однако появление работающей демонстрации для штатной сборки сокращает дистанцию между теорией и прикладной атакой. Командам с Node.js в продакшене стоит считать Brotli частью поверхности атаки, обновить поддерживаемые ветки и отдельно проверить сервисы, где сжатие включали «для экономии трафика». Детали исследования Node2Shell опубликованы в The Hacker News.

Поделиться: Telegram X LinkedIn