AI и агенты23 мин чтения

Критическая уязвимость PHP: как обновить версию и защитить сайт

Две критические уязвимости PHP с удалённым выполнением кода. Как узнать и обновить версию PHP до 8.2.35–8.5.12 на хостинге, VPS и в Docker — пошагово.

Критическая уязвимость PHP: как обновить версию и защитить сайт
Содержание

Команда безопасности PHP сделала то, что делает редко: предупредила о патче заранее. Двадцатого октября в рассылке php.announce и на главной php.net появилось сообщение — 21 октября в 14:00 UTC выйдет внеплановое обновление, которое закрывает две критические уязвимости. Обе оценены в 9.2 по CVSS версии 4.0. Ни описания, ни номеров CVE, ни списка затронутых версий в анонсе не было: всё обещали опубликовать вместе с патчем.

Патч вышел даже раньше обещанного — разборы уязвимостей появились в 13:34 UTC, за двадцать с небольшим минут до срока.

Короткий ответ, если нужен только он: обновитесь до 8.2.35, 8.3.36, 8.4.27 или 8.5.12 — в зависимости от вашей ветки. Обе дыры — удалённое выполнение кода без авторизации, и от CMS это не зависит. Дальше — подробности и то, что делать, если «просто обновиться» в вашем случае не работает.

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

Что такое PHP и почему это касается вас

Короткая вводная для тех, кто про PHP слышал, но никогда им не занимался. Это язык, на котором работают многие популярные CMS — WordPress, Joomla, Drupal, Bitrix, OpenCart — и большинство самописных сайтов небольших компаний. Работает он не в браузере, а на сервере: когда кто-то открывает страницу, сервер запускает PHP-код и отдаёт готовый HTML.

Из этого следует две вещи. Первая: дыра в самом PHP — это дыра не в одном плагине и не в одной теме, а в фундаменте, на котором стоит сайт целиком. Вторая: если сайт раздаёт только готовые файлы — статика на Astro, Hugo, Tilda, Webflow, обычный лендинг из HTML, — PHP в этой схеме нет. Правда, у витрины может оказаться соседний сервис или отдельная админка на PHP, так что при сомнениях лучше спросить разработчика или хостера.

Почему о патче предупредили заранее

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

Логика, судя по формулировкам анонса, такая: дать администраторам время подготовиться. Если обновление выходит внезапно, крупной инфраструктуре нужны сутки только на организационную часть — согласовать окно, предупредить клиентов, собрать образы. Если предупредить за день, к моменту релиза план уже есть. Платить за это приходится тем, что предупреждение читают обе стороны.

В анонсе отдельно оговорено: если детали станут публичными или появятся признаки реальных атак, релиз выпустят раньше назначенного времени. Это, по сути, страховка от собственного предупреждения.

Что означает 9.2 и почему это много

CVSS — отраслевая шкала технической серьёзности от 0 до 10. Диапазон 9.0–10.0 называется критическим, и 9.2 попадает в него.

Но важно понимать, чего это число не говорит. Оно не говорит, каким способом уязвимость эксплуатируется, какие версии задеты, нужна ли особая конфигурация и включён ли уязвимый модуль у вас. Бывает, что критическая по шкале уязвимость живёт в расширении, которого на большинстве серверов просто нет. И оно не говорит о вероятности того, что сломают именно ваш сайт. Без описания 9.2 — основание отнестись серьёзно, а не основание считать, что вас уже взломали. В этом случае описание появилось вместе с патчем, и оно оказалось неприятным — о нём следующий раздел.

Вторая деталь: это оценка по версии 4.0 — довольно новой редакции методики. По третьей версии те же дыры могли бы получить другую цифру, так что расхождения в публикациях стоит сверять не только по числу, но и по методике.

Что за уязвимости: CVE-2026-109618 и CVE-2026-109619

Номера, гулявшие по сети ещё до релиза, оказались настоящими: это CVE-2026-109618 и CVE-2026-109619, обе помечены как критические. Исправленные версии по веткам:

Ветка PHP Уязвимы версии Обновляться до
8.2 ниже 8.2.35 8.2.35
8.3 ниже 8.3.36 8.3.36
8.4 ниже 8.4.27 8.4.27
8.5 ниже 8.5.12 8.5.12
7.4, 8.0, 8.1 все сборки без патча пакет от поставщика или бэкпорт в исходниках от команды PHP
7.3 и старше в разборе не указаны поставщик пакетов или переход на поддерживаемую ветку

