VPSРейтинг
Безопасность1 ноября 2026 · 10 мин

PHP2Shell (CVE-2026-109618 и CVE-2026-109619): как проверить и закрыть дыру в PHP

PHP2Shell — общее имя двух уязвимостей в самом интерпретаторе PHP. Специально составленный запрос позволяет выполнить на сервере чужой код без всякого входа, а значит, под ударом не один плагин или движок, а любой сайт на PHP. Дыры уже используют в атаках, поэтому действовать стоит сегодня. Ниже — как узнать, какая версия PHP обслуживает ваш сайт, как её обновить и что делать, если обновиться прямо сейчас не выходит.

Кратко, если нет времени читать

  • Что уязвимо: ядро PHP, все версии ниже 8.2.35, 8.3.36, 8.4.27 и 8.5.12. Затронут любой сайт на PHP, независимо от движка и фреймворка.
  • Чем опасно: выполнение чужого кода на сервере без входа и без действий с вашей стороны. Оценка опасности — 9.2 из 10, их уже используют в атаках, а 109618 внесена в список активно используемых уязвимостей CISA.
  • Что делать: обновить PHP до исправленной версии своей ветки и перезапустить воркеры (systemctl restart php8.3-fpm или перезапуск веб-сервера). Без перезапуска заплатка не действует.
  • Если обновиться нельзя сейчас: закройте сервер от внешнего доступа. Полного обходного решения нет — PHP прямо пишет, что помогает только обновление.

1. Что это за уязвимости и чем они опасны

PHP2Shell — это пара уязвимостей в ядре PHP, которые команда PHP раскрыла 21 октября 2026 года. Обе ведут к удалённому выполнению кода: отправив серверу специально составленный запрос, посторонний может запустить на нём собственные команды. Вход на сайт для этого не нужен, и срабатывает всё без участия администратора — в отличие от многих других дыр, где нужно, чтобы жертва что-то открыла или нажала.

Главное отличие от обычной дыры в плагине: проблема в самом PHP, а не в чьём-то коде. Под ударом оказывается любой сайт, который обслуживается уязвимой версией PHP, — на WordPress, на Laravel, на самописном движке, без разницы. Поэтому уязвимость и получила общее имя: речь не о конкретной программе, а о способе превратить запрос к PHP в выполнение команд («to shell»).

ИдентификаторыCVE-2026-109618 и CVE-2026-109619 (общее имя — PHP2Shell)
ГдеЯдро PHP, затронуты все сайты на уязвимой версии
Уязвимые версииВсе ниже 8.2.35, 8.3.36, 8.4.27 и 8.5.12
Исправлено8.2.35, 8.3.36, 8.4.27, 8.5.12 (вышли 21 октября 2026)
ТипПовреждение памяти при обработке запроса → выполнение кода
Оценка CVSS 4.09.2 из 10 (критическая) у обеих
Нужен ли входНет — запрос шлёт неавторизованный посетитель
СтатусЭксплуатируется в атаках; 109618 в списке CISA с 26 октября 2026

Одна тонкость, которая снижает панику, но не повод медлить: по оценке PHP, атака требует определённых условий и не срабатывает с первого случайного запроса — в формуле опасности это отражено как высокая сложность. Но условия воспроизводимы, рабочие атаки уже ходят по сети, поэтому ставка на «до меня не доберутся» не оправдана.

2. Касается ли это вас: какая версия PHP у сайта

Вопрос один: какая версия PHP обслуживает ваш сайт и входит ли в неё заплатка. Здесь есть две ловушки. Первая: на сервере нередко стоит сразу несколько версий PHP, и та, что запускается в терминале, может быть не той, что обслуживает сайт. Вторая: на Debian, Ubuntu и RHEL номер версии после обновления не меняется, хотя дыру уже закрыли. Разберём по порядку.

Шаг 1. Узнать версию, которая обслуживает сайт

Версия в терминале — это только начало, и верить ей как версии сайта нельзя:

Версия PHP в командной строке — не обязательно та, что обслуживает сайт
php -v

Сайт почти всегда обслуживает отдельный процесс — PHP-FPM или модуль Apache. Какая это ветка, видно по работающим процессам FPM:

Покажет строку вида: php-fpm: master process (/etc/php/8.3/fpm/php-fpm.conf)
ps -eo args | grep 'php-fpm: [m]aster'

Узнав ветку, спросите её точную версию (подставьте свою цифру):

Это версия именно того PHP, который обслуживает сайт
php-fpm8.3 -v

