Быстрее, выше, дырявее. В коде HTTP/3 нашли идеальный инструмент для бесплатного DDoS
Ошибки в семи популярных реализациях HTTP/3 позволяют удаленному клиенту перегрузить сервер без авторизации и огромного потока трафика. Специалист FoxIO проверил десять реализаций и обнаружил, что небольшой сжатый запрос в памяти может разрастись в десятки, сотни и даже тысячи раз. В отдельных тестах для отказа в обслуживании хватало одного соединения.
Проблема прячется в QPACK, который сжимает заголовки HTTP/3. Вместо повторяющейся строки клиент может отправить короткую ссылку на запись в таблице, а сервер затем восстановит полное значение. Экономия работает хорошо, пока программа ограничивает не только полученные байты, но и объем данных после распаковки. Несколько библиотек следили за неправильной величиной, проверяли размер слишком поздно или вовсе не устанавливали нужный предел.
Исследователь назвал технику Header Accordions. В одном варианте атакующий набивает блок множеством коротких заголовков: 1 МБ сжатых данных превращался примерно в 160 тыс. полей. В другом варианте клиент сначала помещает в динамическую таблицу запись размером около 4 КБ, а затем обращается к ней однобайтовыми ссылками. Сервер каждый раз восстанавливает полную запись и снова тратит память. Для некоторых реализаций один переданный байт заставлял выделить около 4 КБ, что дает усиление примерно в 4000 раз.
Самый тяжелый сценарий исследователь воспроизвел на Bun. Около 5,8 МБ входящего трафика хватило, чтобы исчерпать 2 ГБ памяти контейнера. Отдельная ошибка в коде управления буфером позволяла добиться другого эффекта: примерно 516 КБ данных загружали процессор на 100%, после чего сервер переставал принимать новые запросы и самостоятельно уже не восстанавливался.
Уязвимые участки нашлись также в quic-go, Cloudflare quiche, lsquic, aioquic с mitmproxy, библиотеке h3 и Wireshark. Причины различались. quic-go ограничивал размер сжатого блока, но не проверял итоговый объем заголовков. Cloudflare quiche неправильно учитывал размер полей и мог заранее выделить слишком много памяти. h3 позволял набрать столько заголовков, что программа аварийно завершала обработку. В тестах IIS, Envoy и связка ngtcp2/nghttp3 выдержали подготовленные запросы.
Часть разработчиков закрыла ошибки еще до публикации подробностей. Исправления вошли в quic-go 0.57.0, Cloudflare quiche 0.29.3, lsquic 4.9.0, Wireshark 4.6.2 и 4.4.12. Для проблем в quic-go, quiche и Wireshark зарегистрированы CVE-2025-64702, CVE-2026-12523 и CVE-2025-13945.
Bun на момент выхода разбора оставался уязвимым, но разработчики позднее выпустили исправление в версии 1.4.4. Теперь Bun ограничивает суммарный размер распакованных заголовков и число полей. Уязвимы версии от 1.3.14 до 1.4.3 включительно, а HTTP/1.1 и HTTP/2 проблема Bun не затрагивает.
Header Accordions особенно опасна из-за разницы в затратах двух сторон. Клиент отправляет компактные ссылки, а сервер тратит память и процессорное время на восстановление и хранение гораздо большего объема данных. Поэтому для атаки не нужен ботнет или поток в сотни гигабит в секунду: при уязвимой реализации один клиент способен создать нагрузку, несопоставимую с объемом отправленного трафика.