К основному содержимому

PHP в Docker: как закрыть PHP2Shell пересборкой образа

PHP · 27.10.2026 · 2 мин чтения

Коротко

Обновление пакетов на хост-системе не трогает PHP внутри контейнера. Нужно взять свежий базовый образ, пересобрать свой и перезапустить контейнеры. Проверять версию следует внутри контейнера, а не на хосте.

Шаг 1. Понять, что у вас внутри

docker ps --format '{{.Names}}\t{{.Image}}'
docker exec -it имя_контейнера php -v
docker exec -it имя_контейнера sh -c 'dpkg -l | grep php || rpm -q php-cli'

Официальные образы PHP собраны из исходников, поэтому номер версии там честный: 8.3.36 и новее — исправлено, 8.3.35 и старше — нет.

Шаг 2. Обновить базовый образ

Если в Dockerfile закреплён точный тег, поднимите его до исправленной версии:

FROM php:8.3.36-fpm-bookworm

Если тег плавающий (php:8.3-fpm), достаточно скачать образ заново:

docker pull php:8.3-fpm
docker compose build --pull --no-cache
docker compose up -d

Флаг --pull здесь ключевой: без него сборка возьмёт старый слой из локального кэша, и уязвимость останется.

Шаг 3. Проверить результат

docker compose exec php php -v
docker compose exec php php -r 'echo PHP_VERSION, PHP_EOL;'

Версия должна быть не ниже 8.3.36 для ветки 8.3, 8.4.27 для 8.4, 8.5.12 для 8.5, 8.2.35 для 8.2.

Шаг 4. Убедиться, что старые контейнеры не работают

Частая ошибка: образ обновлён, а рядом крутится контейнер, запущенный неделю назад.

docker ps --format '{{.Names}}\t{{.Image}}\t{{.CreatedAt}}'

Если контейнер создан раньше, чем вы пересобрали образ, пересоздайте его.

Чтобы не повторилось

  • Закрепляйте точные теги версий — так видно, что именно развёрнуто.
  • Пересобирайте образы по расписанию, а не только при правке кода: базовый образ стареет сам по себе.
  • Добавьте в конвейер проверку уязвимостей образа: docker scout cves имя_образа или trivy image имя_образа.

Частые вопросы

Нужно ли обновлять PHP на хосте, если всё в контейнерах?

Если на хосте PHP не используется — нет. Но проверьте: утилиты вроде composer или скрипты cron могли притащить системный PHP.

Образ на Alpine тоже уязвим?

Да, уязвим сам код PHP, а не дистрибутив. Обновлять нужно так же.

Как быстро проверить весь парк контейнеров?

for c in $(docker ps -q); do printf '%s ' "$(docker inspect -f '{{.Name}}' $c)"; docker exec $c php -v 2>/dev/null | head -1 || echo 'без php'; done
Статья помогла?
← Назад в базу знаний Задать вопрос поддержке