Две уязвимости высокой степени опасности, восемь — средней, две — низкой. Релиз безопасности 18 июня 2026 исправляет 12 CVE во всех трёх активных ветках Node.js. Разбираем каждую.
18 июня 2026 года команда Node.js выпустила скоординированные обновления безопасности для всех трёх активных веток — v22.23.0 (LTS), v24.17.0 (LTS) и v26.3.1 (Current), исправив в общей сложности 12 уязвимостей.
Релиз устраняет две уязвимости высокой степени опасности: целочисленное переполнение в WebCrypto AES, приводящее к аварийному завершению процесса (CVE-2026-48933), и обход аутентификации TLS через обработку Unicode-разделителей в доменных именах (CVE-2026-48618). Восемь уязвимостей средней степени включают проблемы HTTP/2 (исчерпание памяти, утечка ресурсов при GOAWAY), утечку прокси-учётных данных, обход mTLS и rebinding-атаки через встроенные NUL-символы.
Дополнительно обновлены четыре зависимые библиотеки: llhttp 9.4.2, nghttp2 1.69.0, openssl 3.5.7 и версии undici для каждой ветки.
| Ветка | Статус | Исправленная версия | undici |
|---|---|---|---|
| Node.js 22.x | Active LTS | v22.23.0 | 6.27.0 |
| Node.js 24.x | Active LTS | v24.17.0 | 7.28.0 |
| Node.js 26.x | Current | v26.3.1 | 8.5.0 |
Влияние: Ошибка в реализации WebCrypto в Node.js может аварийно завершить
процесс, если входные данные subtle.encrypt() кратны 2 Гбайт. Целочисленное
переполнение происходит во внутреннем пути шифрования AES при обработке буферов большого размера.
Вектор атаки: Любое приложение, принимающее данные от пользователя и передающее
их в crypto.subtle.encrypt() без проверки размера. Злонамеренный запрос с входными
данными размером 2 147 483 648 байт (2 Гбайт) или более вызывает целочисленное переполнение,
приводящее к segmentation fault и завершению процесса.
Затрагивает: Все поддерживаемые ветки (22.x, 24.x, 26.x).
Сообщил: erichen · Исправил: Filip Skokan
Влияние: DNS-резолвер и верификатор TLS-сертификатов в Node.js нормализуют доменные имена по-разному при обработке Unicode-разделителей (U+3002, U+FF0E и другие символы, которые нормализуются в "." при NFKC-нормализации Unicode).
Вектор атаки: Атакующий, контролирующий DNS-зону, может зарегистрировать
TLS-сертификат для доменного имени, содержащего Unicode-разделители. Резолвер интерпретирует
разделитель как обычную точку (меняя иерархию домена), а верификатор проверяет сырой символ.
Например, сертификат для *.subdomain。example.com (с U+3002) может быть принят
как валидный для трафика subdomain.example.com.
Затрагивает: Все поддерживаемые ветки (22.x, 24.x, 26.x).
Сообщил: tmeletlidis · Исправил: Matteo Collina
Когда учётные данные прокси встроены в URL (например, http://user:pass@proxy:8080),
сообщение об ошибке ERR_PROXY_TUNNEL может включать полный URL прокси с паролем.
Это раскрывает учётные данные в логах, системах мониторинга и любых потребителях объекта ошибки.
Node.js теперь маскирует учётные данные в URL прокси при формировании сообщений об ошибках. Исправил: Matteo Collina
Злонамеренный HTTP/2-сервер может отправить неограниченное количество ORIGIN-фреймов клиенту. Каждый фрейм содержит кортеж origin, который HTTP/2-клиент хранит в памяти. Без лимита атакующий может вызвать неограниченный рост памяти на клиенте, приводящий к Out of Memory.
Исправление ограничивает количество ORIGIN-фреймов, принимаемых клиентом. Исправил: Matteo Collina
Когда HTTP/2-сервер отправляет GOAWAY-фрейм, соединение должно прекратить приём новых потоков. Однако логика очистки была неполной — сервер мог продолжать обработку данных даже после сигнала завершения, позволяя клиенту исчерпать ресурсы сервера.
Важно: Уязвимость затрагивает только Node.js 22.x и 24.x. В 26.x исправление уже было внедрено. Исправил: Tim Perry
В многоконтекстных mTLS-конфигурациях TLS-серверы используют SNI (Server Name Indication) для выбора правильного контекста безопасности. Node.js выполнял регистронезависимое SNI-сопоставление на уровне сети, но регистрозависимое — при выборе контекста, создавая несоответствие.
Атакующий мог зарегистрировать сертификат для Example.com (с заглавной E),
и он применялся бы к трафику для example.com (строчная e).
Исправил: Matteo Collina
В C-строках NUL (0x00) является терминатором строки, но JavaScript-строки могут содержать
встроенные NUL-символы. DNS-резолвер Node.js обрезает доменное имя на первом NUL-байте,
а TLS-верификатор проверяет полную исходную строку. Это позволяет атакующему зарегистрировать
сертификат для example.com\0.attacker.com, который будет принят как валидный
для example.com.
Исправил: Matteo Collina
TLS session resumption позволяет пропустить полное рукопожатие при повторных соединениях. Node.js не проверял, что ServerName в возобновлённой сессии совпадает с целевым доменом. Атакующий, имеющий доступ к TLS-тикетам, мог использовать тикет для одного домена для аутентификации на другом, обходя проверку сертификатов.
Исправил: Matteo Collina
Путь валидации для диагностических отчётов (process.report.writeReport()) был
неполным, позволяя процессу записать отчёт в путь, установленный как read-only.
Исправил: RafaelGSS
Метод FileHandle.utimes() из Promises API изменяет временные метки файла.
При активном Permission Model, путь, установленный только для чтения, не защищался от
изменения метаданных через utimes(). Исправил: RafaelGSS
Permission Model в Node.js 26.x ввёл флаг --allow-net для ограничения сетевого
доступа. Однако Unix domain socket'ы не были покрыты этими ограничениями — процесс мог
запустить локальный сервер через Unix-сокет без явного сетевого разрешения. Это неполное
исправление ранней уязвимости CVE-2026-21636.
Важно: Только Node.js 26.x. Исправил: RafaelGSS
Race condition (Time-of-Check Time-of-Use) в пуле соединений http.Agent могла привести к тому, что клиент принимал ответ, отправленный до того, как клиент отправил свой запрос. В общих пулах соединений медленный запрос мог получить ответ, предназначенный для другого запроса.
Исправил: Matteo Collina
Помимо CVE в самом Node.js, релиз включает важные обновления безопасности зависимостей:
| Зависимость | Новая версия | Область |
|---|---|---|
| llhttp | 9.4.2 | Все ветки |
| nghttp2 | 1.69.0 | Все ветки |
| openssl | 3.5.7 | Все ветки |
| undici | 8.5.0 / 7.28.0 / 6.27.0 | По веткам |
nvm install 26.3.1 # или 24.17.0, 22.23.0
nvm alias default 26.3.1
# Arch Linux
sudo pacman -Syu
# Ubuntu/Debian (NodeSource)
curl -fsSL https://deb.nodesource.com/setup_26.x | sudo -E bash -
sudo apt-get install -y nodejs
# Обновите базовый образ в Dockerfile
FROM node:26.3.1-alpine # или node:24.17.0-alpine, node:22.23.0-alpine
jobs:
test:
strategy:
matrix:
node-version: ['22.23.0', '24.17.0', '26.3.1']
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
node -v
# Должно вывести: v26.3.1 (или ваша версия)
subtle.encrypt(). Отклоняйте входные данные более 1 Гбайт на уровне приложения--experimental-permission) в production, если выполняете непроверенный кодmaxSessionMemory и лимиты ресурсов для исходящих соединенийnpm audit и npm outdated в CIsubtle.encrypt() вызывает целочисленное переполнение, аварийно завершающее процесс (DoS). Исправление добавляет проверку размера входных данных перед передачей OpenSSL.nvm install 26.3.1), пакетный менеджер (apt, pacman), скачайте с nodejs.org или обновите Docker-образы. Для CI/CD обновите версию в GitHub Actions. Для production используйте pinned digest образа.subtle.encrypt(), используемые библиотеки могут зависеть от этих компонентов. Регулярное обновление Node.js — самая надёжная мера безопасности. О других типах угроз читайте в разборе атаки на цепочку поставок npm Mini Shai-Hulud.--experimental-permission. Если вы не используете Permission Model, эти уязвимости вас не затрагивают. Подробнее о модели разрешений читайте в руководстве по Permission Model в Node.js.Обновления безопасности критически важны — но правильное обновление означает тестирование совместимости, проверку зависимостей и безопасный деплой без downtime. Если вы управляете Node.js-продакшеном, свяжитесь со мной. Я предоставляю бесплатные консультации — без давления и навязывания услуг.
Расскажите о вашем проекте — я помогу оценить безопасность Node.js и спланировать обновление. Бесплатно и без обязательств.