21 октября 2026 года команда PHP выпустила внеплановые релизы 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Они закрывают две критические уязвимости в ядре, каждая с оценкой 9.2 по CVSS v4.0. В обеих подтверждено удалённое выполнение кода без авторизации, причём для одной из них — ещё до того, как управление дойдёт до кода вашего приложения.
Релиз планировали на 17:00 МСК, но бюллетени появились около 16:30: подробности утекли раньше эмбарго. Ниже — разбор официальных бюллетеней без пересказа слухов, скрипт для проверки сервера и временные меры для тех, кто не может обновиться прямо сейчас.
Коротко
CVE-2026-109618 |
CVE-2026-109619 |
|
|---|---|---|
Бюллетень |
||
Суть |
RCE через порчу состояния при нехватке памяти (OOM) |
RCE через use-after-free «протухшего» глобального состояния воркера |
CVSS v4.0 |
9.2 ( |
9.2 ( |
Авторизация |
не нужна |
не нужна |
Подтверждённая RCE |
Apache mod_php |
Apache mod_php; сценарий с сессиями — также PHP-FPM |
Исправлено в |
8.2.35, 8.3.36, 8.4.27, 8.5.12 |
8.2.35, 8.3.36, 8.4.27, 8.5.12 |
Все ветки до 8.1 включительно официально не поддерживаются, и исправлений для них от PHP не будет.
Что именно сломано
CVE-2026-109618: OOM и longjmp()
Когда скрипту не хватает памяти (memory_limit), PHP прерывает обработку запроса через longjmp(). Проблема в том, что в некоторых местах память запроса уже доступна, но ещё не инициализирована. Если любое выделение памяти падает в этот момент, процедура завершения запроса потом работает с невалидными данными. Это и превращается в RCE.
Самое неприятное — способы гарантированно довести запрос до OOM, не выходя за видимые лимиты. Все они связаны с разбором multipart/form-data:
multipart-запрос без корректной длины тела может пройти проверку
post_max_sizeи продолжать слать данные;у части multipart может быть неограниченное количество заголовков, а в памяти PHP они занимают гораздо больше, чем по сети;
пустые поля загрузки файлов не считаются в
max_file_uploads, но создают массивы метаданных, а вложенные имена полей умножают эту работу.
Почему mod_php страдает сильнее всего: Apache с mod_php вызывает завершение запроса, даже если старт запроса упал. Разбор тела происходит ещё до вашего кода, поэтому атака не зависит от приложения: у вас может быть хоть пустой index.php. По данным бюллетеня, полная RCE подтверждена против mod_php с лимитами PHP по умолчанию. FrankenPHP, по анализу исходников, ведёт себя так же. PHP-FPM в этом сценарии просто убивает воркер, но после нормального старта OOM всё ещё опасен: FPM считается уязвимым, хотя полного эксплойта под него не показали.
CVE-2026-109619: «протухшее» состояние между запросами
Воркер PHP хранит глобальное состояние: ошибки, сессии, объекты, состояние расширений. Иногда оно указывает на память конкретного запроса. Если запрос прервался фатальной ошибкой (в том числе из-за той же нехватки памяти или таймаута), сброс этого состояния может не произойти. Память запроса освобождается, а указатель остаётся. Следующий запрос в том же воркере обращается к нему раньше нормальной инициализации — получается use-after-free.
Для атаки нужны два запроса: один оставляет мусор, второй его использует. Несколько воркеров снижают шанс попасть в тот же процесс, но не устраняют проблему. Подтверждено:
RCE через путь с fatal error backtraces (PHP 8.5) против mod_php;
RCE через жизненный цикл сессий против mod_php и PHP-FPM;
утечка памяти процесса.
Проверяем сервер за минуту
Один бинарник
php -v
Безопасные версии: 8.2.35+, 8.3.36+, 8.4.27+, 8.5.12+.
Но php -v в консоли часто показывает не ту версию, которая обслуживает сайт. На серверах с ISPmanager, cPanel, CloudLinux или Remi стоит по несколько PHP, а сайт может работать через php-fpm другой версии.
Все PHP на машине
Скрипт ищет PHP в типичных местах (системные пакеты, Remi, cPanel EA, CloudLinux alt-php, ручные сборки) и сравнивает каждую версию с исправленной:
#!/usr/bin/env bash # Ищет PHP на сервере и сравнивает версии с исправленными (PHP2Shell, 21.10.2026) fixed() { case "$1" in 8.2) echo 35;; 8.3) echo 36;; 8.4) echo 27;; 8.5) echo 12;; esac; } for bin in /usr/bin/php* /usr/sbin/php-fpm* /usr/local/bin/php* /usr/local/sbin/php-fpm* \ /opt/remi/php*/root/usr/bin/php /opt/remi/php*/root/usr/sbin/php-fpm \ /opt/cpanel/ea-php*/root/usr/bin/php /opt/alt/php*/usr/bin/php \ /opt/php*/bin/php /usr/local/php*/bin/php; do [ -x "$bin" ] && [ -f "$bin" ] || continue case "$(basename "$bin")" in phpize*|php-config*) continue;; esac v=$("$bin" -v 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1) [ -n "$v" ] || continue branch=${v%.*}; patch=${v##*.}; need=$(fixed "$branch") if [ -z "$need" ]; then case "$branch" in 8.[6-9]) status="тестовая ветка, проверьте вручную";; *) status="EOL: исправления от PHP не будет";; esac elif [ "$patch" -ge "$need" ]; then status="OK" else status="УЯЗВИМ: нужна $branch.$need или новее"; fi printf '%-45s %-8s %s\n' "$bin" "$v" "$status" done
Пример вывода:
/usr/bin/php7.4 7.4.33 EOL: исправления от PHP не будет /usr/sbin/php-fpm8.4 8.4.26 УЯЗВИМ: нужна 8.4.27 или новее /opt/remi/php85/root/usr/bin/php 8.5.12 OK
⚠️ Важно про пакеты дистрибутивов. Debian, Ubuntu, RHEL и другие часто переносят исправления в старую версию, не меняя её номер. Скрипт покажет «уязвим», хотя пакет уже залатан. В таком случае смотрите changelog пакета (
apt changelog php8.2-fpm,rpm -q --changelog php-fpm | head) и трекер безопасности своего дистрибутива по номерам CVE. И наоборот: ветки 7.x и 8.0/8.1 из сторонних репозиториев вряд ли получат исправление вообще.
Docker
docker ps --format '{{.Names}}' | while read c; do printf '%-30s ' "$c"; docker exec "$c" php -v 2>/dev/null | head -n1 || echo "php не найден" done
Не забудьте пересобрать образы, а не только перезапустить контейнеры: в базовом образе php:8.x должна оказаться исправленная версия.
Если доступа к консоли нет
WordPress: «Инструменты» → «Здоровье сайта» → «Информация» → «Сервер».
1С-Битрикс: «Настройки» → «Инструменты» → «Проверка системы».
Виртуальный хостинг: версия обычно видна в панели. Обновление PHP — задача хостера, напишите в поддержку и уточните сроки.
Заголовок
X-Powered-By(curl -sI https://example.com | grep -i powered) — ненадёжно: его часто скрывают, а версия в нём может не совпадать с реальной.
Обновляемся
После обновления пакетов обязательно перезапустите все воркеры (php-fpm, Apache), иначе в памяти продолжит работать старый код:
# Debian/Ubuntu, пример для 8.3 из ondrej/php apt update && apt install --only-upgrade 'php8.3*' systemctl restart php8.3-fpm # или apache2 для mod_php # RHEL/Alma/Rocky с Remi dnf upgrade 'php*' systemctl restart php-fpm
Затем снова прогоните скрипт или php -v и проверьте сайт.
Если обновиться прямо сейчас нельзя
Оба бюллетеня прямо пишут: полноценная защита — только обновление. Всё ниже лишь сужает поверхность атаки, пока вы готовите обновление.
Против CVE-2026-109618 (OOM):
Принудительный
memory_limit=-1на уровне администратора (php_admin_valueв пуле FPM или конфиге Apache) с перезапуском всех воркеров. Это убирает предсказуемый лимит, на котором построен эксплойт. Но сервер теряет защиту от прожорливых скриптов, поэтому ограничивайте память снаружи (cgroup/контейнер) и следите за нагрузкой.Не используйте
RLIMIT_AS/RLIMIT_DATAкак замену: по бюллетеню это как раз переводит PHP в уязвимую ветку.Держите консервативный
post_max_size, уменьшитеmax_input_nesting_levelиmax_input_vars, ограничьте размер тела и количество частей multipart на фронтенде (nginx, WAF).Если сайт не принимает
multipart/form-data(нет загрузки файлов и форм с файлами), режьте такие запросы на фронтенде.
Против CVE-2026-109619 (stale state):
На PHP 8.5:
fatal_error_backtraces=0на уровне администратора — убирает подтверждённый путь к RCE.session.upload_progress.enabled=0— закрывает подтверждённый сценарий с сессиями. Авторы бюллетеня советуют выключить его и после обновления, если функция не нужна.Если производительность не критична —
pm.max_requests=1в пуле FPM: каждый воркер обрабатывает один запрос, и «мусору» не к кому перейти.Ищите и устраняйте фатальные ошибки и предупреждения, которые атакующий может вызвать запросом: загрузки, импорты, страницы ошибок, деструкторы, обработчики вывода.
Что делать владельцам сайтов на PHP 7.x и 8.0/8.1
Это самая болезненная часть. В рунете огромное количество сайтов на Битриксе, WordPress и самописных движках со старым PHP. Исправлений для этих веток не будет, а временные меры выше не дают полной защиты.
Реальный выход один — переезд на поддерживаемую ветку (8.2+). Это не всегда «поменять версию в панели»: старые модули, плагины и самописный код могут сломаться. Поэтому порядок такой:
Сделать полный бэкап сайта и базы.
Развернуть копию на новой версии PHP и прогнать основные сценарии: каталог, корзина, оплата, формы, админка.
Исправить несовместимости (обычно это устаревшие функции,
each(),create_function(), строгие типы, изменения вmysqli).Переключить боевой сайт и временно включить меры из раздела выше, пока переезд не завершён.
Чек-лист
[ ] Найти все PHP на сервере, а не только тот, что в
php -v.[ ] Обновить до 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 или проверить бэкпорт в пакете дистрибутива.
[ ] Перезапустить php-fpm и Apache.
[ ] Пересобрать Docker-образы.
[ ] Если обновиться нельзя — включить временные меры и запланировать обновление.
[ ] Если ветка 7.x / 8.0 / 8.1 — планировать переезд, а не ждать патча.
[ ] Проверить логи на всплески ошибок нехватки памяти и фатальных ошибок при разборе POST-запросов.
Источники
Если не хотите разбираться сами — могу помочь: проверю, какие версии PHP реально обслуживают ваши сайты, обновлю их или перенесу проект со старого PHP 7.x на актуальную ветку с проверкой работоспособности. Пишите в Telegram: @sonic_h1.
Комментарии (11)

arkady
21.10.2026 14:25Хорошие новости, патч выпущен также и для 7.4.*, 8.0.* и 8.1.*
https://github.com/php/php-src/tree/PHP-7.4-CVE-2026-109618-109619
https://github.com/php/php-src/tree/PHP-8.0-CVE-2026-109618-109619
https://github.com/php/php-src/tree/PHP-8.1-CVE-2026-109618-109619

evgeniymx
21.10.2026 14:25Так ведь получается достаточно уменьшить на фронтенде макс размер файла до меньшего размера, чем указано в memory_limit/post_max_size/upload_max_filesize, чтобы еще на уровне nginx запрос обрывался с 413 (или apache c 400), и утечка памяти была бы невозможной, т.к. memory_limit бы и не дергался (это касается CVE-2026-109618)

NotSlow
21.10.2026 14:25Проблема еще в том, что memory_limit может быть задан в php.ini и потом еще 10 раз изменен в .htaccess и самих php скриптах. Причем как в большую, так и в меньшую сторону. Много раз наблюдал когда изначально стоит допустим 1024мб лимит, но скрипт обрывается с ошибкой по памяти. В итоге выясняется что где-то в недрах скриптов зачем-то стоит невозмутимая строчка типа ini_set(‘memory_limit’, '128M');
А если в nginx сделать совсем уж малое значение, то появиться могут проблемы у нормальных запросов.
unsec
https://php2shell.ru - методы зщаиты от PHP2Shell и ссылки на патчи, информация обновляется.
trinxery
Спамить плохо
slbeat
Зависть? Человек помощь сообществу хочет!
trinxery
Пусть придумает другой способ, все его комментарии это спам этой ссылкой. Если применять критерий полезности для общества, то окажется, что всем можно спамить чем угодно где угодно, а это, очевидно, вредно.
P.S. Если оценивать текст сайта, то первый же рекомендуемый способ исправления уязвимости (не считая самого патча), судя по [1], на самом деле не работает. На сайте даже нет почты для обратной связи, поэтому @unsec никогда бы не узнал, если у него что-то написано не так.
unsec
На сайте агрегация способов защиты от уязвимости, никаких почт и ссылок нет - он сделан для оповещения об уязвимости и добавлен в посты про багу для удобства получения информации, извините если вас это задело. Замечания и исправления можно прислать мне в личные сообщения.