Уязвимость обнаружена в скриптовом движке модуля Stream в NGINX. Она затрагивает конфигурации, использующие функцию "ssl_preread" совместно с переменными на основе регулярных выражений и сложными значениями в блоках stream. Проблеме присвоен идентификатор CVE-2026-42533. В случае эксплуатации неаутентифицированный удалённый злоумышленник может вызвать аварийное завершение рабочих процессов или добиться выполнения произвольного кода.
Уязвимости CVE-2026-42533
Корень уязвимости лежит в двухэтапном механизме вычисления сложных значений в NGINX. Сначала движок рассчитывает размер буфера, необходимый для хранения результата, а затем выполняет второй проход - копирование вычисленных данных в выделенную область памяти. Если между этими этапами переменная, определённая регулярным выражением, изменяет глобальное состояние захватов, операция копирования может использовать более крупный захват, чем тот, который был учтён при расчёте длины. Это приводит к записи за границы выделенного буфера в куче.
Уязвимый фрагмент кода находится в файле "src/stream/ngx_stream_script.c" примерно в строке 940, в функции "ngx_stream_script_copy_capture_code()". Конкретный вектор атаки связан с обработкой TLS-рукопожатий до завершения TLS. При включённой опции "ssl_preread" NGINX анализирует метаданные ClientHello, в том числе Server Name Indication (SNI), и предоставляет их через переменные, например "$ssl_preread_server_name". Администраторы часто используют эти значения в директивах map, логике маршрутизации или операторах return. Если в такой конфигурации применяется регулярное выражение с безымянным захватом (например, "$1"), то содержимое захвата может измениться после того, как размер целевого буфера уже вычислен.
Злоумышленник может отправить специально сформированный TLS ClientHello с увеличенным значением SNI на открытый слушатель stream-модуля. В проверочной концепции (PoC) директива map на основе регулярного выражения оценивает SNI, а оператор return одновременно раскрывает "$1" и переменную, определённую через regex. На первом проходе выделяется небольшой буфер, однако последующее вычисление обновляет данные захвата до длинной строки, контролируемой атакующим. Затем NGINX копирует эти данные в буфер меньшего размера. Вывод AddressSanitizer подтверждает переполнение кучи: операция "memcpy" на 1000 байт в область, размер которой составлял всего 256 байт. Хотя в тесте наблюдалось только аварийное завершение рабочего процесса, повреждение кучи в сетевом процессе при определённых условиях - поведении аллокатора, защитных механизмах сборки и расположении памяти - может привести к выполнению произвольного кода.
Уязвимость представляет особую опасность, поскольку возникает до этапа аутентификации, во время обработки preread TLS. Интернет-ориентированные экземпляры NGINX, в которых настроены директивы map на основе регулярных выражений, безымянные захваты, сложные значения stream и "ssl_preread", требуют первоочередной проверки.
Обнаруженная проблема не связана с недавней уязвимостью в HTTP-модуле rewrite, однако оба случая иллюстрируют, как несогласованность состояния между этапами расчёта длины и копирования в скриптовом движке NGINX может приводить к опасным повреждениям кучи.
До появления и установки официального исправления от разработчиков NGINX организациям рекомендуется провести аудит конфигураций stream на предмет наличия "ssl_preread", regex-карт, безымянных захватов и директив, которые объединяют раскрытие захватов с динамически вычисляемыми переменными. В качестве временных мер защиты следует удалить безымянные захваты из затрагиваемых сложных значений, упростить логику на основе регулярных выражений, ограничить доступность слушателей TLS preread (например, через списки контроля доступа), а также запускать рабочие процессы NGINX с актуальными средствами аппаратной платформы - рандомизацией адресного пространства (ASLR) и сервисными учётными записями с минимальными привилегиями.
Ссылки
- https://github.com/DepthFirstDisclosures/Nginx-Rift/blob/main/CVE-2026-42533/report.md
- https://www.cve.org/CVERecord?id=CVE-2026-42533