Исследователи Wordfence Threat Intelligence обнаружили в плагине Gravity Forms для WordPress уязвимость произвольной загрузки файлов. Проблема затрагивает версии до 3.0.2 включительно и позволяет неаутентифицированному злоумышленнику записать во временную публичную директорию файл с выбранным расширением. При определённой конфигурации сервера это приводит к удалённому выполнению кода. Разработчики выпустили исправление в версии 3.0.3 20 августа 2026 года, а пользователям рекомендуется обновиться как можно скорее.
Уязвимость CVE-2026-19513
Уязвимость получила идентификатор CVE-2026-19513 и оценку 8.1 балла по шкале CVSS, что считается высоким уровнем опасности. Причиной стала недостаточная проверка состояния многопоточной загрузки файлов в функции, обрабатывающей запросы на продолжение передачи. В Gravity Forms встроен механизм загрузки нескольких файлов, который разбивает большой файл на блоки. Для каждого последующего блока клиент отправляет параметр state, связывающий временное имя файла с номером блока, формой, полем и исходным именем файла. Начиная с версии 3.0.2, разработчики попытались защитить это состояние с помощью хэша WordPress - но сделали это без учёта контекста.
Суть проблемы в том, что одна и та же хэш-функция wp_hash() применяется в двух разных ситуациях. Публичное состояние формы включает хэш от URL текущей страницы. Этот URL формируется на основе запроса посетителя, то есть злоумышленник может влиять на его содержимое. Если подобрать такой адрес страницы, значение которого совпадает с заранее подготовленной строкой, описывающей состояние загрузки, то полученный легитимный хэш URL можно использовать как хэш продолжения загрузки. Атакующему не нужно подбирать секретный ключ сайта или создавать поддельную подпись - достаточно переиспользовать настоящий хэш, выпущенный для другой цели. Такая ошибка относится к классу доменных конфликтов криптографических функций.
Дополнительно обработчик загрузки недостаточно проверял временное имя файла. Он принимал имя, переданное злоумышленником, проверял его хэш и только потом пропускал через функцию очистки. При этом фактическое имя временного файла и разрешённые типы загрузки проверялись отдельно. В результате атакующий мог указать в исходных данных обычное разрешённое имя, например safe.png, а временный файл на диске получал расширение .php. Чтобы обойти проверку содержимого, использовался так называемый полиглот - файл, который одновременно является корректным изображением PNG или PDF и содержит встроенный PHP-код. Форма проверяет только тип загрузки, поэтому файл, прошедший как изображение, сохраняется с расширением .php и может быть исполнен сервером.
Для проведения атаки достаточно, чтобы на сайте существовала публичная форма с полем загрузки файлов, у которого включён режим множественного выбора. Поддержка PNG и PDF в Gravity Forms и WordPress включена по умолчанию, поэтому администратору не нужно добавлять эти типы в список разрешённых. Ещё одно важное обстоятельство: для отправки ненулевого номера блока вовсе не требуется, чтобы первый блок был создан сервером. Обработчик открывает файл с расширением .part в режиме добавления, создавая его при отсутствии. Если запрос помечен как последний блок, суффикс .part удаляется, и файл получает итоговое имя. Такой механизм позволяет неаутентифицированному пользователю записать файл с произвольным расширением в директорию временных загрузок без каких-либо прав.
Итоговое влияние зависит от веб-сервера. Gravity Forms при активации размещает во временной директории файл .htaccess, который запрещает выполнение PHP на типичных конфигурациях Apache. Если сайт работает под управлением Apache с учётом этих директив, эксплуатация уязвимости не приведёт к выполнению кода. Однако серверы NGINX не обрабатывают .htaccess, поэтому PHP-файл в этой директории может быть исполнен. В случаях, когда выполнение PHP заблокировано, злоумышленник может загрузить HTML-файл и использовать его для межсайтового скриптинга в том же домене: если жертва откроет сгенерированный URL, вредоносный JavaScript выполнится в контексте сайта.
Разработчики Gravity Forms устранили проблему в версии 3.0.3. Патч меняет логику работы с временными именами: теперь сервер сам генерирует случайное имя файла, которое включает только допустимое расширение исходной загрузки. Продолжение загрузки возможно лишь при наличии подписанного состояния, созданного сервером. Для проверки используется структурированный HMAC-токен с разделением доменов, который привязывает имя файла, номер следующего блока, идентификаторы формы и поля, исходное имя, текущее смещение и общее число блоков. Дополнительно код отклоняет любые неканонические имена и запрещает временным файлам иметь недопустимые расширения. Теперь злоумышленник не может повлиять на конечное имя файла и не способен переиспользовать хэш публичного состояния формы для аутентификации загрузки.
Специалисты Wordfence обнаружили уязвимость 9 августа 2026 года в ходе внутреннего исследования с помощью собственной системы Argus. Полные детали были переданы команде Gravity Forms через портал управления уязвимостями 11 августа. Разработчик подтвердил отчёт и выпустил исправление 20 августа того же года.
Пользователям WordPress с установленным Gravity Forms следует проверить версию плагина и обновить сайт до 3.0.3 или новее. Учитывая высокую оценку опасности и то, что атака не требует аутентификации, откладывать обновление не стоит. Даже если сайт работает на Apache с файлом .htaccess, ограничивающим выполнение PHP, остаётся риск загрузки HTML-содержимого и последующего скриптинга. Этот случай в очередной раз показывает, как переиспользование криптографических примитивов в разных контекстах может привести к серьёзным последствиям, а своевременное взаимодействие исследователей и разработчиков сокращает окно уязвимости до минимума.
Ссылки
- https://www.cve.org/CVERecord?id=CVE-2026-19513
- https://www.wordfence.com/threat-intel/vulnerabilities/id/d20b2d00-054e-4772-a5a5-b7b33063043c
- https://docs.gravityforms.com/gravityforms-change-log/