Исследователи из Fortbridge показали, что обычная загрузка изображения в WordPress может закончиться выполнением команд на сервере. В основе цепочки лежит переполнение буфера в библиотеке libheif, которая разбирает форматы HEIC и AVIF. Проблема затрагивает декодер несжатых изображений. Её отслеживают под номером GHSA-x8r2-mggj-j6wr, исправление вышло в версии 1.23.3.
Детали уязвимостей
Уязвимы выпуски libheif с 1.18.0 по 1.23.2 включительно. Вендор отнёс проблему к критическому уровню и оценил её в 10 баллов по шкале CVSS. Чтобы добраться до неё, нужен не только файл, но и работающая цепочка обработки изображений. WordPress строит такую цепочку по умолчанию. Нашли проблему в Wordfence, а описание опубликовал сопровождающий библиотеки.
Механизм ошибки связан с цветовыми компонентами. Формат позволяет объявить один из компонентов цветности, Cb, шестнадцатибитным, а второй, Cr, восьмибитным. libheif выделяет память под плоскость Cr из расчёта один байт на отсчёт. Однако цикл обработки берёт ширину Cb, то есть два байта, и применяет её к обеим плоскостям. Каждая запись в Cr уходит дальше положенного. Данные, которые попадают при этом в память, задаёт автор изображения. Ошибка живёт внутри самого декодера и не требует внешних кодеков. Достаточно, чтобы библиотеку собрали с поддержкой кодека несжатых изображений.
Плоскость в этом контексте означает буфер памяти для одного цветового канала вместе со служебными данными. Когда записи выходят за границу выделенного буфера, они задевают соседние объекты в динамической памяти. При удачной раскладке повреждённая плоскость оказывается рядом с внутренними структурами декодера. Тогда дальнейшие записи меняют указатель на таблицу виртуальных методов объекта, написанного на C++. Такая таблица хранит адреса функций, которые вызываются при обработке объекта. Подменив её, атакующий выбирает, куда перейдёт управление при следующем вызове.
В WordPress файл проходит несколько этапов обработки. Медиабиблиотека принимает загрузку, расширение Imagick для PHP передаёт данные в ImageMagick, а тот обращается к libheif. Разбор происходит внутри рабочего процесса PHP-FPM. Поэтому сбой или выполнение чужого кода проявляются на стороне сервера, хотя начинается всё с рядовой операции в панели управления.
Цепочка не сводится к одной загрузке. Сначала исследователи отправляют вспомогательные изображения и изучают производные JPEG, которые WordPress создаёт автоматически для превью. Из пикселей этих файлов удаётся восстановить адреса загруженных библиотек. Здесь работает вторая уязвимость, GHSA-2jg2-4ch7-h545, связанная с чтением и записью за пределами плоскости при обработке производных изображений. Её закрыли в libheif 1.23.2. Вторую проблему описал отдел безопасности Meta, где вместе с ней нашли ещё десять ошибок того же класса. Получив адреса, эксплойт (вредоносный код, использующий уязвимость) подбирает профиль под конкретную сборку. Затем он собирает полезную нагрузку с поправкой на ASLR (механизм, который случайным образом размещает библиотеки при каждом запуске процесса).
Fortbridge проверила цепочку на двух наборах пакетов. Первый - Ubuntu 26.04, WordPress 7.1.1, PHP-FPM 8.5.4, ImageMagick 7.1.2.18 и libheif 1.21.2. Второй - Debian 13, WordPress 7.0, PHP-FPM 8.4.24, ImageMagick 7.1.1.43 и libheif 1.19.8. Команду id удалось выполнить от имени учётной записи www-data в шести запусках из восьми на Ubuntu и в двадцати двух из двадцати четырёх на Debian. В лабораторных опытах цепочка также позволяла скопировать системный файл с перечнем учётных записей в общедоступный каталог загрузок.
Успех зависит от совпадения множества условий: версии библиотек, раскладки памяти, поведения аллокатора, размера пула PHP-FPM. Обновление одного пакета меняет смещения, поэтому готовые профили перестают работать. Атака требует учётной записи с правом upload_files, обычно это роль Author и выше. Если сайт разрешает загрузку файлов гостям или сторонний плагин открывает тот же маршрут обработки, требования к атакующему снижаются. Публично подтверждённых случаев эксплуатации в реальных атаках нет.
Администраторам стоит обновить libheif до 1.23.3 или новее. Debian уже выпустил пакет 1.23.4-1~deb13u1, который закрывает ряд уязвимостей библиотеки, включая описанную. После установки нужно перезапустить PHP-FPM. Долго живущие рабочие процессы держат старую версию библиотеки в памяти, поэтому без перезапуска исправление не заработает.
Там, где загрузка HEIC и AVIF не нужна, форматы лучше отклонять до того, как файл дойдёт до нативного декодера, то есть до библиотеки, скомпилированной под конкретную платформу. Разбор медиафайлов разумно выносить в отдельный сервис с минимальными правами, без доступа к сети и без секретов приложения. Записываемые каталоги стоит ограничить, а выполнение скриптов из папки загрузок запретить.
Признаки проблемы заметны в журналах. Повторные аварийные завершения рабочих процессов PHP-FPM, ответы 503 во время загрузки изображений и файлы HEIC с отношениями unci, iden, crop, overlay или grid заслуживают проверки. Само по себе падение процесса не доказывает эксплуатацию, однако серия таких событий при загрузке медиафайлов похожа на попытку атаки.
Картина, которую описали Fortbridge, затрагивает не только веб-приложение. Обработка картинок давно опирается на библиотеки, написанные на C и C++. Они остаются вне привычной модели угроз, где защита сводится к паролям, обновлению плагинов и разграничению ролей. Крепкий пароль администратора не помогает, если вредоносный файл разбирает уязвимый декодер.
Ссылки
- https://fortbridge.co.uk/research/wordpress-libheif-rce/
- https://github.com/strukturag/libheif/security/advisories/GHSA-x8r2-mggj-j6wr
- https://github.com/strukturag/libheif/security/advisories/GHSA-2jg2-4ch7-h545
- https://github.com/FORTBRIDGE-UK/libheif-unci-wordpress-rce