Обе — удалённое выполнение кода без авторизации, с правами того пользователя, под которым работает веб-сервер. И обе про одно и то же: про память, которая переживает границу запроса.

Первая, «RCE via OOM corruption», — про исчерпание памяти. Когда запрос упирается в лимит, PHP выходит из текущего контекста коротким путём. В некоторых точках память запроса в этот момент видна, но ещё не достроена, и аварийный выход оставляет её в недопустимом состоянии; процедура завершения запроса потом в это состояние заглядывает. Команда PHP в своём разборе пишет, что полное выполнение кода подтверждено по HTTP против mod_php при настройках по умолчанию.

Вторая, «RCE via stale global state», — про состояние, которое воркер хранит между запросами: ошибки, сессии, объекты, расширения. Часть операций выполняется раньше обычной инициализации следующего запроса и успевает обратиться к данным, оставшимся от предыдущего и уже освобождённым. Это обращение к освобождённой памяти, а при удачно разложенной куче — тоже выполнение кода. Здесь подтверждены и mod_php, и FPM. Важная деталь: запрос, который оставляет мусор, и запрос, который на него натыкается, должны попасть в один воркер — несколько воркеров и перезапуск процессов снижают шанс, но проблему не снимают.

Что из этого следует практически. Оба случая не требуют ни учётной записи на сайте, ни действий посетителя. Оба не зависят от CMS: дыра не в WordPress и не в плагине, а в самом PHP, так что «у меня простой сайт, там и ломать нечего» здесь не работает.

И ещё одна деталь из разбора второй дыры — она отвечает на возражение «у меня на сайте даже сессий нет». Одно из звеньев подтверждённой цепочки — отслеживание прогресса загрузки, session.upload_progress. Оно включено по умолчанию и срабатывает без всякого session_start() в коде сайта. То есть сайту не нужно самому работать с сессиями, чтобы это звено у него было.

Про слухи — и почему на них всё равно не стоило опираться

Отдельно стоит зафиксировать, как выглядела эта история до релиза, потому что следующая будет выглядеть так же.

До выхода патча команда PHP подтверждала ровно четыре вещи: внеплановый релиз, дату и время, две уязвимости и оценку 9.2 по CVSS v4.0. Номеров CVE, описания и списка версий в уведомлении не было. Всё остальное — номера, слово RCE, «задеты все версии начиная с PHP 5», оценка «10.0 по CVSS» — ходило по соцсетям из анонимного пересказа со ссылкой на «надёжный источник».

Номера и RCE в итоге подтвердились. Но это не значит, что им стоило верить заранее: в тот момент проверить их было нечем, и ровно так же выглядят слухи, которые не подтверждаются. Из подтвердившегося, кстати, не всё: охват «начиная с PHP 5» официально не подтверждён — в разборах перечислены поддерживаемые ветки, а бэкпорты команда выпустила для 7.4, 8.0 и 8.1, не старше; оценка осталась 9.2, а не 10.0.

Следом по сети пошёл и «рабочий эксплойт» — архив с проверочным скриптом. Ондржей Сури, мейнтейнер самого популярного репозитория PHP-пакетов для Debian и Ubuntu, предупредил: архив никто не проверял, он похож на собранный нейросетью, при неверных параметрах он просто роняет процесс, и относиться к нему стоит как к недоверенному. Вывод для владельца сайта простой: никаких «проверок на уязвимость» скриптами из соцсетей на своём сервере. Это классический способ занести себе что-то похуже самой дыры.

Почему тянуть с обновлением опаснее, чем раньше

Прямого измерения «сколько времени проходит от патча PHP до первых атак» у меня нет, и честнее сказать об этом сразу. Но общая экономика атак за последний год изменилась, и это измерено.

В разборе исследования NorForge про открытые панели Cairn я приводил цифры из кампании против интернет-магазинов: средняя стоимость обработки одной цели — около 25 долларов, подбор жертв автоматический, по трафику, доля успешных попыток около десяти процентов, меньше суток от запуска до результата. Похожую механику со стороны мошеннических сервисов видно в докладе про фишинг на ИИ.

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

Как обновить PHP: пошаговый план для владельца сайта

Начните с диагностики, она нужна всем и занимает минуты. Потом — ваш случай.

