Apache HTTP/2 CVE-2026-23918: double-free и рабочий RCE-PoC

Apache Software Foundation выпустил патч 2.4.67. Уязвимость mod_http2 (CVE-2026-23918, CVSS 8.8) даёт тривиальный DoS и рабочий RCE на x86_64. Разбираем, как срабатывает, кто затронут и какой минимум нужно сделать сегодня.

Обложка: Apache HTTP/2 CVE-2026-23918: double-free и рабочий RCE-PoC

Apache Software Foundation 4 мая 2026 года выпустил Apache HTTP Server 2.4.67 — он закрывает CVE-2026-23918 (CVSS 8.8) и ещё несколько уязвимостей. Главная — double-free в mod_http2: даёт гарантированный DoS из коробки и рабочий PoC удалённого выполнения кода на x86_64. Если у вас в проде Apache 2.4.66 с включённым HTTP/2 — обновляйтесь сегодня.

Уязвимость нашли и сообщили в ASF Bartlomiej Dmitruk (сооснователь Striga.ai) и Stanislaw Strzalkowski (исследователь ISEC.pl). DoS тривиален и работает на любом дефолтном Apache, у которого включён mod_http2 и выбран многопоточный MPM (Multi-Processing Module — модель обработки запросов; в современных продакшенах это обычно worker или event). RCE-путь требует ещё одного условия — APR (Apache Portable Runtime, слой работы с памятью и файлами в Apache) с mmap-аллокатором. Это дефолт на Debian-подобных дистрибутивах и в официальном httpd Docker-образе.

Главное
Ключевые выводы
CVE-2026-23918 в Apache HTTP/2 — что важно знать
  • CVE-2026-23918, CVSS 8.8 — double-free в mod_http2, стеком cleanup в h2_mplx.c. Затронут Apache 2.4.66, патч в 2.4.67.
  • DoS — тривиален: один TCP, два HTTP/2-фрейма (HEADERS + RST_STREAM с ненулевым error code), без авторизации, без специальных URL — воркер падает.
  • RCE — рабочий PoC на x86_64. Подменяется h2_stream, указатель cleanup-функции направляется на system(). В лабораторных условиях, по словам авторов, исполнение приземляется за минуты.
  • Затронуты только многопоточные MPM (worker, event); MPM prefork — не уязвим. RCE только при APR с mmap-аллокатором (Debian-семейство, httpd Docker).
  • Поверхность атаки большая: mod_http2 идёт в дефолтных сборках, HTTP/2 широко включён в продакшене. Обновляться сразу.

Как срабатывает double-free

Триггер очень короткий: клиент отправляет HTTP/2-фрейм HEADERS, сразу за ним — RST_STREAM с ненулевым error code на том же stream. Главное условие — мультиплексер ещё не успел зарегистрировать stream.

В этот момент два колбэка nghttp2 срабатывают подряд: on_frame_recv_cb для RST и затем on_stream_close_cb для close. Оба вызывают цепочку h2_mplx_c1_client_rst, которая запускает m_stream_cleanup, и оба раза один и тот же указатель h2_stream пушится в массив spurge cleanup — то есть в очередь на освобождение.

Когда позже c1_purge_streams проходит по spurge и для каждого элемента вызывает h2_stream_destroy с последующим apr_pool_destroy, второй вызов уже работает с уже освобождённой памятью. Это и есть double-free: память освобождается дважды, и в её ячейке к этому моменту уже может лежать чьи-то другие данные.

DoS: тривиальный, работает на дефолтных сборках

Один TCP-коннект, два фрейма, без аутентификации, без специальных заголовков, без определённого URL — и воркер падает. Apache перезапускает его, но каждый запрос на упавший воркер дропается. Атаку можно поддерживать сколько угодно, пока атакующий продолжает слать запросы.
Bartlomiej Dmitrukсооснователь Striga.ai, нашёл уязвимость; пересказ описания DoS

RCE: PoC на x86_64

Цепочка эксплуатации, по описанию авторов:

  1. Через mmap-reuse подкладывается поддельный h2_stream по освобождённому виртуальному адресу.
  2. Указатель cleanup-функции пула направляется на system().
  3. В качестве стабильного контейнера для fake-структур и команды используется память Apache scoreboard.