Если сайт работает на Apache с модулем mod_php, процесса FPM не будет. Самый надёжный способ увидеть версию, которую реально отдаёт сайт, — временно положить в корень сайта файл с одной строкой <?php phpinfo();, открыть его в браузере, прочитать «PHP Version» вверху страницы и сразу удалить файл: он раскрывает лишнее.

Шаг 2. Сравнить с исправленными версиями

Найдите свою ветку в таблице. Если ваша версия ниже указанной — вы под угрозой.

Ваша ветка PHPИсправлено в версии
8.5.x8.5.12
8.4.x8.4.27
8.3.x8.3.36
8.2.x8.2.35
8.1.x и старшеПоддержка окончена, официальной заплатки нет — переходите на свежую ветку

Если PHP стоит из репозитория дистрибутива

На Debian, Ubuntu и RHEL-подобных системах заплатку переносят в сборку пакета, не меняя номер версии. После обновления php -v может по-прежнему показывать, например, 8.3.6 — и это нормально, если заплатка в пакете есть. Судите не по номеру, а по тому, стоит ли у вас последняя версия пакета из репозитория и упомянут ли в его журнале нужный номер (команда — в разделе 4). Честный номер версии только у PHP из исходников php.net или из репозитория Sury (ppa:ondrej/php): там он должен быть не ниже значения из таблицы.

3. Как это работает — коротко

Разбирать атаку по шагам здесь незачем, но суть знать полезно: от неё зависит, что помогает, а что нет.

  • Обе дыры — про память запроса. Обрабатывая запрос, PHP в отдельных случаях оставляет свою память в неверном состоянии: одна уязвимость связана с нехваткой памяти во время обработки, другая — с остатками данных от прошлого запроса, которые попадают в следующий. На этой ошибке и строится выполнение чужого кода.
  • Запрос приходит снаружи. Чтобы довести PHP до нужного состояния, хватает обычных HTTP-запросов — например, особым образом собранной отправки формы. Вход и права не нужны.
  • Apache mod_php — первым. PHP подтвердил, что при работе через модуль Apache атака удаётся на стандартных настройках и срабатывает ещё до кода вашего сайта. Связка nginx с PHP-FPM тоже признана уязвимой, просто её ставят следом по приоритету.

Отсюда вывод, который определяет всё остальное: раз дыра в самом PHP, её не закрыть ни правкой сайта, ни плагином безопасности. Надёжно помогает только обновление PHP — так прямо и написано в бюллетене PHP: это единственное полное решение.

4. Быстрое решение: обновить PHP и перезапустить воркеры

Решение в два действия: обновить пакет PHP и перезапустить то, что его запускает. Второе так же важно, как первое: пока процессы не перезапущены, они держат в памяти старый, уязвимый код.

Debian и Ubuntu

Обновите пакеты и перезапустите PHP-FPM своей ветки (подставьте свою цифру вместо 8.3):

Обновление пакетов, затем перезапуск воркеров PHP-FPM
sudo apt update
sudo apt upgrade
sudo systemctl restart php8.3-fpm

Если сайт работает на Apache с модулем mod_php, перезапускать нужно сам Apache — воркеры PHP живут внутри него:

Для mod_php перезапуск PHP-FPM не нужен — перезапускаем веб-сервер
sudo systemctl restart apache2

Если пакеты PHP у вас из репозитория Sury, он обычно получает исправленную версию в день выхода; штатные репозитории Ubuntu и Debian приносят заплатку своей сборкой чуть позже, но тоже без смены номера. Посмотреть, какая версия пакета вам сейчас доступна, можно так:

Строка Candidate — что встанет при обновлении
apt-cache policy php8.3-fpm

Docker

В контейнере PHP не обновляют внутри — пересобирают образ на исправленной основе. Укажите в Dockerfile точную версию базового образа и пересоберите контейнер:

Пример строки FROM — возьмите исправленную версию своей ветки
FROM php:8.3.36-fpm
Подтянуть свежий образ, пересобрать и поднять заново
docker compose pull
docker compose up -d --build

Проверить, что заплатка встала

На PHP из php.net или Sury достаточно сверить номер версии с таблицей из раздела 2:

Должно быть не ниже исправленной версии вашей ветки
php-fpm8.3 -v

На пакетах Debian и Ubuntu номер не покажет правду — там загляните в журнал пакета: если в нём упомянут номер уязвимости, заплатка на месте.

