PHP2Shell: CVE-2026-109618 и CVE-2026-109619 — обновление PHP
PHP2Shell: обновление PHP и проверка защиты
Проверено 26 октября 2026 года, Asia/Yekaterinburg (UTC+5). Бюллетени и исправленные upstream-релизы опубликованы 21 октября. Это инструкция по двум CVE, а не сообщение о новой атаке 26 октября или о взломе конкретного сайта.
Приоритет — обновить сам PHP и заменить работающие процессы. Обновление CMS, плагинов, WAF или одного CLI-интерпретатора не подтверждает исправление веб-сайта. На VPS и выделенном сервере действие выполняет ответственный администратор; для managed/shared-хостинга нужно подтверждение провайдера по используемой версии и пулу.
Основа — бюллетень PHP от 21 октября и два отдельных advisory разработчиков. Команды ниже — примеры для разрешённой инфраструктуры, не сканер и не автоматическое обновление production.
Что исправлено и кого касается
| Уязвимость | Суть | Оценка PHP |
|---|---|---|
| CVE-2026-109618 / GHSA-w8hw-w9fx-j79w | Ошибки обработки нехватки памяти могут оставить внутренние данные запроса в некорректном состоянии | 9,2, CVSS v4.0 |
| CVE-2026-109619 / GHSA-6wmf-4rv5-p3rp | Рабочий процесс может сохранить ссылки на освобождённое состояние предыдущего запроса и использовать их в следующем | 9,2, CVSS v4.0 |
Возможен удалённый запуск кода без предварительной авторизации, с правами веб-воркера, не автоматически root. PHP указывает на риск для веб-установок PHP-FPM, Apache mod_php, php-cgi, FrankenPHP и LiteSpeed. CMS не определяет наличие ошибки в интерпретаторе; это касается и самописных приложений.
Наиболее сильное подтверждение независимой от приложения эксплуатации относится к mod_php: обработка может произойти до запуска кода сайта. Для FPM подтверждён сценарий CVE-2026-109619, зависящий от операций приложения. Это не основание считать FPM безопасным и не доказательство одинаковой эксплуатируемости всех конфигураций. Источники: условия OOM-уязвимости, условия stale-state-уязвимости.
Обычная страница входа CMS не изолирует PHP от входящих запросов. При невозможности быстро исправить критичный публичный сервис ограничивайте доступ до интерпретатора — на reverse proxy, балансировщике или сетевом уровне, включая прямой доступ к origin. Это эксплуатационное решение с влиянием на доступность, которое согласует владелец сервиса.
Исправленные версии: сравнивать внутри своей ветки
Минимальные upstream-релизы для этих двух CVE, выпущенные 21 октября:
| Ветка | Уязвимые upstream-релизы ветки | Первый исправленный релиз |
|---|---|---|
| 8.2 | 8.2.0–8.2.34 | 8.2.35 |
| 8.3 | 8.3.0–8.3.35 | 8.3.36 |
| 8.4 | 8.4.0–8.4.26 | 8.4.27 |
| 8.5 | 8.5.0–8.5.11 | 8.5.12 |
Таблица сверена с обоими advisory выше. Например, 8.3.35 не становится исправленной потому, что численно выше 8.2.35. Более поздний стабильный security-релиз своей поддерживаемой ветки предпочтительнее устаревшего минимума; prerelease/RC не подставляется вместо production-релиза.
Старые PHP и backport-пакеты
PHP 8.1 и старше не получают обычных upstream-обновлений. PHP отдельно предоставил минимальные исходные backport-исправления для 7.4, 8.0 и 8.1. Это не возобновление поддержки этих веток. Проверенный пакет поставщика ОС/LTS либо переход на совместимую поддерживаемую ветку предпочтительнее неподготовленной сборки из исходников. При собственной сборке нужно учитывать расширения, параметры сборки, полное применение исправлений и замену работающих процессов. Источник PHP.
Фраза «для старых PHP есть только исходники» относится к предоставленным PHP backport, не ко всем дистрибутивам. На дату проверки Ubuntu указывает исправленные пакеты, например 8.1.2-1ubuntu2.28 для Ubuntu 22.04 и 8.3.6-0ubuntu0.24.04.13 для 24.04; доступность старых веток может зависеть от Ubuntu Pro. Низкий upstream-номер сам по себе не доказывает отсутствие патча. Проверять нужно обе записи: Ubuntu / 109618, Ubuntu / 109619.
Для Debian tracker перечисляет, в частности, 8.2.35-1~deb12u1 в bookworm-security и 8.4.27-1~deb13u1 в trixie-security. Эти номера нельзя переносить на Ubuntu, сторонний репозиторий или контейнер. Debian / 109618, Debian / 109619.
Remi: исправления уже объявлены
22 октября Remi объявил PHP 8.2.35, 8.3.36, 8.4.27 и 8.5.12 в remi-modular, а также Software Collections в remi-safe. Поэтому утверждение «в Remi обновления пока нет» на дату этой проверки устарело. Официальная публикация Remi.
Это не означает, что пакет автоматически выбран вашим сервером: проверьте ОС, архитектуру, подключённый stream, исключения и pinning. Не меняйте ветку PHP через module switch-to только ради совпадения с чужим примером.
Для CloudLinux различайте native PHP, alt-php и ea-php: сверяйте полную версию пакета и соответствующий канал, а не только вывод php -v. Сводка поставщика. Отсутствие CVE в одном changelog не является универсальным тестом отсутствия исправления.
Порядок обновления
1. Сопоставить каждый сайт с его PHP
Зафиксируйте для каждого домена: reverse proxy → сокет/порт FastCGI либо обработчик → FPM-служба/контейнер → пакет или образ → источник исправления. Отдельно учтите фоновые CLI-процессы, очереди и несколько установленных веток.
Безопасная инвентаризация в оболочке:
cat /etc/os-release
php -v
php --ini
php -r 'printf("version=%s\nsapi=%s\n", PHP_VERSION, PHP_SAPI);'
systemctl list-unit-files --type=service --no-pager \
| grep -Ei 'php.*fpm|apache2|httpd|frankenphp|lsws' || true
systemctl применим к systemd-системе, не к любому контейнеру. Эти команды не устанавливают пакеты и не перезапускают службы. Вывод CLI не подтверждает версию обслуживающего сайт процесса. Веб-версию проверяйте отдельно после обновления.
Для Debian/Ubuntu:
# Отсутствие совпадающего пакета может вернуть ненулевой код.
dpkg-query -W -f='${binary:Package}\t${Version}\n' 'php*' 'libapache2-mod-php*'
# Пример: адаптируйте имена под уже установленную ветку.
apt-cache policy php8.4-fpm php8.4-cli php8.4-common
Для RPM-систем:
rpm -qa --qf '%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\n' \
| grep -E '^(php|alt-php|ea-php)'
dnf repolist
Сохраните приватный отчёт с точными пакетами, источником и датой проверки. Не публикуйте конфигурации с секретами, клиентские IP и полные диагностические дампы.
2. Подготовить восстановление и установить исправление
Проверьте пригодную резервную копию файлов и БД, сохраните конфигурацию PHP и список расширений. Подготовьте короткие функциональные проверки и окно перезапуска. При активном риске совместите подготовку с ограничением внешнего доступа, а не оставляйте уязвимый сервис открытым на время длительного тестирования.
Установите проверенные пакеты из уже выбранного доверенного источника, согласованно обновляя интерпретатор и установленные расширения. Сначала просмотрите план транзакции, исключите неожиданные удаления, смену ветки или репозитория. Универсальная команда обновления для apt, Remi SCL, панельной сборки и контейнера здесь намеренно не приводится.
Для контейнера обновляется образ, затем пересоздаются контейнеры и все реплики; изменение тега в Dockerfile без пересборки/развёртывания недостаточно. Для встроенного PHP нужно обновить содержащий его бинарник/образ. Откат к уязвимой сборке не считается безопасным восстановлением: при проблеме совместимости оставьте доступ ограниченным до исправления.
3. Заменить действительно работающие процессы
| Способ запуска | Что проверить и перезапустить после установки |
|---|---|
| PHP-FPM | Все используемые версии и пулы; убедиться, что прежние воркеры завершились |
| Apache mod_php | Процессы Apache с обновлённым модулем; перезапуск отдельного FPM здесь ничего не меняет |
| php-cgi / FastCGI | Запускающий их менеджер и оставшиеся долгоживущие процессы |
| FrankenPHP | Сервис/бинарник или контейнер с нужной встроенной версией PHP и его worker-процессы |
| LiteSpeed / LSAPI | Используемый lsphp и процессы external application по процедуре установленной панели/сервера |
| Docker / Kubernetes | Все экземпляры исправленного образа, включая фоновые задачи и старые реплики |
Это контрольный план, а не выполненная проверка перечисленных платформ. PHP требует перезапуска воркеров после защитных изменений; настройки FPM описаны в официальном руководстве.
Пример только для стандартной systemd-установки PHP 8.4 FPM, после обновления её пакетов. Перезапуск прерывает активные запросы; прежде проверьте правильность имени службы, согласуйте окно и завершите/перенаправьте текущую нагрузку:
sudo php-fpm8.4 -t &&
sudo systemctl restart php8.4-fpm &&
sudo systemctl is-active php8.4-fpm
Для Remi SCL, панели управления и другой ветки имена отличаются. Не выполняйте этот блок вслепую. Перезагрузка только Nginx не заменяет PHP-воркеры. Аналогично проверьте долгоживущие Laravel Queue/Horizon/Octane и другие фоновые процессы после обновления их runtime.
Временные меры: не заменяют исправление
Применяются лишь до обновления с пониманием влияния на загрузки файлов, сессии и доступность. После установки патча не объявляйте сайт безопасным только по наличию этих строк.
php.ini и FPM pool — разный синтаксис
Пример для php.ini используемого веб-интерпретатора:
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 4M
; Только PHP 8.5, если обновление пока невозможно:
; fatal_error_backtraces = 0
Альтернативный фрагмент в существующей секции нужного пула FPM:
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 4M
; Только для пула PHP 8.5:
; php_admin_flag[fatal_error_backtraces] = off
Не вставляйте первый блок как обычные директивы в pool-файл. php_admin_* исключает переопределение через ini_set(); после проверки конфигурации замените все воркеры. Синтаксис FPM, описание session-настроек.
session.upload_progress.enabled нужно отключить до разбора запроса. Для этой защиты не подходят ini_set() и FPM .user.ini: изменение на позднем этапе не перекрывает ранний путь обработки. Отключение прогресса загрузки не означает запрета всех файловых загрузок. fatal_error_backtraces=0 относится только к PHP 8.5 и лишь к одному пути эксплуатации CVE-2026-109619. Ошибки приложения и устаревшие INI-настройки, вызывающие ранние diagnostics, также требуют исправления; скрытие ошибок не защищает. Advisory stale state.
Для необходимых загрузок PHP предлагает рассмотреть post_max_size=32M, сохраняя upload_max_filesize ниже него. Это компромисс, не защитная константа. Согласуйте ограничения с веб-сервером/proxy и проверьте обычные формы, API и загрузки. Одного лимита тела недостаточно против всех вариантов исчерпания памяти. Рекомендации PHP.
Отдельно об OOM и memory_limit
В актуальном advisory CVE-2026-109618 описана временная административная установка memory_limit=-1: она убирает контролируемый отказ по лимиту PHP, но не отказ системного выделения памяти. Это не полное исправление, и снятие лимита может исчерпать память сервера.
Поэтому memory_limit=-1 не включено в блок для безусловного копирования. Такое решение требует отдельного плана ограничения ресурсов контейнером/cgroup, оценки того, какой процесс будет завершён, и проверки всех переопределений. PHP прямо не рекомендует подменять этот механизм RLIMIT_AS/RLIMIT_DATA, которые могут вызвать уязвимый путь отказа выделения памяти. Без проверенной изоляции предпочтительнее обновление или временное ограничение доступа до PHP, а не бессистемная смена лимитов.
Дополнение PHP от 23 октября: upload progress после патча
PHP отдельно предупредил о редком сценарии с переключением обработчика сериализации сессий во время запроса и обозначил CVE-2026-115560. На дату проверки рекомендуется оставить session.upload_progress.enabled=0 до следующего обычного bugfix-релиза, если ранее мера была включена. Это другая проблема, не утверждение, что исправления двух CVE от 21 октября отсутствуют. Условия и дальнейшее исправление следует сверять с информационным бюллетенем PHP от 23 октября.
Как подтвердить результат без эксплуатации уязвимости
Для каждого сайта сохраните раздельно: package_patch_status, running_web_runtime, temporary_mitigations, functional_checks. Значение неизвестно лучше ложного «исправлено» по одному HTTP-заголовку.
Версию веб-процесса и эффективные настройки можно получить через существующую закрытую диагностику. При необходимости минимальный временный фрагмент ниже размещают только за заранее проверенным ограничением доступа на proxy/сети, не на публичном URL. Проверьте запрет и прямого origin. Не публикуйте phpinfo(); после проверки удалите диагностику и убедитесь, что она больше не доступна.
<?php
// Только закрытая диагностика; этот фрагмент сам не реализует авторизацию.
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
echo json_encode([
'version' => PHP_VERSION,
'sapi' => PHP_SAPI,
'session.upload_progress.enabled' => ini_get('session.upload_progress.enabled'),
'post_max_size' => ini_get('post_max_size'),
'upload_max_filesize' => ini_get('upload_max_filesize'),
'memory_limit' => ini_get('memory_limit'),
'fatal_error_backtraces' => PHP_VERSION_ID >= 80500
? ini_get('fatal_error_backtraces') : null,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), PHP_EOL;
Этот вывод не вычисляет статус CVE и не определяет backport по номеру PHP. В CLI он проверяет только CLI. В балансируемой установке отдельно проверяют каждую реплику/пул и отсутствие старых воркеров: случайное попадание в один новый процесс недостаточно.
Контроль после обновления:
- Runtime: оба CVE закрыты подтверждённым пакетом/сборкой; веб-процессы и фоновые задачи используют его, а не только CLI в оболочке.
- Приложение: главная, типовая статья, вход в админку, форма, штатная небольшая загрузка, API, cron/очереди; для WordPress/Laravel проверить фоновые задания и ошибки PHP.
- SEO и HTTP: ожидаемые тело и статус ответа, sitemap, robots.txt, canonical; GET через CDN и разрешённый origin. Один
200от кеша не подтверждает работу PHP. - Безопасность: изучить доступные логи и изменения файлов/учётных записей. Патч не удаляет уже созданное закрепление и не отзывает утёкшие секреты. При признаках компрометации изолировать сервис, сохранить доказательства и выполнить отдельное восстановление/ротацию с доверенной среды.
Не используйте RCE-PoC, исчерпание памяти или массовую отправку multipart-запросов для проверки рабочего сайта. Отсутствие ошибок в логах и наличие WAF не подтверждают исправление интерпретатора.
Границы проверки материала
Первоисточники прочитаны 26 октября 2026 года. Локально проверены четыре Bash-блока через bash -n, синтаксис двух INI-фрагментов и диагностического PHP-примера. На CLI PHP 8.4.24 выполнен только безвредный вывод диагностики: с отдельным временным php.ini подтверждены отключение upload progress и значения 8M/4M. Это проверка примера, не безопасности этого runtime; эксплуатация CVE не воспроизводилась. PHP 8.5, применение настроек в настоящем FPM-пуле, установка пакетов и веб-проверки не тестировались. Production-команды, миграции, перезапуски и настройки пользовательских сайтов не выполнялись.
Проверка защиты требует одновременно сведений о пакете поставщика и фактически работающей веб-сборке. При последующем обновлении статьи сверяйте новые advisory и не распространяйте статус этих двух CVE на все будущие уязвимости PHP.
Первоисточники
- PHP: security advisory 21 октября и информационное дополнение 23 октября.
- PHP: CVE-2026-109618.
- PHP: CVE-2026-109619.
- Remi: исправленные RPM от 22 октября.
- Debian: CVE-2026-109618 и CVE-2026-109619.
- Ubuntu: CVE-2026-109618 и CVE-2026-109619.
- CloudLinux: состояние пакетов.
- PHP: FPM configuration и session configuration.