Шаг 1. Как узнать версию PHP на своём сайте

Проверить версию PHP проще всего в панели управления хостингом. В cPanel это MultiPHP Manager, в FASTPANEL — карточка сайта и её настройки PHP, в ispmanager — настройки домена. Имейте в виду две вещи: настройка может распространяться сразу на несколько сайтов, а версия для консоли выбирается отдельно от версии, на которой работает сайт.

Если сайт на WordPress, версия видна в админке: Инструменты → Здоровье сайта → вкладка «Информация» → раздел «Сервер». Названия разделов немного отличаются от версии к версии. Там же WordPress предупреждает об устаревшей ветке — но отсутствие предупреждения не означает, что конкретный патч установлен.

На своём сервере есть ловушка, на которой спотыкаются регулярно. Команда php -v показывает версию консольного PHP, а сайт работает через отдельный процесс — PHP-FPM, и версия у него может быть другой. Более того, версий FPM на машине может быть несколько, и разные сайты могут обслуживаться разными. Что именно обслуживает конкретный сайт, видно в конфигурации веб-сервера — по сокету или порту в fastcgi_pass:

grep -rn fastcgi_pass /etc/nginx/
systemctl list-units 'php*-fpm.service'

Первая команда покажет, к какому сокету обращается сайт, вторая — какие FPM-сервисы на машине вообще запущены. Сопоставив их, вы получите ответ на вопрос «какой у меня PHP» — тот, который действительно имеет значение.

Шаг 2. Кто обновляет PHP: хостинг, свой сервер или Docker

Обычный или управляемый хостинг. Обновлять PHP будет хостер, сами вы этого сделать не можете. Ваша задача — не ждать молча. Посмотрите раздел новостей или статуса у провайдера, а лучше напишите в поддержку прямым вопросом: какая версия PHP обслуживает мой домен, установлено ли обновление безопасности от 21 октября (8.2.35, 8.3.36, 8.4.27 или 8.5.12), а если нет — когда будет, и нужно ли что-то с моей стороны. Сроки у хостеров различаются радикально, от нескольких часов до ближайшего планового обслуживания, и ответ на этот вопрос — единственный способ узнать свой.

Частый вопрос владельцев WordPress — как обновить PHP из админки. Никак: WordPress только показывает версию в «Здоровье сайта», а меняется она в панели хостинга. Внутри одной ветки — с 8.3.35 на 8.3.36 — это делает хостер, и обычно такое обновление проходит незаметно. Но «обычно» не гарантия: после него стоит открыть сайт и проверить формы и оплату, как в пятом шаге. Если же нужно переехать на другую ветку, например с 7.4 или 8.1 на поддерживаемую, сначала обновите WordPress, тему и плагины: именно старые плагины чаще всего ломаются на новой версии PHP.

Свой VPS или выделенный сервер. Первым делом выясните, откуда у вас вообще пакеты PHP: от этого зависит, когда придёт исправление.

Если из стороннего репозитория Ондржея Сури — packages.sury.org для Debian или ppa:ondrej/php для Ubuntu, а на серверах с несколькими версиями PHP это почти всегда он, — исправления там собираются в день релиза. Мейнтейнер пообещал их для всех веток, что есть в репозитории, и для всех поддерживаемых релизов Debian и Ubuntu: сначала для обычных серверов на amd64, сборки для ARM — позже. Сроков он не называл, сборочный сервер в тот день был перегружен.

Если PHP из штатных репозиториев дистрибутива, исправление придёт через обычные обновления безопасности — но не сразу. Вечером 21 октября у Ubuntu все затронутые пакеты стояли в статусе «требует оценки», а в трекере Debian записей по этим CVE ещё не было. В таком случае временные меры из раздела ниже — не опция, а то, что нужно сделать, пока пакет не вышел.

Что установлено и что доступно, покажут эти команды:

sudo apt update
apt list --upgradable
apt-cache policy php8.3-fpm   # подставьте свою версию
apt-mark showhold

В выводе apt-cache policy первая строка — установленная версия, вторая — кандидат на обновление, а ниже видно, из какого репозитория он придёт. apt-mark showhold проверяет ловушку: пакеты, которые кто-то когда-то «заморозил», не обновятся ни разом, ни точечно, и выглядеть это будет так, будто обновлять нечего. Если PHP в этом списке — снимите заморозку через sudo apt-mark unhold с именами пакетов.

