PHP2Shell: две критические уязвимости закрыли, но следом обнаружили ещё одну
23 октября 2026 года команда PHP выпустила дополнительное предупреждение для администраторов серверов: до следующего регулярного обновления рекомендуется отключить отслеживание прогресса загрузки файлов. Причина - ещё один потенциальный сценарий удалённого выполнения кода, получивший идентификатор CVE-2026-115560.
Предупреждение появилось через два дня после исправлений PHP2Shell - двух критических уязвимостей самого интерпретатора. Обновления для них уже вышли, но новая проблема затрагивает отдельное сочетание настроек сессий и кода приложения. Поэтому даже сервер с установленной исправленной версией PHP может нуждаться в дополнительной настройке.
У трёх уязвимостей разные механизмы. CVE-2026-109618 связана с нехваткой памяти при обработке запроса, CVE-2026-109619 - с использованием устаревшего внутреннего состояния, а CVE-2026-115560 возникает при определённом переключении обработчика сериализации сессий. Разберём, что именно происходит и какие меры рекомендуются, если немедленно обновить все серверы не получается.
CVE-2026-109618: ошибка при нехватке памяти
Первая уязвимость возникает, когда PHP не может выделить необходимую память во время обработки запроса. Такая ситуация называется out-of-memory (OOM). Обычно подобная ошибка приводит к прерыванию операции, но в этом случае проблема заключается в том, что происходит дальше.
При обработке запроса PHP создаёт внутренние структуры и постепенно заполняет их данными. Если выделение памяти завершается ошибкой, выполнение может прерваться до того, как подготовка этих структур будет закончена. Затем интерпретатор запускает очистку ресурсов. Код очистки рассчитан на определённое состояние данных, но после аварийного прерывания оно может оказаться неполным.
В результате PHP обращается к неинициализированным данным так, словно они уже готовы к использованию. Это создаёт условия для повреждения памяти и дальнейшего выполнения кода атакующего.
Речь не о том, что любая нехватка памяти позволяет захватить сервер. Для эксплуатации необходимо попасть в уязвимый путь обработки запроса и добиться подходящего состояния памяти. Но исследователи продемонстрировали удалённое выполнение кода через этот дефект, в том числе в конфигурации Apache с mod_php, где уязвимый путь доступен до выполнения кода приложения.
Поэтому обычная проверка входных данных в CMS не всегда помогает: если интерпретатор доходит до проблемного участка раньше, чем запускается прикладной код, приложение не успевает применить собственные проверки.
CVE-2026-109619: внутреннее состояние переживает освобождение памяти
У второй уязвимости другая причина. PHP может сохранить ссылки на данные запроса после того, как память, в которой они находились, уже освобождена. Последующее обращение к такой памяти называется use-after-free.
Проблема становится особенно интересной при повторном использовании рабочего процесса. Например, PHP-FPM обслуживает множество HTTP-запросов через пул процессов. После завершения одного запроса процесс может принять следующий, не запускаясь заново. Если внутреннее состояние не было корректно сброшено, в процессе остаются ссылки на память, которая уже не принадлежит прежним данным.
Следующий запрос может задействовать эти устаревшие ссылки до того, как обычная инициализация обновит состояние. Содержимое освобождённой области памяти к этому моменту может измениться, поэтому PHP рискует работать с данными, не соответствующими ожидаемой структуре.
Исследователи продемонстрировали удалённое выполнение кода через такие сценарии. В частности, риск связан с обработкой сессий и прогресса загрузки, а в PHP 8.5 - также с определённым путём формирования трассировки при фатальной ошибке. Это объясняет, почему временные меры для CVE-2026-109619 включают несколько отдельных настроек, а не только отключение одной функции.
Обе первоначальные уязвимости получили оценку CVSS 9.2. Они затрагивают PHP, обслуживающий веб-запросы, включая PHP-FPM, Apache с mod_php, php-cgi, FrankenPHP и LiteSpeed. Риск зависит от конфигурации и поведения приложения; наиболее высокий приоритет разработчики рекомендуют отдавать Apache mod_php, для которого был продемонстрирован путь эксплуатации до запуска кода приложения.
Какие версии PHP исправлены
21 октября команда PHP выпустила исправления для четырёх веток:
- PHP 8.5.12;
- PHP 8.4.27;
- PHP 8.3.36;
- PHP 8.2.35.
Эти версии устраняют CVE-2026-109618 и CVE-2026-109619. Они не исправляют появившуюся позднее CVE-2026-115560: для неё PHP обещает выпустить исправление в рамках следующего регулярного обновления.
Обновление CMS, фреймворка или плагинов не заменяет обновление самого интерпретатора. При этом версия, которую показывает команда php -v, может отличаться от той, что обрабатывает запросы сайта. На одном сервере могут одновременно работать CLI-PHP, PHP-FPM с отдельным бинарным файлом и PHP внутри контейнера.
Если PHP установлен через репозиторий Linux-дистрибутива или предоставлен хостингом, проверяйте уведомление поставщика. Исправление может быть включено в пакет без изменения номера версии в соответствии с официальным релизом PHP. Важно подтвердить не только наличие исправленного пакета, но и то, что его действительно использует работающий веб-сервис.
CVE-2026-115560: когда переключение обработчика сессий становится опасным
Новое предупреждение от 23 октября касается взаимодействия двух настроек PHP: session.upload_progress.enabled и session.serialize_handler.
Первая включает отслеживание хода загрузки файлов. PHP сохраняет сведения о процессе загрузки в сессии, а приложение может использовать эти данные для отображения прогресс-бара. Вторая определяет, в каком формате PHP сохраняет и восстанавливает данные сессии.
Для возникновения CVE-2026-115560 требуется конкретная последовательность действий. В конфигурации должен использоваться обработчик php_binary или php_serialize, после чего приложение переключает его на php с помощью ini_set() до вызова session_start(). При этом отслеживание прогресса загрузки должно оставаться включённым.
Если приложение не меняет session.serialize_handler во время выполнения, описанный сценарий к нему не относится. Поэтому не следует считать каждый PHP-сайт автоматически уязвимым к новой проблеме. Но и полагаться на предположение, что в коде такого переключения нет, не стоит: его можно проверить поиском вызовов ini_set() и анализом порядка запуска сессии.
Полное техническое описание CVE-2026-115560 команда PHP планирует опубликовать со следующим регулярным выпуском. До выхода исправления рекомендуется отключить session.upload_progress.enabled. Эта настройка одновременно устраняет необходимое условие для описанного сценария и перекрывает подтверждённые пути эксплуатации CVE-2026-109619, связанные с прогрессом загрузки.
Временные меры: что делать, если обновить PHP пока нельзя
Обновление исправленной сборки остаётся единственным полноценным решением. Временные меры предназначены для снижения риска на серверах, которые нельзя немедленно обновить. Их нужно применять с учётом конфигурации: некоторые изменения влияют на загрузку файлов, использование памяти и обработку запросов.
1. Отключите отслеживание прогресса загрузки
В конфигурации, применяемой к веб-запросам, задайте:
//ini
session.upload_progress.enabled = 0Это основная временная мера для подтверждённых сценариев CVE-2026-109619, связанных с сессиями, а также для CVE-2026-115560. Параметр следует задавать на уровне php.ini, пула PHP-FPM или серверной конфигурации, которая применяется до начала разбора запроса.
Не рассчитывайте на ini_set() внутри приложения или .user.ini: эти механизмы не подходят для гарантированного применения настройки до уязвимого этапа обработки. После изменения конфигурации перезапустите затронутые рабочие процессы.
У отключения есть побочный эффект: приложение, использующее встроенный механизм PHP для отображения прогресса загрузки, перестанет получать соответствующие данные. Если эта функция нужна сайту, проверьте код и по возможности устраните переключение обработчика сериализации.
2. Уменьшите риск CVE-2026-109618
Для этой уязвимости команда PHP рекомендует убрать управляемый приложением лимит памяти PHP, задав memory_limit = -1 административно - например, через php_admin_value в пуле PHP-FPM или конфигурации Apache. Это устраняет сценарий, в котором атакующий может намеренно вызвать ошибку выделения памяти через установленный лимит.
Однако такой шаг увеличивает риск исчерпания памяти сервера: отдельный запрос сможет потреблять больше памяти, чем допускает обычный лимит PHP. Поэтому применять эту меру следует только при наличии внешнего ограничения ресурсов, например лимита памяти контейнера или cgroup. Не используйте RLIMIT_AS или RLIMIT_DATA как замену: эти ограничения сами могут вызвать ошибку выделения памяти и привести к уязвимому пути.
Дополнительно PHP рекомендует ограничить размер запросов. В качестве временной отправной точки предлагается post_max_size = 8M, если загрузка файлов не нужна, или post_max_size = 32M, если она используется. upload_max_filesize должен быть меньше post_max_size. Перед изменением проверьте требования приложения: слишком низкие лимиты могут нарушить отправку форм и загрузку файлов.
На уровне веб-сервера или обратного прокси следует ограничить размер тела запроса и его сложность: число частей multipart, заголовков, полей и глубину вложенности. Если приложение не использует multipart-запросы, их можно блокировать до передачи в PHP. Для таких ограничений важно учитывать фактический размер декодированного запроса, а не только наличие заголовка Content-Length.
3. Ограничьте дополнительные пути CVE-2026-109619
Для PHP 8.5 рекомендуется отключить формирование трассировок при фатальных ошибках:
//ini
fatal_error_backtraces = 0Эта мера закрывает подтверждённый путь эксплуатации, связанный с трассировкой, но не все возможные сценарии CVE-2026-109619.
Для PHP-FPM можно также установить pm.max_requests = 1 в конфигурации пула. В этом режиме процесс завершает работу после одного запроса, что уменьшает риск переноса внутреннего состояния между запросами. Цена такой меры - дополнительные накладные расходы на запуск рабочих процессов. Это временное снижение риска, а не исправление дефекта.
Кроме того, проверьте конфигурацию на устаревшие или некорректные INI-параметры, передаваемые на уровне отдельных запросов, например через php_value, .htaccess или PHP_VALUE от фронтенда. Такие настройки могут задействовать диагностические механизмы на раннем этапе обработки. Исправление конфигурации должно устранять причину, а не просто скрывать сообщения об ошибках через display_errors или error_reporting.
4. Перезапустите процессы и проверьте настройки
После изменения конфигурации перезапустите все затронутые процессы PHP и сервисы, загружающие интерпретатор. Для контейнеров замените работающие экземпляры после обновления образа. Простое редактирование конфигурационного файла или загрузка нового образа не гарантируют, что уже запущенные процессы применили изменения.
Затем проверьте фактические настройки веб-среды и убедитесь, что сайт использует исправленную сборку либо временные меры действительно активны. Временные ограничения необходимо документировать, чтобы после установки патча можно было пересмотреть их и вернуть необходимые функции без сохранения лишних ограничений на годы.
Что делать со старыми версиями PHP
PHP 8.1 и более ранние ветки завершили обычный цикл поддержки проекта. При этом некоторые поставщики Linux-дистрибутивов и сервисы долгосрочной поддержки выпускают собственные исправленные пакеты. Для отдельных старых веток существуют и ограниченные исправления исходного кода, но доступность готового пакета зависит от поставщика.
Если сайт работает на старой версии PHP, уточните, есть ли исправленная сборка именно для вашей платформы. Если её нет, следует планировать переход на поддерживаемую ветку. Для публичного сайта нельзя считать отсутствие ошибок в работе признаком безопасности неподдерживаемого интерпретатора.
PHP2Shell - пример того, почему после экстренного обновления важно проверить не только номер версии, но и фактическое состояние сервера. Для CVE-2026-109618 необходимо снизить риск управляемого исчерпания памяти, для CVE-2026-109619 - отключить уязвимые пути обработки сессий и учитывать повторное использование процессов, а для CVE-2026-115560 - временно выключить отслеживание прогресса загрузки до выхода исправления.
Первым шагом остаётся установка обновлённой сборки. Если сделать это немедленно невозможно, временные меры нужно применить на уровне серверной конфигурации, перезапустить рабочие процессы и проверить результат. После выхода следующего регулярного выпуска PHP следует установить исправление для дополнительной проблемы и пересмотреть временные настройки с учётом требований приложения.
Комментарии
Чтобы оставить комментарий, войдите в аккаунт.