Текуща ситуация: PHP2Shell. Две критични уязвимости в PHP (CVSS 9,2) позволяват злонамерен код без вход. Корекции от 21.10.2026 г.Какво да направите сега →

Как PHP създава уебстраница: пътят на една заявка

Какво се случва между клика и готовата страница: уеб сървър, SAPI, компилатор, OPcache и Zend VM в седем стъпки и защо PHP2Shell засяга точно този процес.

Актуалност 4 мин. четенеЗнания за PHP

Накратко: Когато браузър поиска PHP страница, уеб сървърът приема заявката и я предава на PHP през интерфейс (SAPI). PHP превежда скрипта в байткод, изпълнява го в Zend Engine и връща резултата, най-често HTML, на уеб сървъра. След това състоянието на заявката се почиства, за да започне следващата начисто.

Какво се случва, когато някой отвори Вашия уебсайт?

За посетителите това е един клик. На сървъра за милисекунди се изпълняват много стъпки. Който познава този процес, разбира по-добре защо актуализациите, рестартиранията и конфигурацията са толкова важни и защо уязвимост в самия PHP тежи повече от уязвимост в добавка.

Ръководството на PHP посочва три компонента, необходими за един PHP уебсайт: интерпретатор на PHP (като CGI или сървърен модул), уеб сървър и браузър. Интерпретаторът е програмата, която чете и изпълнява PHP кода. Начинът, по който е свързан с уеб сървъра, определя режима на работа.

Как работи PHP? Седем стъпки на една заявка

  1. Заявка: Браузърът изпраща HTTP заявка, например GET /kontakt.php, до сървъра.
  2. Уеб сървър: Apache, Nginx или LiteSpeed приемат заявката. Статичните файлове като изображения те предоставят сами. За .php файловете извикват PHP.
  3. Предаване през SAPI: Сървърният интерфейс (SAPI) предава на PHP данните от заявката, като заглавни редове, параметри и данни от формуляри. При PHP-FPM това става чрез протокола FastCGI, при mod_php директно в процеса на Apache. Подробности в SAPI, обяснен.
  4. Подготовка на заявката: PHP поставя данните от заявката в променливи като $_GET, $_POST, $_COOKIE и $_FILES и резервира памет за заявката.
  5. Превеждане: Скриптът се разчленява на градивни елементи (токени), от тях се получава абстрактно синтактично дърво (AST) и от него опкодове, един вид машинен език за PHP. Ако OPcache е активен, тази стъпка се прескача, когато скриптът вече е в кеша.
  6. Изпълнение: Виртуалната машина на Zend Engine обработва опкодовете, отправя заявки към бази данни, чете файлове и създава изхода.
  7. Отговор и почистване: Изходът се връща през SAPI към уеб сървъра и оттам към браузъра. След това PHP освобождава паметта на заявката и нулира състоянието.

AST съществува от PHP 7. Според свързания RFC преди това парсерът създавал опкодовете директно по време на четенето; разделянето на три фази направило компилатора по-лесен за поддръжка.

Пример: какво вижда скриптът от заявката

Следният безобиден скрипт показва каква информация PHP получава от заявката и в какъв режим на работа се изпълнява:

<?php
header('Content-Type: text/plain; charset=utf-8');

echo 'Betriebsart (SAPI): ' . PHP_SAPI . "\n";
echo 'PHP-Version: ' . PHP_VERSION . "\n";
echo 'Methode: ' . ($_SERVER['REQUEST_METHOD'] ?? '-') . "\n";
echo 'Speicher in dieser Anfrage: ' . memory_get_usage() . " Bytes\n";

На сървър с PHP-FPM PHP_SAPI извежда стойността fpm-fcgi, при Apache с mod_php apache2handler. Поставяйте такива проверочни файлове в публичната директория само за кратко и никога за постоянно, защото данните за версията помагат и на атакуващите да се ориентират.