Снимите резервную копию до того, как выполните следующую команду, а не после: про бэкап подробно в четвёртом шаге, но делается он здесь. Обновление, которое поссорилось с расширением, откатывать уже нечем.

Если в списке только пакеты PHP, можно обновлять всё разом (sudo apt upgrade). Если там же лежит половина системы, которую вы сегодня трогать не планировали, — обновите точечно, перечислив свои пакеты PHP вместе с расширениями:

sudo apt install --only-upgrade php8.3-fpm php8.3-cli php8.3-common

Дальше нужно перезапустить те FPM-сервисы, которые обслуживают сайты, — все, если версий несколько:

sudo systemctl restart php8.3-fpm

Nginx при этом трогать не нужно: он обращается к FPM по сокету, и обновление PHP его конфигурацию не меняет. Перечитывать конфигурацию стоит, только если вы её правили, и тогда сначала sudo nginx -t. Если же PHP у вас подключён модулем к Apache (mod_php), а не через FPM, перезапускать нужно сам Apache — модуль живёт внутри его процессов.

Отдельно — долгоживущие PHP-процессы вне FPM: Laravel Octane, Swoole, RoadRunner, обработчики очередей и демоны под supervisor. Они держат в памяти ту версию PHP, с которой стартовали, и обновлённый пакет на диске их не касается. Перезапустите и их — в первую очередь те, что сами принимают HTTP-запросы.

Для RHEL, AlmaLinux и Rocky порядок тот же через dnf, обычно с подключённым репозиторием Remi.

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

Сначала загляните в Dockerfile и compose.yaml и посмотрите, как записана версия. Если там FROM php:8.3-fpm, свежий образ подтянется. А если версия прибита гвоздями — php:8.3.35-fpm или ссылка по digest, — никакая команда вас с неё не сдвинет: тег указывает на конкретную сборку, и --pull честно проверит обновления именно для неё. Такую строку нужно руками поменять на исправленную версию, и только потом обновляться.

Дальше зависит от того, как собран сервис. Если у вас свой Dockerfile с FROM php:...:

docker compose build --pull php
docker compose up -d php

Если в compose.yaml указан готовый образ через image::

docker compose pull php
docker compose up -d php

Здесь php — имя сервиса из вашего Compose-файла, подставьте своё. Ключ --pull важен: без него сборка может взять старый базовый образ из локального кеша, и --no-cache эту проблему не решает — он пересобирает слои, но не обновляет базу. А если образы собираются в CI, помните, что сборка — это половина дела: новый образ ещё нужно опубликовать и выкатить, работающий контейнер сам не обновится.

И отдельная ловушка, из-за которой сайт может лечь уже после успешного обновления. Если nginx у вас в соседнем контейнере и ходит в PHP по имени сервиса (fastcgi_pass php:9000), то пересозданный контейнер получит новый адрес, а nginx продолжит стучаться по старому — и вместо сайта вы увидите 502. Лечится перезапуском фронтенда следом:

docker compose restart nginx

Проверить результат внутри контейнера:

docker compose exec php php -v

Шаг 3. Какая версия PHP актуальна и не осталась ли ваша без поддержки

Это отдельный и, на мой взгляд, самый важный пункт для небольших сайтов.

Актуальные версии PHP — те, что поддерживает сам проект: сейчас это 8.2, 8.3, 8.4 и 8.5. Последняя стабильная — 8.5, а 8.6 пока на стадии релиз-кандидатов и для боевого сайта не годится. Ветка 8.1 и всё, что старше, объявлены end of life: обычных релизов для них команда PHP больше не выпускает. На этот раз она сделала исключение — об этом чуть ниже.

Важная оговорка, без которой пункт звучит страшнее, чем есть. Дистрибутивы и коммерческие поставщики часто сопровождают старые ветки сами: Debian, Ubuntu и RHEL переносят исправления безопасности в свои пакеты в течение жизненного цикла релиза ОС. Поэтому сайт на PHP 7.4 из системного репозитория может получить исправление от поставщика ОС — а может и нет. Узнать это можно только у того, кто вам эти пакеты поставляет: у хостера, у вендора ОС или у подрядчика.

