Россия
RU
Казахстан
RU KZ
Беларусь
RU
Грузия
RU EN
Турция
RU EN
Критическая RCE в PHP (CVE-2026-109619) и легаси: как защитить PHP 5.6 и написать C-патч для ядра

Критическая RCE в PHP (CVE-2026-109619) и легаси: как защитить PHP 5.6 и написать C-патч для ядра

21 октября 2026 года в экосистеме PHP были раскрыты две критические уязвимости с максимальным рейтингом опасности CVSS 9.2: CVE-2026-109618 и CVE-2026-109619. Обе связаны с нарушением управления памятью ядра Zend Engine и приводят к удалённому исполнению произвольного кода (RCE).

1. В чём проблема для реального сектора?

Официальный совет специалистов по кибербезопасности звучит просто: «Срочно обновитесь до актуальных релизов PHP 8.2+ или PHP 8.3+ с официальными патчами».

Однако для огромного количества корпоративных B2B-порталов, платформ электронной коммерции и производственных сайтов миграция с PHP 5.6 за один день невозможна. Официальная поддержка ветки PHP 5.6 завершена в конце 2018 года (EOL), и официальные патчи для неё больше не выпускаются. Ниже описан практический опыт аудита, локализации проблемы и создания собственного бэкпорт-патча.

2. Анатомия уязвимости в коде на Си

Вектор атаки CVE-2026-109619 строится на ошибке освобождения памяти в механизме session.upload_progress (файл ext/session/session.c):

  1. При отправке формы multipart/form-data с полем PHP_SESSION_UPLOAD_PROGRESS ядро выделяет в оперативной памяти структуру отслеживания и сохраняет её адрес в глобальной переменной PS(rfc1867_progress).
  2. Если во время передачи файла происходит нехватка памяти (OOM, превышение memory_limit) или обрыв связи, движок выполняет экстренный сброс zend_bailout(), минуя штатное завершение запроса.
  3. Память текущего запроса освобождается, но системный указатель в долгоживущем воркере (Apache / PHP-FPM) остаётся указывать на освобождённый адрес. Образуется так называемый «висячий указатель» (dangling pointer).
  4. Следующий запрос, попадающий на этот же воркер, обращается к чужой памяти — происходит Use-After-Free, позволяющий злоумышленнику исполнить произвольный шеллкод на сервере.

3. Стратегия защиты: три уровня безопасности

Уровень 1: Полный переход на PHP 8 (Рекомендуется)

Единственное исчерпывающее решение обеих уязвимостей (включая OOM-сбои ядра CVE-2026-109618) — планомерный перевод проекта на поддерживаемые ветки PHP 8.2 или 8.3.

Уровень 2: Бэкпорт C-патча для PHP 5.6

Для серверов, где обновление невозможно, мы разработали и протестировали C-патч для исходного кода PHP 5.6. Патч принудительно обнуляет указатель PS(rfc1867_progress) = NULL; в самом начале каждого нового запроса (RINIT) и корректно освобождает структуры при сбое (RSHUTDOWN). Воркер физически не может унаследовать адрес освобождённой памяти.

Уровень 3: Временная мера без перекомпиляции (.htaccess / Nginx)

Если у вас нет прав root на сервере, отключите уязвимый механизм в конфигурации веб-сервера:

# Отключение уязвимого механизма
<IfModule mod_php5.c>
    php_flag session.upload_progress.enabled off
</IfModule>

# WAF: отсекаем маркеры атаки
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{THE_REQUEST} (PHP_SESSION_UPLOAD_PROGRESS|upload_progress) [NC,OR]
    RewriteCond %{QUERY_STRING} (PHP_SESSION_UPLOAD_PROGRESS|upload_progress) [NC]
    RewriteRule .* - [F,L]
</IfModule>
Важно: Отключение session.upload_progress блокирует вектор CVE-2026-109619, но НЕ исправляет общую проблему OOM-сбоев ядра (CVE-2026-109618). Штатная загрузка картинок товаров и прайс-листов через $_FILES при этом продолжает работать штатно.

4. Открытые исходники и бинарники для сообщества

Все наработки — C-патч, готовые .deb пакеты, Dockerfile для воспроизводимой сборки и подробное описание — опубликованы под открытой лицензией в репозитории на GitHub:

Репозиторий на GitHub: checkfoxe/php56-session-uaf-patch →

Автор: Viktor Zarbashev (@checkfoxe)

Содержание