Один анонимный HTTP-запрос может привести к выполнению кода на сайте WordPress, даже если владелец не устанавливал ни одного плагина. Уязвимость находится в ядре системы и складывается из двух отдельных ошибок: SQL-инъекции и сбоя в пакетной обработке запросов REST API. Вместе они позволяют злоумышленнику пройти путь от обычного обращения к сайту до запуска команд на сервере без учётной записи и каких-либо действий со стороны пользователя.
Цепочка получила название wp2shell. Ошибкам присвоили идентификаторы CVE-2026-60137 и CVE-2026-63030. Первая затрагивает WordPress начиная с версии 6.8, а вторая появилась только в ветке 6.9. Поэтому удалённое выполнение кода возможно в WordPress 6.9.0–6.9.4 и 7.0.0–7.0.1. Исправления вошли в версии 6.9.5 и 7.0.2. Для ветки 6.8 выпущена версия 6.8.6, закрывающая только SQL-инъекцию. Оба патча также включены в WordPress 7.1 beta 2.
Разработчики WordPress оценили цепочку удалённого выполнения кода как критическую и включили принудительное распространение обновлений через встроенную систему автоматической установки. Администраторам всё равно рекомендуют проверить фактическую версию каждого сайта, поскольку успешное получение обновления зависит от конфигурации сервера и состояния механизма автообновления.
Первая часть атаки находится в классе WP_Query, который WordPress использует для формирования запросов к базе данных. Уязвимым оказался параметр author__not_in. В нормальной ситуации он должен получать массив идентификаторов авторов, чьи записи необходимо исключить из результатов.
Проверка входных данных предполагала, что в параметр всегда передаётся массив. Если вместо него отправить строку, часть фильтрации можно обойти. Необработанное значение попадает в SQL-запрос и позволяет изменить его структуру. Так возникает SQL-инъекция, зарегистрированная как CVE-2026-60137.
Сама по себе ошибка не означает, что любой анонимный посетитель автоматически получит возможность выполнить код. Для эксплуатации необходимо передать подготовленное значение в уязвимый параметр WP_Query. На сайтах WordPress 6.8 подобный путь может появиться через тему или плагин, который принимает ненадёжные данные и использует их при формировании запроса. Официальное описание поэтому называет уязвимость «облегчённой» SQL-инъекцией.
В WordPress 6.9 появилась вторая ошибка, которая устранила это ограничение. Она связана с пакетным маршрутом REST API /wp-json/batch/v1. Такой маршрут позволяет объединить несколько внутренних запросов в одно HTTP-обращение, чтобы клиент мог выполнить сразу несколько операций.
WordPress хранит сведения о пакетных подзапросах в параллельных структурах. Из-за ошибки при обработке неудачного элемента записи могли сместиться относительно друг друга. В результате один подзапрос выполнялся обработчиком, предназначенным для другого.
Вложенная последовательность подобных запросов позволяла обойти ограничения пакетного маршрута и передать подготовленное значение в уязвимый author__not_in. Именно сочетание путаницы маршрутов с SQL-инъекцией превращало две сравнительно небольшие ошибки в выполнение кода без аутентификации.
Дефект затрагивает ядро WordPress, поэтому для атаки не требуются сторонние расширения или специально настроенная тема. Под угрозой находилась и стандартная установка с настройками по умолчанию. Официальное предупреждение подтверждает, что цепочка затрагивает WordPress 6.9 и 7.0 и позволяет добиться удалённого выполнения кода через пакетный маршрут REST API.
Диапазоны уязвимых версий различаются. WordPress 6.8.0–6.8.5 содержит SQL-инъекцию, но не ошибку пакетной маршрутизации, поэтому описанная цепочка RCE для этой ветки не работает. WordPress 6.9.0–6.9.4 и 7.0.0–7.0.1 содержат обе проблемы и допускают полную атаку.
Дополнительное условие касается постоянного объектного кеша. По данным Cloudflare, путь к выполнению кода работает, когда сайт не использует такой кеш. По умолчанию WordPress постоянный объектный кеш не включает, поэтому это ограничение не защищает большинство базовых конфигураций.
Redis или Memcached могут использоваться для хранения объектов WordPress между отдельными запросами. Наличие такого кеша способно нарушить конкретную последовательность действий, необходимую для wp2shell. Однако подобную особенность нельзя считать исправлением: она не закрывает SQL-инъекцию и не гарантирует защиту от других вариантов эксплуатации.
Оценки опасности двух CVE могут показаться противоречивыми. WordPress называет итоговую цепочку критической, однако CVE-2026-63030 получила оценку 7,5 из десяти. SQL-инъекция CVE-2026-60137 оценивается выше, хотя самостоятельно не даёт анонимному посетителю такого же прямого пути к выполнению кода. Разница возникает потому, что система CVSS рассматривает каждую ошибку отдельно, а не весь результат их совместного использования.
Для защиты необходимо отслеживать оба идентификатора. Исправление только одной части разрушает вектор атаки, но оставляет вторую проблему в системе. WordPress 6.9.5 и 7.0.2 закрывают обе ошибки, а версия 6.8.6 устраняет SQL-инъекцию в более ранней ветке.
На момент первоначального раскрытия специалисты не сообщали о подтверждённых атаках в реальных системах. Отсутствие таких сведений не снижает риск, поскольку патч и описание изменений уже доступны публично. После выхода исправления исследователи могут сравнить старый и новый код, восстановить принцип эксплуатации и создать рабочий инструмент для поиска уязвимых сайтов.
Cloudflare заранее подготовила правила межсетевого экрана для обеих уязвимостей и включила их 17 июля. Защита распространяется на сайты, трафик которых проходит через Cloudflare WAF, включая бесплатный набор правил. Компания подчёркивает, что фильтрация запросов лишь снижает риск до установки обновления и не исправляет код WordPress.
Временно ограничить атаку можно блокировкой пакетного маршрута REST API. Фильтр должен учитывать оба способа обращения: прямой путь /wp-json/batch/v1 и вариант с параметром rest_route=/batch/v1. Блокировка только первого адреса оставляет второй путь открытым.
Другой временный вариант заключается в запрете анонимного доступа к REST API или только к маршруту /batch/v1. Такие ограничения могут нарушить работу редактора, мобильных приложений, интеграций и плагинов, которые используют программный интерфейс WordPress. Поэтому их следует рассматривать как краткосрочную меру, а не замену обновлению.
Администраторам необходимо проверить, что сайт работает на WordPress 6.8.6, 6.9.5, 7.0.2 или более новой исправленной версии соответствующей ветки. Официальный архив подтверждает выпуск WordPress 6.9.5 17 июля 2026 года, а команда проекта рекомендует немедленно установить обновление из-за серьёзности ошибок.
Особое внимание требуется сайтам, на которых автоматические обновления отключены, не работают из-за прав доступа или управляются хостинг-провайдером. Полагаться только на сообщение о принудительном распространении патча нельзя: безопасную версию следует проверить непосредственно в панели WordPress или средствами управления сервером.
После обновления стоит просмотреть журналы веб-сервера и WAF на предмет обращений к пакетному маршруту REST API, особенно запросов со сложной вложенной структурой. Само наличие обращений ещё не доказывает успешный взлом, поскольку маршрут используется легитимными клиентами. Подозрение должны вызывать необычные анонимные запросы, совпадающие с правилами обнаружения уязвимости.
Rapid7 подготовила авторизованные проверки для InsightVM и Nexpose, выпуск которых запланирован на 20 июля. Такие проверки смогут подтвердить установленную версию и состояние исправления, но внешнее сканирование без доступа к системе не всегда точно определяет наличие патча.
Опасность wp2shell связана не только с уровнем доступа, который получает злоумышленник. WordPress установлен на огромном числе публичных сайтов, а стандартная конфигурация не требует плагинов и не включает постоянный объектный кеш. После публикации механизма разрыв между выпуском исправления и его фактической установкой становится главным фактором риска.
Цепочка показывает, как две ошибки в разных компонентах могут усиливать друг друга. SQL-инъекция предоставила возможность изменить запрос к базе данных, но не имела универсального анонимного входа. Сбой пакетной маршрутизации открыл такой вход, но без инъекции не позволял выполнить код. Объединение двух проблем превратило их в критическую уязвимость ядра WordPress.