Исключение сделала и сама команда PHP. Из-за серьёзности уязвимостей она выложила минимальные бэкпорты исправления в исходниках для трёх снятых с поддержки веток: PHP 7.4, PHP 8.0 и PHP 8.1 в репозитории php-src. Важно понимать, что это такое. Это не релизы: новых номеров версий и готовых пакетов не будет, патч нужно собрать самому. Адресованы они тем, кто собирает PHP из исходников, или тем, у кого нет поставщика, сопровождающего старую ветку. Владельцу сайта на обычном хостинге они не помогут — там вопрос по-прежнему к хостеру. И к PHP 7.3 и более старым это не относится.

Хороший пример — тот же репозиторий sury. Исправление этих двух CVE там обещано для всех веток, что в нём есть, а не только для поддерживаемых командой PHP. По сообщениям пользователей, в день релиза обновления пришли и для 7.4, 8.0 и 8.1, и даже для 5.6. Это не повод оставаться на 7.4: следующую дыру в старой ветке может закрыть уже никто. Но в моменте это ответ на вопрос «что делать прямо сейчас».

Полезно посмотреть и на календарь поддержки. У ветки 8.2 исправления безопасности заканчиваются 31 декабря 2026 года — через два месяца она окажется там же, где сейчас 8.1. У 8.3 срок до конца 2027 года, у 8.4 — до конца 2028-го, у 8.5 — до конца 2029-го. Если вы на 8.2, миграцию стоит готовить сейчас: выбрать ветку, совместимую с вашей CMS, плагинами и расширениями, и протестировать переход до конца года, а не в последнюю неделю декабря.

Для сайта на EOL-ветке порядок действий такой: сначала резервная копия и понятный способ вернуться назад, потом проверка на копии сайта, и только потом переключение боевого. Само по себе переключение версии в панели не равно установке патча — убедитесь, что переезжаете на свежую сборку поддерживаемой ветки, а не на прошлогоднюю.

Шаг 4. Бэкап до обновления — и проверка, что он разворачивается обратно

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

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

И отдельный момент, про который вспоминают поздно: бэкап должен быть защищён от удаления той же учётной записью, из-под которой работает сайт. В разборе кампании против интернет-магазинов у одной из жертв автоматика снесла заодно и таблицы с резервными копиями.

Шаг 5. Как проверить, что обновление установилось

После обновления посмотрите версию обслуживающего сайт процесса и полный номер установленного пакета. Нюанс: если исправление пришло от поставщика ОС, номер версии PHP может не измениться вовсе — меняется номер пакета. В этом случае подтверждением служит бюллетень поставщика, а не вывод php -v.

Дальше откройте сайт — и не только главную. Админка, форма оплаты, загрузка файлов, отправка почты: это те места, где всплывает несовместимое расширение. И загляните в журнал ошибок веб-сервера: он покажет то, чего не видно на странице.

Что делать, если обновить PHP прямо сейчас нельзя

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

Для первой дыры, про исчерпание памяти, основная настройка — административно задать memory_limit=-1 и перезапустить все воркеры. Да, снять лимит, а не ужесточить: именно предсказуемый лимит на запрос делает подтверждённый сценарий управляемым. Перед этим стоит честно оценить, выдержит ли сервер запросы без потолка по памяти, и проверить, что ни один пул, каталог или настройка приложения не возвращает конечный лимит обратно. Там же отдельное предостережение: не ограничивать память через RLIMIT_AS и RLIMIT_DATA — они приводят ровно к тому отказу выделения памяти, который и запускает уязвимый путь. Лимит памяти контейнера или cgroup — возможная замена, но с оговорками и тоже не полная.

Полезно и то, что снижает риск даже после патча: держать post_max_size скромным, проверять реальный размер тела запроса на фронтенде, уменьшить вложенность и количество входных переменных, а если приложение вообще не принимает multipart-формы — резать такие запросы до того, как они дойдут до PHP. В nginx это несколько строк внутри блока server:

if ($http_content_type ~* "multipart") {
    return 403;
}

Цена этой меры — перестанет работать любая загрузка файлов и формы, которые отправляют данные как multipart. Прежде чем включать, пройдитесь по формам сайта.