Къде се включват кешът за байткод и JIT

Превеждането в стъпка 5 отнема време. OPcache според ръководството съхранява предварително компилиран байткод в споделената памет и така спестява на PHP зареждането и разчленяването на скриптовете при всяка заявка. От PHP 8.0 допълнително JIT компилатор може да създава от опкодовете истински машинен код. Според JIT-RFC той е почти самостоятелна част от OPcache.

Фаза Резултат Кешира ли се?
Лексикален анализ поток от токени не
Синтактичен анализ абстрактно синтактично дърво (AST) не
Компилиране опкодове (op-масиви за всеки файл и функция) да, в OPcache
JIT (по избор) машинен код да, в паметта на OPcache
Изпълнение изход на страницата не

Кешът засяга само преведения код. Данните на отделната заявка, например въведените във формуляри стойности или стойностите на сесията, не се споделят през OPcache.

Защо PHP2Shell засяга точно този процес

Двете уязвимости на PHP2Shell не засягат отделно приложение, а самия процес. При CVE-2026-109618 състояние на изчерпана памет (out-of-memory) може да прекъсне PHP, докато данните от заявката са подготвени само частично, т.е. в стъпка 4. При последвалото почистване невалидни данни могат да бъдат третирани като валидни.

При CVE-2026-109619 вътрешно състояние на заявка може да остане след освобождаването на паметта. По-късна заявка в същия работен процес може да го използва, преди то да бъде нулирано. Това засяга стъпка 7, почистването. Предистория има на страницата CVE-2026-109619 и в статията за жизнения цикъл на заявката.

От това следва: защитните мерки в кода на приложението, например защитни добавки, действат едва в стъпка 6. При mod_php според екипа на PHP е показан експлойт още преди изобщо да се изпълни код на приложението. Действа само актуализацията на PHP до 8.5.12, 8.4.27, 8.3.36 или 8.2.35 и рестартиране на всички PHP процеси, защото дълготрайните работни процеси иначе продължават да изпълняват стария код.

Как помага PHP SOS конкретно?

  • Показване на процеса: Установяваме кой режим на работа, коя конфигурация и кой кеш са действително активни на Вашия сървър.
  • Правилна актуализация: Внасяме актуализацията на PHP и чрез времето на стартиране проверяваме, че вече не работи стар процес.
  • Защита на слоевете: В рамките на заздравяването на сървъра ограничаваме размерите на заявките, паметта и правата там, където действат: пред кода на приложението.
  • Проверка за следи: При сървъри, достъпни без защита, търсим признаци за пробив.

Често задавани въпроси

Превежда ли се PHP кодът наново при всяко извикване?

Без кеш да: PHP разчленява скрипта, изгражда синтактично дърво и от него създава опкодове. При активен OPcache опкодовете лежат в споделената памет и се използват повторно, докато файлът не се промени.

Какво остава в паметта след една заявка?

По принцип състоянието на заявката се почиства накрая, за да започне следващата заявка начисто. Дълготрайни са само неща като OPcache или постоянните връзки. Именно в това почистване се намесва CVE-2026-109619.

Защо PHP трябва да се рестартира след актуализация?

При PHP-FPM и mod_php процесите работят постоянно и са заредили стария програмен код. Новите файлове на диска не променят това. Едва рестартирането зарежда поправения код.

По-сигурен ли е уеб сървър без PHP?

Той има по-малка повърхност за атака, защото никаква програмна логика не реагира на заявките. За чисто статично съдържание това е реална възможност. За магазини, формуляри и влизане в система обаче е нужен език от страна на сървъра и тогава значение има неговата поддръжка.

Източници

Незабавен контакт

Всеки час има значение. Пишете ни сега.

Опишете накратко системата, версията на PHP и какво сте забелязали. Ние се свързваме с Вас, уточняваме ситуацията и работим отдалечено, докато инцидентът бъде приключен и документиран.

Незабавна помощ