Пустой ответ — заплатки в установленном пакете ещё нет
zcat /usr/share/doc/php8.3-fpm/changelog.Debian.gz | grep -i -m1 109618

И последняя сверка — на живом сайте: если вы снимали версию через phpinfo(), повторите замер (и снова удалите файл). Номер должен соответствовать обновлённой версии.

5. Если обновиться прямо сейчас нельзя

Бывает, что обновить немедленно не выходит: ветка PHP снята с поддержки, обновление ломает совместимость, смена версии требует проверки сайта. Полного обходного решения у этих дыр нет — PHP говорит об этом прямо. Но пока вы готовите обновление, доступ к серверу можно резко ограничить.

  • Закройте сервер от посторонних. Самая надёжная временная мера — убрать сайт из открытого доступа: закрыть его межсетевым экраном на всех, кроме своих адресов, или спрятать за вход. Нет внешних запросов — нет и атаки.
  • Обрежьте то, через что приходит атака. Дыру разгоняют тяжёлые и необычные запросы, прежде всего отправка форм и файлов. На веб-сервере или в защитном модуле стоит ограничить размер запроса (в PHP это post_max_size) и, если сайт не принимает файлы и формы, блокировать загрузки целиком. Это сужает щель, но не закрывает её.
  • Помните, что это только отсрочка. У PHP есть и более тонкие частичные меры из бюллетеня, но все они неполные и с оговорками. Единственное, что закрывает дыру насовсем, — обновление, поэтому держите его первой задачей, а не «когда-нибудь потом».

6. Проверить, не атаковали ли уже

Дыры эксплуатируют с самого дня раскрытия, поэтому вопрос законный. Простого и надёжного признака атаки, по которому её можно опознать одной командой, нет: повреждение памяти не оставляет заметной строки в журнале. Поэтому исходите из риска. Если сервер смотрел в интернет уязвимой версией хоть сколько-то времени, считайте, что его могли достать, и проверьте несколько вещей.

  • Чужие файлы в корне сайта. После захвата первым делом кладут веб-оболочку — короткий PHP-файл, через который дальше управляют сервером. Поищите недавно изменённые файлы PHP: find /var/www -name '*.php' -mtime -14 -printf '%Tc %p\n'. Всё, что вы не меняли сами, — повод присмотреться.
  • Лишние процессы и исходящие соединения. Загляните в список процессов и сетевых соединений (ps aux, ss -tunp): незнакомые программы и неожиданные исходящие подключения — тревожный знак.
  • Новые задания и пользователи. Проверьте задания планировщика (crontab -l и каталоги /etc/cron.*) и недавно добавленные учётные записи: через них закрепляются, чтобы вернуться после перезагрузки.

Если нашли следы вторжения

Чистить захваченный сервер по одному файлу — ненадёжно: что-то обязательно останется. Правильнее поднять его заново из заведомо чистой резервной копии или с нуля, перенести только проверенные данные, а все пароли и ключи — к базе, в панели, по SSH — сменить, считая их скомпрометированными. И, конечно, уже на обновлённом PHP, иначе дыра останется открытой.

7. Чтобы это не повторилось

Критические дыры в PHP выходят редко, но когда выходят — счёт идёт на часы. Защищает не разовое обновление, а то, как устроено обслуживание сервера.

  • Держите PHP на поддерживаемой ветке. Снятые с поддержки версии (сейчас это 8.1 и старше) заплаток не получают вовсе — в этот раз для них официального исправления просто нет. Своевременный переход на свежую ветку избавляет от тупика, когда чинить уже нечем.
  • Включите автоматические обновления безопасности. На Debian и Ubuntu это пакет unattended-upgrades: критические заплатки приезжают сами, не дожидаясь, пока вы прочитаете новость. Проследите только, чтобы после установки заплаток перезапускались службы, — сам PHP-FPM их не подхватит.
  • Не держите лишнего снаружи. Чем меньше у сервера открытых наружу сервисов, тем меньше у атаки точек входа. Базовую настройку доступа и файрвола разбираем в статье про безопасность VPS.

Автоматическую блокировку ботов, которые перебирают такие дыры, разбираем в статье про CrowdSec, а резервные копии, из которых можно за минуты поднять сервер заново, — в разборе бэкапов на restic и rclone.

8. Частые вопросы

Обновлять PHP не страшно, когда есть куда откатиться. Провайдеры со снимками дисков и бэкапами позволяют вернуть сервер за минуты, если обновление что-то задело, — у кого что есть, видно в рейтинге.

Рейтинг провайдеров →