Для второй дыры, про состояние между запросами, общей настройки нет вовсе — это тоже сказано прямо. Частные меры: на PHP 8.5 выключить fatal_error_backtraces, всем — выключить session.upload_progress.enabled, если он не нужен (команда PHP советует оставить его выключенным и после обновления: функция редкая и плохо обкатанная), и перезапустить воркеры. Если производительность позволяет, помогает pm.max_requests=1 — воркер живёт один запрос и не успевает ничего унести в следующий. И стоит разобраться с фатальными ошибками и предупреждениями на путях, куда дотягивается посетитель: именно они оставляют тот самый мусор.

«Административно» в этих советах — важное слово. Настройки задаются там, где приложение не сможет их переопределить: в php.ini или в пуле FPM. Например, так:

; /etc/php/8.3/fpm/pool.d/www.conf — подставьте свою версию и пул
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1
; только для PHP 8.5
php_admin_flag[fatal_error_backtraces] = off

После правки — перезапуск FPM. А вот .htaccess с php_value и php_flag и параметр PHP_VALUE, который nginx передаёт в FastCGI, для этого не годятся. Команда PHP прямо советует предпочитать настройки, которые применяются при старте: значения, приходящие с каждым запросом, обрабатываются раньше его инициализации, и устаревшая директива, выдающая там предупреждение, — одно из звеньев второй цепочки. Старые и неверные директивы оттуда стоит вычистить совсем.

И чего не делать даже в панике — «выключать PHP» в веб-сервере. Если убрать обработчик, nginx или Apache начнут отдавать файлы .php как обычный текст, вместе с паролями к базе из конфигов. Если сайт нужно закрыть на время обновления, пусть веб-сервер отвечает кодом 503.

Дальше — обычная гигиена, которая была актуальна и до этой истории.

Сократите то, что торчит наружу. Админка, доступная откуда угодно, phpMyAdmin на стандартном адресе, забытый тестовый поддомен с копией сайта — всё это лишняя поверхность. Про порты, файрвол и то, что стоит закрывать по умолчанию, я подробно писал в статье про безопасный старт сервиса в Docker. Ограничивая доступ, не отрежьте заодно себя и нужные интеграции: учтите мобильный интернет с меняющимся адресом и платёжные уведомления, которые приходят извне.

Посмотрите на WAF, если он есть в тарифе хостинга или у вас подключён Cloudflare: детали опубликованы, и поставщики защиты на такие вещи реагируют — стоит проверить, появилось ли правило и включено ли оно. Но имейте в виду, что обе дыры срабатывают на обычных с виду запросах, так что ждать от фильтра многого не нужно. И WAF работает, только если до сервера нельзя достучаться в обход него: если IP сайта известен и открыт для всех, фильтр на Cloudflare просто обойдут.

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

И назначьте себе срок. «Обновимся, когда будет время» — худший вариант: он превращает временные меры в постоянные.

Как проверить, не было ли взлома

Детали дыр утекли за сутки до патча, а выполнение кода по HTTP подтвердила сама команда PHP. При этом на момент публикации подтверждённых сообщений о массовых атаках не было: заявления о них ходили, но публичных данных за ними никто не показал. Паниковать рано, а посмотреть — самое время, особенно если сайт до обновления был открыт всем.

Что смотреть в первую очередь:

  • процессы веб-сервера: php-fpm или Apache, которые запускают командную оболочку, — плохой знак;
  • новые и изменённые .php-файлы в корне сайта и особенно в каталогах загрузок;
  • задания планировщика — crontab -l от имени пользователя веб-сервера и каталоги /etc/cron.*: закрепиться там — стандартный приём;
  • журнал доступа: всплески POST-запросов с multipart/form-data к страницам, которые загрузку вообще не принимают.

Свежие PHP-файлы за последние три дня можно найти одной командой (путь — свой):

find /var/www -name '*.php' -mtime -3 -ls

Если что-то нашлось, одного обновления мало: доступ, который уже получен, патч не отзывает. Нужны смена паролей и ключей, ревизия файлов и, скорее всего, восстановление из копии, снятой до проблем.

Чеклист: обновление PHP за десять шагов

