21 жовтня команда PHP випустила екстрені релізи для двох критичних вразливостей у ядрі інтерпретатора: CVE-2026-109618 і CVE-2026-109619. Ланцюжок експлойтів назвали PHP2Shell. Обидві отримали 9,2 бала за CVSS v4.0 і дозволяють віддалене виконання коду без автентифікації.
Для команди, яка підтримує один сайт, це один вечір роботи. Для компанії, що веде десятки проєктів на різних гілках PHP, у різних середовищах і з різною історією, це повноцінний інцидент. Розповім, як ми в WEZOM організовуємо реагування і чому «оновити PHP» тут лише один з п’яти кроків.
Що робить цю вразливість особливою
Зазвичай критичні баги в PHP-екосистемі живуть у CMS, плагінах чи фреймворках. Тут проблема в самому рантаймі:
- CVE-2026-109618 пов’язана з обробкою нестачі пам’яті, коли дані запиту ініціалізовані лише частково;
- CVE-2026-109619 — це use-after-free між запитами на одному воркері, з можливим витоком пам’яті.
Під загрозою всі поширені SAPI: PHP-FPM, mod_php, php-cgi, FrankenPHP, LiteSpeed. У деяких конфігураціях атака спрацьовує ще до виконання коду застосунку. Дослідники Wiz вже продемонстрували pre-auth RCE на WordPress, Drupal і Joomla (Huntress).
Найнеприємніше — таймінг. Amazon зафіксувала спробу експлуатації у своїх honeypot-пастках ще 17 жовтня, за чотири дні до розкриття (Help Net Security). 20 жовтня ідентифікатори CVE з’явилися в соцмережах, і команда PHP перенесла реліз на день раніше (Bitsight). А вже за кілька годин після релізу Cloudflare фіксувала спроби атак і запустила захисні правила WAF (PPC Land).
Чому це складно в масштабі
Проблема великих портфелів не в самому оновленні, а в усьому навколо нього:
- Різні гілки. Виправлення вийшли для 8.2–8.5. Для 7.4–8.1 є лише мінімальні бекпорти від команди PHP і пакети від дистрибутивів. Для гілок, старших за 7.4, офіційних виправлень немає.
- Невидимі середовища. Staging, старі промосайти, адмінки, Docker-образи, зібрані пів року тому, сервери від попередніх підрядників.
- Легасі-код. Проєкт на PHP 7.x часто не можна просто перевести на 8.2+: ламаються модулі, інтеграції з 1С чи CRM, кошик.
- Можлива компрометація до патча. Оновлення закриває вразливість, але не відповідає на питання, чи хтось уже зайшов.
Наш процес реагування
- Інвентаризація. Ми збираємо повний перелік PHP-середовищ кожного клієнта: продакшн, staging, внутрішні сервіси, контейнери, CI. Фіксуємо гілку PHP, SAPI і джерело пакетів. Без цього решта кроків — гадання.
- Пріоритизація за ризиком. Першими йдуть публічні системи з платежами й персональними даними, потім системи на конфігураціях з найвищим ризиком, потім внутрішні сервіси. Застарілі гілки отримують окремий трек.
- Оновлення лише через перевірені канали. Офіційні релізи, пакети дистрибутивів, вендорні бекпорти. Жодних «латок» із форумів. Кожне оновлення проходить регресійне тестування командою QA: для інтернет-магазину зламаний кошик — це теж інцидент.
- Перевірка на компрометацію. Оскільки спроби атак були ще до розкриття, ми аналізуємо активність щонайменше з 17 жовтня. Якщо є підстави вважати сервер скомпрометованим, змінюємо секрети: паролі до баз, API-ключі, токени платіжних систем та інтеграцій.
- Довгостроковий захист. Для проєктів на EOL-гілках складаємо план міграції. Для всіх — регулярні оновлення та моніторинг, щоб наступна критична вразливість не вимагала аврального режиму.
Саме стандартизований процес дозволив працювати в масштабі. За першу ніч після розкриття ми перевірили 125 сайтів, а за наступні два дні 98 з них пішли в допрацювання: оновлення, міграцію та усунення ризиків.
Що ми винесли для себе
- Інвентаризація має бути завжди актуальною, а не збиратися під час інциденту.
- WAF — це тимчасовий захід, а не рішення. Навіть після запуску правил Cloudflare зловмисники одразу почали змінювати запити, щоб їх обійти.
- EOL-версії PHP — це технічний борг із датою погашення, і PHP2Shell показав, що ця дата вже настала.
А як це виглядало у вас? Скільки часу зайняла інвентаризація і чи знайшлися середовища, про які всі забули? Діліться в коментарях — цікаво порівняти підходи.