Что произошло
21 октября 2026 года разработчики PHP выпустили внеочередные версии 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Они закрывают две критические уязвимости в самом интерпретаторе: CVE-2026-109618 и CVE-2026-109619. Исследователи назвали их PHP2Shell. Через них можно выполнить свой код на сервере без логина и пароля, отправив сайту специально подготовленные запросы.
Ошибка находится в PHP, а не в коде сайта. Поэтому под угрозой оказывается любой сайт на уязвимой версии: WordPress, Битрикс, самописный проект и даже страница из одной строки. Обновление CMS, тем и плагинов уязвимость не закрывает. Помогает только исправленная сборка PHP и перезапуск процессов, которые его выполняют.
- Узнайте версию. Посмотрите, какая сборка PHP обслуживает сайт, а не только что выводит команда в терминале.
- Обновите PHP. Установите исправленный выпуск своей ветки или пакет дистрибутива с исправлением.
- Перезапустите процессы. Без перезапуска PHP-FPM или Apache сайт продолжит работать на старом коде.
- Проверьте журналы. Ищите следы атак с 20 октября и смените пароли и ключи, если они найдутся.
Сведения об уязвимостях утекли до официальной даты публикации, и по данным Cloudflare атаки на сайты уже идут. Откладывать обновление не стоит.
Какие версии PHP уязвимы
В официальном уведомлении PHP перечислены поддерживаемые ветки. Уязвимы все выпуски ниже исправленного номера:
| Ветка PHP | Уязвимые версии | Исправлено в |
|---|---|---|
| 8.5 | ниже 8.5.12 | 8.5.12 |
| 8.4 | ниже 8.4.27 | 8.4.27 |
| 8.3 | ниже 8.3.36 | 8.3.36 |
| 8.2 | ниже 8.2.35 | 8.2.35 |
| 8.1, 8.0, 7.4 | все | Официальных выпусков нет, только исходные патчи для самостоятельной сборки |
| 7.3 и старше | по данным Cloudflare, все начиная с 5.4 | Исправлений от PHP нет |
Тестовая версия PHP 8.6.0 RC4 тоже содержит исправления, более ранние тестовые сборки 8.6 уязвимы. Для старых веток команда PHP из-за серьёзности проблемы подготовила минимальные патчи к исходному коду PHP 7.4, 8.0 и 8.1. Готовых сборок для этих веток PHP не выпускает, но их выпускают некоторые дистрибутивы Linux. Об этом ниже.
Ветка 8.2 перестанет получать исправления безопасности 31 декабря 2026 года. Если сайт работает на ней, после срочного обновления запланируйте переход на 8.3 или новее.
Чем опасна уязвимость и кого она касается
Обе ошибки связаны с тем, как PHP убирает за собой после сбоя. Когда обработка запроса обрывается из-за нехватки памяти или фатальной ошибки, часть внутренних данных остаётся недоделанной или указывает на уже освобождённую память. Злоумышленник подбирает запросы так, чтобы вызвать такой сбой, а затем подсовывает PHP свои данные вместо испорченных.
| Уязвимость | Что ломается | Где подтверждена атака |
|---|---|---|
| CVE-2026-109618 | PHP заканчивает память при разборе отправленной формы с файлами и завершает запрос с наполовину заполненными данными | mod_php: атака срабатывает ещё до запуска кода сайта |
| CVE-2026-109619 | После сбоя один запрос оставляет ссылки на освобождённую память, и следующий запрос к тому же процессу ими пользуется | mod_php и PHP-FPM |
Обе получили 9,2 балла из 10 по шкале CVSS 4.0. Разработчики PHP относят к группе риска все установки, которые обрабатывают запросы к сайтам: PHP-FPM, модуль Apache mod_php, php-cgi, FrankenPHP и LiteSpeed. Сильнее всего рискует mod_php, а работа через PHP-FPM атаку усложняет, но не исключает.
Исследователи на сайте PHP2Shell показали захват свежих установок WordPress, Drupal и Joomla без входа в админку. Кроме выполнения команд, ошибка позволяет прочитать память процесса PHP. В ней бывают пароли от базы данных, токены входа, ключи API и сертификаты, причём не только ваши, но и данные чужих запросов, которые обрабатывал тот же процесс.
Сайт на обычном хостинге
PHP обновляет хостинг. Ваша задача — убедиться, что он это сделал: посмотрите версию в панели или спросите поддержку, обновлена ли сборка PHP и перезапущены ли процессы.
Свой сервер или VPS
Обновлять PHP придётся самостоятельно или поручить администратору. Обновление сайта через админку CMS не трогает PHP на сервере.
Сайт в контейнере
PHP находится внутри образа Docker. Нужно пересобрать образ на исправленной версии и пересоздать контейнеры.
Облачный сервис или конструктор
Если сайт работает в облачном сервисе и доступа к серверу у вас нет, PHP обновляет сам сервис. Следите за его новостями о сроках.
Как проверить, исправлен ли PHP на сервере
Просто сравнить номер версии с таблицей выше получится не всегда. У одного сервера бывает несколько установленных версий PHP, а дистрибутивы Linux часто исправляют уязвимость, не меняя номер. Поэтому сначала выясните, какой PHP обслуживает сайт.
Версия, на которой работает сайт
На хостинге номер версии виден в панели управления, обычно в разделе настроек PHP или сайта. В WordPress откройте «Инструменты» → «Здоровье сайта» → «Информация» → «Сервер»: там указана версия PHP. Универсальный способ — временный файл с функцией phpinfo. Создайте его в папке сайта:
<?php phpinfo(); Откройте https://ваш-сайт/info.php и посмотрите две строки. PHP Version показывает номер версии, Server API показывает способ запуска: «Apache 2.0 Handler» означает mod_php, самый рискованный вариант, «FPM/FastCGI» означает PHP-FPM. Сразу после проверки удалите файл: phpinfo показывает пути и настройки сервера, которые пригодятся взломщику.
Команда php -v в терминале показывает версию PHP для командной строки. Сайт может работать на другой версии, установленной рядом, поэтому сверяйтесь с тем, что показывает сам сайт или пакет, из которого запущен PHP-FPM или Apache.
Почему исправленный PHP может показывать старый номер
Debian и Ubuntu не переходят на новый выпуск PHP, а переносят исправление в свою версию. Такой перенос называется бэкпортом. Например, в Ubuntu 24.04 после обновления php -v по-прежнему показывает 8.3.6, хотя пакет уже защищён. Проверять нужно номер пакета. Исправленные пакеты на 21 октября 2026 года по данным трекеров Debian и Ubuntu:
| Система | Пакет | Исправленная версия пакета |
|---|---|---|
| Ubuntu 26.10 | php8.5 | 8.5.9-0ubuntu2.1 |
| Ubuntu 26.04 LTS | php8.5 | 8.5.4-0ubuntu1.5 |
| Ubuntu 24.04 LTS | php8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 LTS | php8.1 | 8.1.2-1ubuntu2.28 |
| Ubuntu 20.04 LTS | php7.4 | 7.4.3-4ubuntu2.29+esm5, только с подпиской Ubuntu Pro |
| Debian 13 trixie | php8.4 | 8.4.27-1~deb13u1 |
| Debian 12 bookworm | php8.2 | 8.2.35-1~deb12u1 |
В Red Hat, AlmaLinux, Rocky Linux и Fedora статус ищите в трекере Red Hat. В репозитории Remi пакеты повторяют номера PHP, поэтому для них подходит основная таблица выше.
Скрипт для проверки сервера
Чтобы не собирать сведения вручную, запустите на сервере скрипт ниже. Он только читает данные и ничего не меняет, это видно по коду. Скрипт показывает версию PHP, установленные пакеты и упоминание исправления в их журнале изменений, время запуска процессов PHP-FPM и Apache и временные меры защиты, которые уже записаны в настройках.
#!/bin/sh
# Проверка PHP после PHP2Shell (CVE-2026-109618, CVE-2026-109619).
# Скрипт только читает сведения о системе и ничего не меняет.
echo "== PHP в командной строке"
if command -v php >/dev/null 2>&1; then
php -r '
$fixed = ["8.2" => "8.2.35", "8.3" => "8.3.36", "8.4" => "8.4.27", "8.5" => "8.5.12"];
$branch = PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;
echo "Версия: ", PHP_VERSION, "\n";
if (isset($fixed[$branch])) {
echo version_compare(PHP_VERSION, $fixed[$branch], ">=")
? "Номер исправленный\n"
: "Номер ниже " . $fixed[$branch] . ": для сборки с php.net это уязвимая версия, для пакета дистрибутива сверьте версию пакета\n";
} elseif (version_compare($branch, "8.2", "<")) {
echo "Ветка без официальных обновлений: нужен патч поставщика или переход на 8.2+\n";
}
'
else
echo "Команда php не найдена"
fi
echo
echo "== Пакеты PHP"
if command -v dpkg-query >/dev/null 2>&1; then
pkgs=$(dpkg-query -W -f='${Package} ${Version}\n' 2>/dev/null | grep -E '^(php[0-9.]*-(common|fpm|cgi|cli)|libapache2-mod-php[0-9.]*) ')
fixed=$(zgrep -l 'CVE-2026-10961[89]' /usr/share/doc/php*-common/changelog.Debian.gz 2>/dev/null)
elif command -v rpm >/dev/null 2>&1; then
pkgs=$(rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE}\n' 'php*')
fixed=$(for pkg in $(rpm -qa 'php*common*'); do rpm -q --changelog "$pkg" | grep -q 'CVE-2026-10961[89]' && echo "$pkg"; done)
elif command -v apk >/dev/null 2>&1; then
pkgs=$(apk info -v 2>/dev/null | grep -E '^php[0-9]*-(common|fpm|cli|apache2)-[0-9]')
fi
echo "${pkgs:-Пакеты PHP не найдены}"
[ -n "$fixed" ] && echo "$fixed" | sed 's/^/Исправление упомянуто в журнале: /'
echo
echo "== Запущенные процессы, которые выполняют PHP"
echo "Процесс, запущенный раньше обновления, работает со старым кодом: перезапустите его"
procs=$(ps -eo lstart=,args= 2>/dev/null || ps -o args 2>/dev/null)
procs=$(echo "$procs" | grep -E 'php-fpm: master|apache2|httpd|frankenphp|litespeed|lshttpd' | grep -v grep)
echo "${procs:-Не найдено}"
echo
echo "== Временные меры в файлах настроек"
conf=$(grep -RHsE \
'^[[:space:]]*(php_admin_value|php_value|php_admin_flag|php_flag)?[[:space:][]*(session\.upload_progress\.enabled|fatal_error_backtraces|memory_limit|post_max_size)' \
/etc/php* /etc/opt/remi /usr/local/etc/php* /etc/apache2 /etc/httpd 2>/dev/null | grep -v 'php\.ini-')
echo "${conf:-Настройки не найдены}"
Сохраните код в файл и запустите обычной командой. Для сайта в контейнере передайте скрипт внутрь контейнера:
sh php2shell-check.sh
# сайт в контейнере
docker exec -i имя-контейнера sh -s < php2shell-check.sh Строка «Исправление упомянуто в журнале» означает, что установленный пакет Debian или Ubuntu содержит патч, даже если номер PHP старый. Если время запуска процесса раньше времени обновления пакетов, процесс работает со старым кодом и его нужно перезапустить. Утилиты, которые сравнивают только номер версии из заголовков сайта или php -v, на пакетах дистрибутивов ошибаются: исправленный сервер они считают уязвимым.
Как обновить PHP
Устанавливайте исправленный выпуск той ветки, на которой уже работает сайт: 8.3 на 8.3, 8.4 на 8.4. Переход на новую ветку меняет поведение языка и может сломать сайт, его лучше делать отдельно и после проверки. Перед обновлением сделайте резервную копию сайта, базы данных и настроек сервера.
Debian и Ubuntu
Обновите пакеты, затем перезапустите службу, которая выполняет PHP. Имя службы PHP-FPM содержит номер ветки, например php8.3-fpm.
sudo apt update
sudo apt upgrade
# PHP-FPM: подставьте свою ветку
sudo systemctl restart php8.3-fpm
# Apache с mod_php
sudo systemctl restart apache2Если PHP установлен из стороннего репозитория, например deb.sury.org, команды те же: исправленные пакеты придут из него.
Red Hat, AlmaLinux, Rocky Linux, Fedora
sudo dnf upgrade 'php*'
sudo systemctl restart php-fpm
# если используется Apache
sudo systemctl restart httpdЕсли в подключённых репозиториях исправленной сборки пока нет, её можно взять из Remi: там сборки всех поддерживаемых веток вышли в день публикации.
Docker
Официальные образы php обновляются по тегам вроде php:8.3-fpm. Если в Dockerfile указан точный номер, например php:8.3.30-fpm, замените его на исправленный. Затем пересоберите образ со свежей базой и пересоздайте контейнеры:
docker compose build --pull
docker compose up -dWindows
Скачайте исправленную сборку со страницы загрузок PHP, замените файлы PHP, сохранив свой php.ini, и перезапустите веб-сервер.
Хостинг
Если в панели можно выбрать сборку PHP, выберите исправленную версию своей ветки. Если такой возможности нет, напишите в поддержку и попросите подтвердить, что PHP обновлён и все процессы перезапущены.
После обновления обязательно перезапустите PHP-FPM или Apache: уже запущенные процессы продолжают выполнять старый код PHP. Перезапуск одного nginx процессы PHP-FPM не обновляет.
Если сайт работает на PHP 7.4, 8.0 или 8.1 и пакета с исправлением для вашей системы нет, остаются три пути: исправления от поставщика дистрибутива, например Ubuntu Pro или Debian LTS, самостоятельная сборка с патчами PHP или переход на поддерживаемую ветку. Последний вариант дольше, но избавляет от той же проблемы при следующей уязвимости.
Если обновить сразу нельзя
Полностью защищает только обновление. Меры ниже из рекомендаций разработчиков PHP закрывают известные пути атаки, но не все. Самое надёжное временное решение — закрыть сайт от доступа из интернета до обновления.
; Временные меры до обновления, они не заменяют обновление
session.upload_progress.enabled = 0
; только для PHP 8.5
fatal_error_backtraces = 0
; 32M, если сайт принимает файлы
post_max_size = 8M
upload_max_filesize = 2M- session.upload_progress.enabled отключает отслеживание загрузки файлов, через которое подтверждена одна из атак. Эта функция почти нигде не используется, и разработчики советуют держать её выключенной даже после обновления.
- fatal_error_backtraces нужен только в PHP 8.5: он убирает путь атаки, на котором построен самый надёжный из показанных эксплойтов.
- post_max_size ограничивает размер отправленной формы. Разработчики советуют 8M для сайтов без загрузки файлов и 32M, если загрузка нужна. upload_max_filesize должен быть меньше.
Задавайте эти значения в php.ini, настройках пула PHP-FPM через php_admin_value и php_admin_flag или в конфигурации Apache, а затем перезапустите все процессы PHP. Вызов ini_set() в коде и файлы .user.ini не помогают: они срабатывают позже, чем атака.
Ещё несколько мер для администраторов:
- memory_limit = -1 убирает лимит памяти PHP, на исчерпании которого построена первая атака. Взамен ограничьте память процессов средствами системы через cgroup или лимиты контейнера, иначе один запрос сможет занять всю память сервера. Лимиты
RLIMIT_ASиRLIMIT_DATAиспользовать нельзя: они сами вызывают уязвимый сбой. - Если сайт не принимает формы с файлами, блокируйте такие запросы на веб-сервере или прокси до того, как они дойдут до PHP.
- pm.max_requests = 1 в PHP-FPM заставляет каждый процесс обработать один запрос и завершиться. Это мешает второй атаке, но заметно снижает скорость сайта.
- WAF помогает выиграть время. Cloudflare включил правила против PHP2Shell для всех тарифов с WAF, включая бесплатный, но сам называет их дополнительной защитой, а не заменой обновлению.
Скрывать ошибки через display_errors, error_reporting или символ @ бесполезно: уязвимый код срабатывает раньше, чем PHP решает, показывать ли сообщение.
Как понять, не взломали ли сайт
Проверьте журналы веб-сервера, PHP-FPM и системы начиная с 20 октября. Признаки, на которые стоит обратить внимание:
- процесс веб-сервера запускает командную оболочку,
curl,wgetили другие программы, которые сайту не нужны; - сообщения о нехватке памяти
Allowed memory size … exhaustedна запросах с отправкой форм; - необъяснимые падения процессов PHP, например записи PHP-FPM о завершении дочернего процесса по сигналу;
- повторяющиеся фатальные ошибки и
Maximum execution time exceededна одних и тех же адресах; - новые или изменённые PHP-файлы в папках сайта, которых вы не загружали.
Чистые журналы не доказывают, что взлома не было: разработчики PHP предупреждают, что сбой может произойти раньше, чем PHP запишет сообщение. Если признаки нашлись, обновите PHP, восстановите сайт из копии, сделанной до появления признаков, и смените все секреты, которые хранились на сервере: пароли базы данных и админки, ключи API, почтовые и платёжные токены. Новые пароли удобно создать в генераторе паролей. О том, каким должен быть пароль, рассказано в статье «Как придумать надёжный пароль».
Частые вопросы
Нужно ли что-то делать посетителям сайтов?
Нет. Уязвимость находится на сервере, через браузер она посетителю не вредит. Риск в другом: если взломанный сайт хранил ваши данные, они могли утечь. Если сервис сообщит о взломе, смените пароль от него и везде, где использовали такой же.
Касается ли уязвимость PHP на компьютере разработчика?
Скрипты в командной строке не принимают запросы из сети, поэтому описанные атаки к ним не относятся. Встроенный сервер для разработки php -S в списке разработчиков PHP не упомянут, но он тоже обрабатывает запросы: не открывайте его для доступа из сети и обновите PHP при следующей возможности.
Можно ли сразу перейти на PHP 8.4 или 8.5?
Можно, но не вместо срочного обновления. Смена ветки меняет поведение языка, и старые темы, плагины или модули могут перестать работать. Сначала установите исправленный выпуск текущей ветки, а переход проверьте на копии сайта. Ветка 8.2 перестанет получать исправления 31 декабря 2026 года, поэтому с ней переход стоит запланировать в ближайшее время.
Что делать, если хостинг ещё не обновил PHP?
Напишите в поддержку и спросите, когда будет установлена исправленная сборка и перезапущены процессы PHP. Если в панели уже доступна исправленная версия вашей ветки, переключитесь на неё сами. Если сайт хранит важные данные, а сроков нет, на время закройте его режимом обслуживания или паролем на уровне веб-сервера.












