21 октября 2026 года разработчики PHP выпустили срочные версии 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Они закрывают две критические уязвимости, CVE-2026-109618 и CVE-2026-109619, с общим названием PHP2Shell и оценкой CVSS 9.2. Авторизация атакующему не нужна: достаточно отправить запрос на сайт. О попытках атак сообщили сразу после выхода исправлений.
Уязвимость сидит в самом интерпретаторе, поэтому под угрозой любой сайт на PHP, какая бы CMS на нём ни стояла. У нас на обслуживании интернет-магазины на 1С-Битрикс, сервис аналитики на Laravel, магазин на Drupal и сайт на старой версии движка, на разных серверах и хостингах. Ниже рассказываем, как мы их проверили, что обновили и где легко ошибиться.
Кого касается
- Любого PHP, который отвечает на веб-запросы: Apache с mod_php, PHP-FPM, php-cgi, LiteSpeed, FrankenPHP.
- Выше всего риск у mod_php: атака срабатывает раньше, чем начинает работать код сайта.
- Исправлены ветки 8.2–8.5. Для 7.4, 8.0 и 8.1 официальных релизов нет, есть только исходные патчи для самостоятельной сборки.
- В дистрибутивах номер версии может остаться прежним. В Ubuntu 24.04 исправленная сборка называется 8.3.6-0ubuntu0.24.04.13, в Debian 12 — 8.2.35-1~deb12u1.
Шаг 1: осмотр только на чтение
До любых изменений прошли по каждому серверу из списка доступа и собрали факты одним скриптом. Скрипт ничего не меняет, только читает:
- все установленные версии PHP, а не только ту, что отвечает на php -v;
- как PHP подключён к веб-серверу: модулем Apache или через FPM;
- из какого репозитория пришли пакеты и есть ли исправление в журнале изменений пакета;
- есть ли PHP внутри Docker-контейнеров;
- какие лимиты PHP действуют на самом деле.
Что показал осмотр. Четыре сайта работали на уязвимой версии. На одном хостинг уже обновил PHP сам. На нескольких серверах PHP не оказалось вовсе. Для сайтов на виртуальных хостингах и серверах, куда у нас нет прямого доступа, подготовили пошаговую инструкцию проверки.
Шаг 2: обновление без остановки продаж
Обновляли только внутри той же ветки PHP, например 8.2.x до 8.2.35. Совместимость кода при таком обновлении не меняется, поэтому магазины дорабатывать не пришлось. На каждом сервере порядок был одинаковый:
- бэкап конфигов PHP и веб-сервера, списка установленных пакетов и свежий дамп базы;
- пробный прогон установки, чтобы увидеть, что именно поменяется;
- обновление только пакетов PHP, без общего обновления системы;
- перезапуск Apache или PHP-FPM и фоновых обработчиков очереди;
- проверка: версия, журнал изменений пакета, страницы сайта, логи ошибок, служебный healthcheck.
$ apt-get -s install --only-upgrade $(dpkg-query -W -f='${Package}\n' 'php8.2*')$ zgrep -c 109618 /usr/share/doc/php8.2-common/changelog.Debian.gz$ grep -l 'libphp.*(deleted)' /proc/[0-9]*/maps | wc -l
Это команды для Debian и Ubuntu. Первая делает пробный прогон обновления только для пакетов PHP 8.2. Вторая ищет исправление в журнале изменений пакета. Третья считает процессы, которые ещё работают на старой библиотеке PHP; после перезапуска веб-сервера должно получиться 0.
Три сервера обновили, на четвёртом поставили временные меры. С бэкапами на всё ушло около 10 минут. Сайт недоступен только на несколько секунд, пока перезапускается веб-сервер. Служебные проверки до и после обновления дали одинаковый результат.
Где легко ошибиться
- Пакет обновился, а сайт всё ещё уязвим. Apache держит старую библиотеку PHP в памяти до перезапуска: на одном сервере после установки пакетов 19 процессов продолжали работать со старой версией.
- Автообновления сработали не везде. На одном сервере пакеты Debian обновились сами, на другом нет: apt выбирал версию из стороннего репозитория, а автообновления берут только репозитории Debian.
- Обновление расширения тянет за собой новую версию PHP. Пробный прогон показал, что обновление расширения redis через метапакет заодно ставит PHP 8.5. Обновили только нужные пакеты.
- В php.ini одно значение, а сайт видит другое. В основном php.ini лимит загрузки 8 МБ, а дополнительный конфиг поднимал его до 1 ГБ. Смотрите действующее значение, а не один файл.
- Консольный PHP и PHP сайта — разные программы. На одном хостинге команда php запускала версию 5.6, а сайт работал на 8.2. Проверять нужно ту версию, которая обслуживает сайт.
- Пакет PHP 7.4 из популярного стороннего репозитория вышел в день исправления, но этого исправления в нём нет: в журнале изменений только исправления из 8.2.34.
Сайт на PHP 7.4: временные меры и переход на PHP 8
Для PHP 7.4 исправленной сборки нет. Сразу перевести сайт на PHP 8 нельзя: в коде движка есть функции, удалённые в PHP 8, и движок сначала нужно обновить.
Поэтому в тот же вечер поставили меры из рекомендаций разработчиков PHP. Отключили отслеживание прогресса загрузки. Лимит размера запроса в PHP и nginx снизили с 1 ГБ до 64 МБ, а лимиты форм, через которые клиенты присылают файлы, оставили как были. Такие меры снижают риск, но обновление не заменяют. Поэтому сайт переводим на PHP 8 через копию: обновляем движок, проверяем на PHP 8.2 и 8.3, а переключаем по согласованию с владельцем.
Попутные находки
- Сервер, где PHP не обновлялся 19 месяцев. Вместе с исправлением PHP2Shell на него пришли и все пропущенные за это время исправления безопасности.
- Шесть записей в списке доступа вели на серверы, которые давно отданы другим владельцам: у них сменился ключ. Подключаться к ним нельзя, записи нужно удалить.
- На части серверов автообновления выключены или не берут пакеты из сторонних репозиториев PHP.
Как проверить свой сайт
- Узнайте версию PHP, которая обслуживает сайт: через phpinfo, заголовок X-Powered-By или панель хостинга. Консольная версия может отличаться.
- Сравните её с исправленными: 8.5.12, 8.4.27, 8.3.36, 8.2.35. Если PHP стоит из пакетов дистрибутива, ищите CVE-2026-109618 в журнале изменений пакета.
- На PHP 8.1 и старше исправления от разработчиков PHP нет. Нужен переход на поддерживаемую ветку или сборка с исправлением от поставщика дистрибутива.
- После обновления перезапустите Apache или PHP-FPM, иначе продолжит работать старый код.
- На виртуальном хостинге PHP обновляет хостер. Проверьте, что сайт работает на поддерживаемой ветке, и при необходимости переключите её в панели.
Не уверены, какая версия PHP на самом деле работает на сайте и как обновить её без простоя? Напишите нам: проверим в режиме только просмотра и обновим по согласованию.
Вопросы, которые задают в такой ситуации
Что такое PHP2Shell?
Так называют две критические уязвимости в ядре PHP, CVE-2026-109618 и CVE-2026-109619, исправленные 21 октября 2026 года. Через них можно без авторизации выполнить свой код на сервере. Затронут любой PHP, который обслуживает веб-запросы, какая бы CMS ни стояла на сайте.
Какие версии PHP исправлены?
8.5.12, 8.4.27, 8.3.36, 8.2.35 и более новые. В дистрибутивах исправление может прийти в сборке со старым номером версии, например 8.3.6-0ubuntu0.24.04.13 в Ubuntu 24.04. Поэтому смотрите журнал изменений пакета.
Есть ли исправление для PHP 7.4, 8.0 и 8.1?
Официальных релизов нет. Разработчики PHP опубликовали исходные патчи для самостоятельной сборки, часть дистрибутивов и LTS-поставщиков выпускает свои сборки. Пакет 7.4 из популярного стороннего репозитория, вышедший 21 октября, исправления не содержал. Надёжный путь — переход на PHP 8.2 и новее.
Нужно ли менять код сайта при обновлении?
При обновлении внутри той же ветки, например 8.2.x до 8.2.35, не нужно: совместимость не меняется. Переход с 7.4 на 8.x — другое дело, его готовят на копии сайта.
Можно ли обойтись настройками вместо обновления?
Только на время. Разработчики PHP перечисляют меры, которые перекрывают известные пути атаки: отключить session.upload_progress, ограничить размер запросов. Полной защиты эти меры не дают, они нужны лишь до обновления.
Сколько занимает обновление?
У нас около 10 минут на три сервера и временные меры на четвёртом, вместе с бэкапами. Сайт недоступен только на несколько секунд, пока перезапускается веб-сервер. Дольше всего занимает осмотр: нужно выяснить, какой PHP на самом деле обслуживает каждый сайт.
Кейс обезличен: проекты, домены, хостинги и адреса серверов не называются. Время и версии взяты из журналов серверов.