Логика классическая для класса use-after-free: освобождённая ячейка памяти повторно используется системой под другой объект, который контролирует атакующий. Когда Apache позже вызывает функцию очистки по сохранённому в этой ячейке указателю, управление улетает туда, куда атакующий написал. Scoreboard Apache — общая таблица состояния воркеров — сидит по фиксированному адресу на всю жизнь сервера, даже при включённом ASLR (Address Space Layout Randomization, рандомизация адресного пространства). Это и есть то, что делает RCE-путь практичным. Авторы уточняют ограничения: нужен info leak (утечка адреса system() и оффсетов scoreboard) и heap spray (массовое выделение памяти, чтобы поймать конкретный адрес) — в дикой природе это требует терпения. В лабораторных условиях, по словам авторов, успех укладывается в минуты.

Кто затронут — и что делать

  • Затронут: Apache HTTP Server 2.4.66 с mod_http2 и многопоточным MPM (worker, event).
  • Не затронут: MPM prefork (он однопроцессный, иной cleanup-путь).
  • RCE-условие: Apache Portable Runtime (APR) с mmap-аллокатором — дефолт на Debian, Ubuntu и в официальном httpd Docker-image.
  • Патч: Apache HTTP Server 2.4.67. ASF рекомендует обновляться немедленно.

Минимальный чек-лист — что сделать сегодня:

  1. httpd -v — проверить версию. Если 2.4.66 и есть HTTP/2 — затронуты.
  2. Обновить до 2.4.67 (через пакетный менеджер дистрибутива или пересборкой Docker-образа).
  3. Если обновить прямо сейчас нельзя — временно отключить mod_http2 или переключиться на MPM prefork (но он медленнее под нагрузкой).
  4. Проверить логи на следы атаки: HTTP/2 RST_STREAM с error-кодом — не штатный сценарий, и подозрительны массовые падения воркеров. Команда быстрого поиска: grep -E 'child .* exit signal Segmentation' /var/log/apache2/error.log.
Частые вопросы
1
Как понять, что у меня уязвимая версия?

Запустите httpd -v или apachectl -v. Если версия 2.4.66 и в конфиге включён mod_http2 (директива Protocols h2 в VirtualHost) — у вас уязвимая комбинация. По advisory ASF, затронут именно 2.4.66; в 2.4.67 баг закрыт. Для других версий нужно сверяться с бюллетенем.

2
Достаточно ли отключить HTTP/2 как временное обходное решение?

Да. Уязвимость в коде mod_http2; если этот модуль выключен (или в конфиге Protocols только http/1.1), триггерить double-free нечем. Для серверов под публичной нагрузкой временное отключение HTTP/2 — приемлемая мера до обновления.

3
Если стоит prefork — точно ничего не нужно делать?

По заявлению авторов уязвимости, MPM prefork не затронут из-за иного cleanup-пути. Но prefork не предназначен для высоконагруженных продакшенов — его обычно используют как узкое решение под mod_php. Если у вас prefork — обновить стоит всё равно, но без срочности.

4
Возможен ли RCE из интернета без аутентификации?

По описанию: возможен, если выполнено условие APR с mmap-аллокатором (Debian, Ubuntu, httpd Docker). DoS — точно возможен без аутентификации, RCE — практичен в лабораторных условиях, для атаки в дикой природе нужны info leak и точный таймер. Но риск нельзя считать гипотетическим: PoC уже есть.

5
Где почитать первоисточник?

Бюллетень ASF: httpd.apache.org/security/vulnerabilities_24.html. Развёрнутый разбор от исследователей и журналистов — на The Hacker News. Запись в NVD — nvd.nist.gov/vuln/detail/CVE-2026-23918.

Выводы

CVE-2026-23918 — типичный пример уязвимости класса use-after-free с RCE-путём через предсказуемый адрес scoreboard. Триггер крошечный, фикс простой, но поверхность атаки огромная: каждый сервер с включённым HTTP/2 и multi-threaded MPM открыт хотя бы для DoS.

Главное практическое правило: обновите Apache до 2.4.67. Если обновить нельзя сию минуту — отключите HTTP/2 как временное обходное решение. Это уязвимость, которую с большой вероятностью начнут эксплуатировать в массовых сканах в ближайшие дни.

Подробный разбор и комментарии исследователей — на The Hacker News. Бюллетень Apache — на httpd.apache.org/security.