Критические уязвимости PHP от 21 октября 2026: до какой версии обновиться и как сделать это безопасно
21 октября 2026 года вышло экстренное обновление PHP, которое закрывает две критические уязвимости. В этой статье разберём, чем они опасны, до какой версии обновляться, как узнать, какой PHP на самом деле обслуживает сайт, и как пройти обновление по шагам: от аудита и резервных копий до проверки и отката. В конце — временные меры для тех, кто не может обновиться сразу, и чек-лист.
Что произошло
Команда PHP выпустила версии 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Они исправляют две уязвимости:
- CVE-2026-109618 — повреждение памяти при обработке нехватки памяти (out of memory). PHP прерывается, когда внутренние данные запроса заполнены лишь частично, а при очистке принимает эти данные за корректные;
- CVE-2026-109619 — «устаревшее» глобальное состояние. Данные одного запроса переживают освобождение памяти, и следующий запрос в том же рабочем процессе может ими воспользоваться.
Обе уязвимости получили оценку 9,2 по CVSS 4.0 и при определённых условиях позволяют выполнить код на сервере без авторизации. Под угрозой все установки PHP, которые обслуживают веб-запросы: PHP-FPM, Apache с mod_php, php-cgi, FrankenPHP, LiteSpeed. Самый высокий риск — у mod_php: там атака срабатывает ещё до того, как запустится код приложения.
По данным CERT-EU на 23 октября, в сети уже ходят proof-of-concept эксплойты. Значит, вероятность реальных атак высокая, и откладывать обновление нельзя.
Официальные источники: бюллетень PHP, поддерживаемые версии PHP, CERT-EU 2026-018.
До какой версии обновиться
| Ветка PHP | Минимальная исправленная версия | Поддержка безопасности до |
|---|---|---|
| 8.5 | 8.5.12 | 31.12.2029 |
| 8.4 | 8.4.27 | 31.12.2028 |
| 8.3 | 8.3.36 | 31.12.2027 |
| 8.2 | 8.2.35 | 31.12.2026 |
| 8.1 и ниже | исправления от проекта PHP нет | ветки не поддерживаются |
Для PHP 8.1 и старше проект PHP новых версий не выпускает. Есть три пути: бэкпорт от поставщика ОС или LTS-поставщика, минимальные патчи для сборки из исходников (команда PHP выложила их для 7.4, 8.0 и 8.1) или переход на поддерживаемую ветку.
Не нужно переводить всё на PHP 8.5. Обновляйтесь в пределах своей ветки: сайт на 8.3 — до 8.3.36 и новее, на 8.4 — до 8.4.27. Патч-версия внутри ветки исправляет ошибки и почти никогда не ломает совместимость. Переход 8.3 → 8.5 — это уже обновление платформы: устаревшие функции, новые требования библиотек и отдельное тестирование. Ветку стоит менять, только если ваша больше не получает исправлений, например 8.1 и ниже. А 8.2 получает исправления только до конца 2026 года, так что её переход стоит запланировать отдельно.
Какой PHP на самом деле обслуживает сайт
Частая ошибка — проверить php -v и успокоиться. Это версия консольного PHP (CLI). Сайт может работать совсем на другой версии через PHP-FPM, а на одном сервере часто стоят сразу несколько веток.
Какие версии установлены и какие пулы PHP-FPM запущены:
ls /usr/bin/php* /usr/sbin/php-fpm*
systemctl list-units --type=service | grep -i php
ps -eo user,pid,cmd | grep "php-fpm: " | grep -v grep
Какой сокет использует каждый сайт в Nginx:
grep -Rn "fastcgi_pass" /etc/nginx/sites-enabled/ /etc/nginx/conf.d/
Для Apache — подключён ли mod_php или запросы уходят в FPM:
apache2ctl -M | grep -i php
grep -Rn "SetHandler.*php" /etc/apache2/
Версия конкретного FPM, на сокет которого указывает сайт:
php-fpm8.4 -v
Если проекты работают в Docker, смотрите версию внутри контейнера: docker exec <контейнер> php -v. Версия на хосте здесь ни при чём.
Номер версии — ещё не вся правда
Debian, Ubuntu, RHEL и другие дистрибутивы часто переносят исправления в старую версию (backport) и не меняют основной номер. Пакет может называться 8.1.2-1ubuntu2.x, но уже содержать патч. Бывает и наоборот: номер свежий, а сборка самодельная и без патча.
Поэтому проверяйте источник пакета и его changelog, а не только номер:
# Откуда пакет и какая версия доступна (Debian/Ubuntu)
apt-cache policy php8.4-fpm
# Есть ли в changelog установленного пакета нужные CVE
zcat /usr/share/doc/php8.4-common/changelog.Debian.gz | grep -m5 -i "CVE-2026-1096"
# RHEL, AlmaLinux, Rocky
rpm -q --changelog php-common | grep -m5 -i "CVE-2026-1096"
Статус пакетов дистрибутива смотрите в его трекере безопасности: Ubuntu, Debian. Если PHP стоит из стороннего репозитория, например из PPA ondrej/php на Ubuntu, исправление приходит оттуда, и changelog — тоже его.
План безопасного обновления
1. Аудит: что есть на сервере
Перед любыми изменениями соберите картину:
- ОС и её версия, веб-сервер (Nginx, Apache);
- все установленные версии PHP и откуда они поставлены;
- пулы PHP-FPM: какой сайт на какой версии и каком сокете;
- проекты, их домены, фреймворки (Laravel, WordPress, Symfony, самописный код) и нужные расширения;
- фоновые задачи: cron, очереди, Supervisor, systemd timers. Они работают через CLI, и его тоже нужно обновить;
- Docker-контейнеры и свои PHP-образы;
- как устроен деплой и как сейчас откатываются изменения;
- свободное место на диске.
Результат удобно свести в таблицу: проект, домен, версия PHP, пул, уровень риска (доступен ли из интернета) и план. На этом этапе ничего не меняйте.
2. Резервные копии
Сохраните всё, что понадобится для восстановления:
- конфигурации Nginx/Apache и виртуальных хостов;
- конфигурации PHP и пулов PHP-FPM (
/etc/php/); - crontab, задания systemd и Supervisor;
- список установленных пакетов и модулей каждой версии PHP;
- базы данных и загрузки пользователей, если изменение может их затронуть.
B=/root/php-upgrade-backup-$(date +%Y%m%d); mkdir -p "$B" && chmod 700 "$B"
tar czf "$B/etc.tar.gz" /etc/nginx /etc/php /etc/cron.d /var/spool/cron/crontabs
dpkg -l | grep -E "^ii\s+php" > "$B/php-packages.txt"
php-fpm8.4 -m > "$B/php8.4-fpm-modules.txt"
gzip -t "$B/etc.tar.gz" && echo "архив цел"
Если хостинг умеет делать снапшоты сервера, сделайте снапшот: это самый быстрый откат. Копию лучше хранить и за пределами сервера.
Учтите неочевидную деталь: сторонние репозитории обычно удаляют старые пакеты, как только выходит новая версия. Откатиться через apt install php8.4-fpm=<старая версия> уже не выйдет. Если нужен план отката, сохраните старые файлы пакетов до обновления.
3. Совместимость и тест
При обновлении внутри ветки (8.4.26 → 8.4.27) требования проекта не меняются: composer.json и composer.lock трогать не нужно. Не запускайте composer update: это обновит библиотеки, которые к уязвимости отношения не имеют.
Если есть тестовый стенд, обновите сначала его. Прогоните автотесты, откройте главные страницы, войдите в админку, отправьте форму. Никаких реальных платежей и рассылок, и никаких миграций на боевой базе.
Если стенда нет, проверьте хотя бы, что все нужные расширения доступны для новой версии: apt-get -s install --only-upgrade <пакеты> покажет, что именно установится, ничего не меняя.
4. Обновление по одному
-
Обновляйте только пакеты PHP, а не всю систему. Без
apt upgradeиdist-upgrade:sudo apt-get update sudo apt-get install --only-upgrade -o Dpkg::Options::=--force-confold \ $(dpkg -l | awk '/^ii +php8\.4-/{print $2}')Флаг
--force-confoldсохраняет ваши изменённые конфиги. -
По одной ветке за раз. Если на сервере несколько версий, начните с той, от которой зависит меньше всего сайтов, и проверьте результат.
-
Помните про общие пулы. Если несколько сайтов работают в одном пуле PHP-FPM, обновление затронет их все сразу. Проверять нужно каждый.
-
Проверяйте конфигурацию перед перезагрузкой:
php-fpm8.4 -t,nginx -t. -
При обновлении пакет сам перезапускает PHP-FPM, и сайт на секунду-две отвечает 502. Делайте это в спокойное время.
-
Старые версии не удаляйте, пока не убедились, что всё работает.
На этом сайте обновление 8.4.26 → 8.4.27 дало примерно 2 секунды ответов 502, пока PHP-FPM перезапускался.
5. Проверка после обновления
Ответа 200 мало: страница может открываться, а форма или вход — не работать. Проверьте:
-
реальную версию PHP у сайта. Служба PHP-FPM должна быть перезапущена после установки, иначе в памяти остался старый код:
php-fpm8.4 -v systemctl status php8.4-fpm | grep Active # время запуска — после обновления -
главные страницы и коды ответов, отсутствие 500, 502 и 503;
-
вход, сессии и формы (POST-запросы);
-
админку, загрузку файлов, отправку почты;
-
cron и очереди — они идут через CLI, так что проверьте и
php -v; -
набор расширений, сравнив с сохранённым списком:
diff <(php-fpm8.4 -m) "$B/php8.4-fpm-modules.txt"; -
логи веб-сервера, PHP-FPM и приложения.
6. Если что-то сломалось
- Остановите дальнейшие обновления.
- Найдите последнее изменение и верните его: конфиг из копии, снапшот или старые пакеты.
- Убедитесь, что сайт работает, и запишите причину.
Откат на уязвимую версию — только временная мера, чтобы вернуть сайт. Такой сервер нельзя считать защищённым. Если исправление поставить не получается, ограничьте доступ к уязвимому сервису из интернета, пока не найдёте решение.
Если обновиться прямо сейчас нельзя
Команда PHP прямо пишет: полностью уязвимости закрывает только обновление. Меры ниже лишь сужают отдельные пути атаки и сервер безопасным не делают.
Против CVE-2026-109618 (нехватка памяти):
- установить
memory_limit=-1так, чтобы приложение не могло его переопределить, например черезphp_admin_valueв пуле FPM. Тогда ограничение памяти внутри PHP не сработает, но системная нехватка памяти по-прежнему может привести к уязвимому сценарию; - уменьшить
post_max_size: 8M, если сайт не принимает файлы, и 32M, если принимает.upload_max_filesizeдолжен быть меньшеpost_max_size; - ограничить размер запросов, число полей и заголовков на уровне веб-сервера или прокси.
Против CVE-2026-109619 (устаревшее состояние):
- выключить
session.upload_progress.enabledвphp.iniили в пуле FPM и перезапустить все рабочие процессы.ini_set()и.user.iniдля этого не подходят; - на PHP 8.5 —
fatal_error_backtraces=0; - исправить фатальные ошибки и таймауты, до которых может дотянуться атакующий.
Пример для пула PHP-FPM:
; /etc/php/8.4/fpm/pool.d/example.conf
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 16M
php-fpm8.4 -t && sudo systemctl reload php8.4-fpm
Обратите внимание: 23 октября команда PHP отдельно посоветовала держать session.upload_progress.enabled=0 даже после обновления — до следующего регулярного релиза. Это защита от ещё одной, маловероятной уязвимости (CVE-2026-115560). Эта функция только показывает прогресс загрузки файла, и сайты ею почти не пользуются. Laravel на неё не опирается совсем, так что выключение обычно ничего не ломает.
Docker
В контейнерах PHP обновляется пересборкой образа, а не пакетом на хосте:
- укажите точную исправленную версию в
Dockerfile, напримерFROM php:8.4.27-fpm, а неlatestили просто8.4; - пересоберите образ без кэша (
docker build --pull --no-cache) и перезапустите контейнеры; - проверьте версию внутри:
docker exec <контейнер> php -v.
Не забудьте про сторонние образы и программы, в которые PHP встроен: их исправленные версии выпускают их авторы.
После обновления: проверьте, не взломали ли сервер раньше
Обновление закрывает дыру, но не удаляет то, что атакующий мог оставить до патча. Уязвимости публичны, эксплойты уже ходят, поэтому стоит проверить сервер. CERT-EU конкретных признаков не публиковал, ниже — общая практика:
# PHP-файлы, появившиеся или изменённые после раскрытия уязвимостей
find /var/www -name "*.php" -newermt "2026-10-20" -not -path "*/vendor/*" -ls
# PHP-файлы в папках загрузок, где их быть не должно
find /var/www -path "*upload*" -name "*.php" -ls
# Задания cron всех пользователей и подозрительные процессы
for u in $(cut -d: -f1 /etc/passwd); do crontab -u "$u" -l 2>/dev/null | sed "s/^/$u: /"; done
ps -eo user,pid,etime,cmd --sort=-etime | grep -E "www-data|nginx|apache" | head -20
Ещё стоит просмотреть:
- логи веб-сервера за 20–24 октября: необычные
multipart/form-dataзапросы, аномально большие тела запросов, всплески 500 и 502; - новых пользователей ОС и ключи в
~/.ssh/authorized_keys; - неожиданные исходящие соединения:
ss -tnp.
Если нашли следы взлома, недостаточно просто удалить файл. Изолируйте сервер, восстановите его из чистой копии, сделанной до появления первых следов взлома, и смените все секреты: пароли БД, ключи API, APP_KEY, SSH-ключи.
На будущее: автоматические обновления
На Ubuntu unattended-upgrades по умолчанию ставит обновления безопасности только из репозиториев Ubuntu. Если PHP стоит из PPA или другого стороннего репозитория, патч сам не приедет. Так было и на этом сайте: сервер три дня после релиза оставался на уязвимой версии, пока PHP не обновили вручную. Либо добавьте репозиторий в разрешённые источники unattended-upgrades, либо подпишитесь на новости php.net и бюллетени своего дистрибутива.
Чек-лист
- Узнать, какие версии PHP есть на сервере и какая обслуживает каждый сайт (FPM, Apache, Docker), а не только
php -v. - Сверить их с исправленными: 8.5.12, 8.4.27, 8.3.36, 8.2.35. Для пакетов дистрибутива — проверить changelog на CVE-2026-109618 и CVE-2026-109619.
- Сделать резервные копии конфигов, списка пакетов и модулей, при необходимости — БД и снапшот.
- Обновлять в пределах своей ветки, только пакеты PHP, по одной версии за раз, без
composer update. - Проверить конфиги (
php-fpm -t,nginx -t), затем сайты: страницы, вход, формы, админку, cron, логи. - Убедиться, что PHP-FPM перезапущен после установки и отдаёт новую версию.
- Оставить
session.upload_progress.enabled=0до следующего релиза PHP. - Проверить сервер на признаки взлома до патча.
- Настроить автоматические обновления или подписку на бюллетени, чтобы следующий патч не прошёл мимо.