Если приложение, сайт, интернет-магазин или API вашей компании разработаны на Node.js, включая сайты на Next.js и бэкенды на Express или NestJS, попросите разработчика сегодня же обновить Node.js до версии 22.23.4, 24.22.1 или 26.12.1, а затем пересобрать и перезапустить сервер. Проект Node.js выпустил эти версии 21 октября 2026 года, чтобы закрыть уязвимость Node2Shell (CVE-2026-111497) с оценкой 9.2 из 10: она позволяет злоумышленнику без всякого пароля выполнить код на вашем сервере, отправив специально подготовленные сжатые данные. Национальное управление кибербезопасности Саудовской Аравии (NCA) выпустило предупреждение с уровнем опасности «очень высокий», а 27 октября американское агентство по кибербезопасности CISA подтвердило, что уязвимость используется в реальных атаках.

Что именно произошло?

Уязвимость находится в Brotli — формате сжатия, с помощью которого веб-серверы и браузеры уменьшают объём передаваемых данных, а Node.js поставляется с собственной копией декодера Brotli от Google. Согласно бюллетеню безопасности Node.js, некорректные сжатые данные заставляют декодер записывать за пределы внутреннего буфера, что может привести к падению приложения, утечке содержимого его памяти или выполнению кода злоумышленником. В бюллетене сообщение об уязвимости приписано команде Codex Security из OpenAI, а тот же выпуск закрыл в общей сложности 10 уязвимостей, 4 из них — высокой степени опасности.

Дальше события развивались быстро. 22 октября, через день после исправления, Red Team компании Imperva выполнила код на официальном образе Node.js 24.22.0 двумя обычными путями: через встроенную функцию fetch() и через тела запросов, которые обрабатывает Express 5. 26 октября ELLIO зафиксировала реальный эксплойт-трафик с публичным кодом атаки. 27 октября CISA внесла уязвимость в свой каталог активно эксплуатируемых уязвимостей.

Сама ошибка давняя. Согласно записи CVE, она затрагивает версии Brotli с 1.0.3 по 1.2.0, а OpenAI говорит, что первопричину исправили в исходном коде Brotli ещё в феврале 2026 года, но никто не знал, что это уязвимость, и новой версии не выходило, пока 21 октября не появилась Brotli 1.2.1. Если это звучит знакомо, то не случайно: на прошлой неделе мы писали о PHP2Shell — уязвимости, открывшей серверы на PHP и WordPress. Node2Shell — риск того же рода для приложений на JavaScript.

Затронуто ли моё приложение?

Node.js обслуживает серверную часть значительной доли современных сайтов, бэкендов мобильных приложений, панелей управления и API. Если вашу систему в последние годы создавало агентство или фрилансер, велика вероятность, что она работает на Node.js, а вы об этом не знаете. Затронуты ветки 22.x, 24.x и 26.x до исправленных версий, а также ветки 20.x, 23.x и 25.x с истёкшей поддержкой, которые, по словам проекта Node.js, всегда уязвимы и исправления не получат.

Сам по себе Node.js ещё не делает вас уязвимым: что-то должно передать данные злоумышленника декодеру. Исследователи называют три распространённых пути:

  • Входящие сжатые запросы. Парсеры тела запроса в Express 5, body-parser 2 и Koa автоматически распаковывают тела в формате Brotli ещё до того, как запустится ваш собственный код.
  • Контент, который загружает ваш сервер. Если ваше приложение открывает внешние ссылки, например для предпросмотра ссылок, вебхуков, поисковых роботов или ИИ-агентов, читающих веб-страницы, враждебный сайт может ответить отравленными сжатыми данными. Встроенная в Node функция fetch(), axios и серверные запросы во фреймворках вроде Next.js распаковывают их автоматически.
  • Файлы, которые загружают пользователи. Любой код, распаковывающий данные Brotli, присланные клиентом или посетителем.