Коротко, в порядке выполнения:

  1. Узнать, какой PHP обслуживает сайт: панель хостинга, «Здоровье сайта» в WordPress или fastcgi_pass плюс список FPM-сервисов.
  2. Если сайт раздаёт только готовые файлы и серверного кода нет — дальше не читать.
  3. Проверить ветку: нужны 8.2.35, 8.3.36, 8.4.27 или 8.5.12 — всё, что ниже, уязвимо. На 7.4–8.1 — пакет от поставщика или бэкпорт команды PHP для сборки из исходников; на ещё более старых — только поставщик или переезд.
  4. Определить, кто обновляет: хостер или вы.
  5. На хостинге — спросить поддержку про домен, патч и действия с вашей стороны.
  6. На своём сервере — понять, откуда пакеты (sury или дистрибутив), проверить apt-mark showhold, сделать бэкап, обновить пакеты PHP, перезапустить все FPM-сервисы и долгоживущие PHP-процессы.
  7. В Docker — проверить, не прибита ли версия в теге, пересобрать с --pull или подтянуть готовый образ, передеплоить, перезапустить фронтенд, проверить версию внутри контейнера.
  8. После обновления — версия, номер пакета, сайт целиком (админка, оплата, почта), журнал ошибок.
  9. Если обновиться нельзя — временные меры из разборов PHP в php.ini или пуле FPM, сократить внешнюю поверхность, назначить дату. PHP в веб-сервере не выключать — отдавать 503.
  10. Если сайт был открыт до обновления — проверить процессы, свежие файлы, задания cron и журнал доступа.

Что из этого останется

Конкретные две уязвимости закроются, и через неделю про них забудут. Останется другое.

Первое: инвентаризация. Самый дорогой ответ на вопрос «вы обновились?» — это «а где у нас вообще PHP?». Список того, где у вас крутится серверный код, с версиями и ответственными, собирается один раз, а потом поддерживается — и в такие дни экономит часы.

Второе: мёртвые ветки. PHP 7.4 давно не поддерживается командой PHP, и без отдельного сопровождения поставщика в нём остаются неисправленные дыры. Внеплановый патч — хороший повод посмотреть на цифру версии и поставить переезд в план, пока он не стал срочным.

И третье, менее очевидное. Само предупреждение за сутки — признание того, что скорость установки патчей стала важнее тишины вокруг уязвимости. Со стороны владельца сайта правильный ответ на это — не паника в день релиза, а заранее известный порядок: кто обновляет, в какое окно, с каким бэкапом и как проверяется результат. Один раз описать это дешевле, чем каждый раз импровизировать.


Статья написана по уведомлению команды безопасности PHP от 20.10.2026, разборам уязвимостей GHSA-w8hw-w9fx-j79w и GHSA-6wmf-4rv5-p3rp в репозитории php-src, журналу изменений PHP 8, ответам мейнтейнера репозитория deb.sury.org и данным Ubuntu Security.

Источники

  1. php.net — анонс внепланового релиза безопасности, 20.10.2026
  2. Рассылка php.announce — [ANNOUNCE] Upcoming Critical PHP Security Release
  3. php.net — Security advisory: Critical remote code execution vulnerabilities, update now, 21.10.2026
  4. GHSA-w8hw-w9fx-j79w — RCE via OOM corruption (CVE-2026-109618), разбор php-src
  5. GHSA-6wmf-4rv5-p3rp — RCE via stale global state (CVE-2026-109619), разбор php-src
  6. PHP 8 ChangeLog — версии 8.2.35, 8.3.36, 8.4.27, 8.5.12
  7. PHP: Supported Versions — сроки поддержки веток
  8. deb.sury.org, issue #145 — Upcoming Critical PHP Security Release, ответы мейнтейнера
  9. Ubuntu Security — CVE-2026-109618, статус пакетов
  10. Mattias Geniar — PHP CVE-2026-109618: early mitigation, 21.10.2026
  11. Qualys — PHP Announces Critical Security Release for Two Vulnerabilities, 20.10.2026
  12. Help Net Security — A critical PHP security release is coming today, 21.10.2026
  13. Laravel News — Critical PHP Security Release Coming Tomorrow, 20.10.2026
Свои рядомСпросите своих — в чате отвечают быстрее, чем поискОсновной чат IT-тусовки Паттайи: айтишники, диджитал-специалисты и предприниматели, которые уже прошли через то же самое. С июля 2023 года.Вступить в чатНужны батыОбмен рублей и USDT на баты — внутри сообществаIT ОБМЕН работает с 2023 года: рубли с любого банка РФ и по СБП, USDT с Bybit и Binance. Наличные привезут по Паттайе, переведут на тайский счёт или выдадут через банкомат. Курс обновляется каждый день.Условия и курс

Читайте также по теме