Риск выходит за рамки Node.js. Предупреждение NCA называет также Python, Bun и Envoy, а Microsoft 25 октября выпустила исправления для .NET 8, 9, 10 и 11, Visual Studio 2019, 2022 и 2026, а также PowerShell с 7.4 по 7.6, присвоив уязвимости статус критической для .NET с оценкой «Exploitation More Likely». Microsoft уточняет, что распаковка Brotli в .NET по умолчанию выключена, поэтому уязвимы только приложения, в которых её включили.

Если ваш сайт размещён на Vercel, компания сообщает в своём бюллетене, что в тот же день, когда Node.js опубликовал исправление, развернула для всех проектов правила файрвола, блокирующие входящий путь атаки, и что с 28 октября все новые развёртывания используют исправленный Node.js. Существующие проекты нужно развернуть заново, а проекты, которые всё ещё работают на Node.js 20, должны перейти на 22 или 24.

Что сделать сегодня: пять шагов

  1. Задайте один письменный вопрос. Какая версия Node.js работает на наших серверах и внутри наших Docker-образов? Попросите разработчика проверить номер версии Node.js командой node -v. Не полагайтесь на номер версии Brotli: ELLIO выяснила, что он показывает 1.2.0 и в исправленных, и в уязвимых сборках.
  2. Обновитесь до исправленной версии. 22.23.4, 24.22.1 или 26.12.1. Если у вас 20.x, 23.x или 25.x, перейдите на поддерживаемую ветку, например 22 или 24, и протестируйте перед запуском.
  3. Пересоберите и перезапустите. Запущенный процесс сохраняет старый код. Пересоберите образы контейнеров на исправленном базовом образе, потому что Dockerfile, закреплённый на 24.22.0, будет и дальше выпускать уязвимую сборку, пока кто-нибудь не изменит эту строку. Проверьте также тестовые серверы, конвейеры сборки и бессерверные функции.
  4. Обновите остальные копии. Пакеты Python Brotli и brotlicffi (версии 1.2.1 и 1.2.1.0), Bun, Envoy, библиотеку Brotli в вашем дистрибутиве Linux и .NET через обновление Microsoft от 25 октября.
  5. Проверьте журналы и файлы аварийных дампов. Ищите необычно большие запросы, сжатые Brotli, и повторяющиеся падения процессов. ELLIO предупреждает, что большинство неудачных атак роняют процесс, а файл аварийного дампа может содержать сессионные cookie и ключи посетителей, поэтому ограничьте круг тех, кто может читать такие файлы (core dumps), и срок их хранения.

Если обновиться сегодня не получается

В качестве временной меры заблокируйте на фронтенд-сервере или в файрволе входящие запросы с заголовком Content-Encoding: br, если вашему приложению они не нужны. Vercel и Imperva добавили правила файрвола для этой уязвимости, но сама Vercel подчёркивает, что файрвол не покрывает ответы, которые ваш сервер получает с других сайтов: этот путь закрывает только обновление Node.js. Считайте любой защитный слой выигранным временем, а не заменой обновления.

Мнение Origami

Две критические уязвимости в фундаменте веба за один месяц, сначала PHP2Shell, затем Node2Shell, рассказывают ясную историю: код, написанный вашей командой, может быть в порядке, тогда как среда выполнения под ним открыта. Исправление Node2Shell пролежало в исходном коде Brotli около восьми месяцев, прежде чем кто-то понял, что речь идёт о проблеме безопасности, а когда подробности стали публичными, исследователям понадобился один день, чтобы выполнить код на официальной сборке. Во многих компаниях мы видим приложение, сданное много лет назад, за обновления которого никто не отвечает, и никакого списка мест, где на самом деле работает Node.js. Если это ваш случай, начните этот список сегодня. В Origami мы разрабатываем веб-приложения и системы, многие из них на Node.js и Next.js, и следим за обновлениями их среды с первого дня. Если хотите проверить своё приложение или обновить Node.js без простоя, свяжитесь с нами.

Источники