Stručne: Keď prehliadač vyžiada stránku PHP, webový server požiadavku prijme a cez rozhranie (SAPI) ju odovzdá PHP. PHP preloží skript do bytecode, vykoná ho v Zend Engine a výsledok, zvyčajne HTML, vráti webovému serveru. Potom sa stav požiadavky upratá, aby ďalšia začala čistá.
Čo sa stane, keď niekto otvorí váš web?
Pre návštevníka je to jedno kliknutie. Na serveri sa v priebehu milisekúnd odohrá množstvo krokov. Kto tento priebeh pozná, lepšie chápe, prečo sú aktualizácie, reštarty a konfigurácia také dôležité a prečo je zraniteľnosť v samotnom PHP závažnejšia než zraniteľnosť v zásuvnom module.
Príručka PHP uvádza tri súčasti potrebné pre web v PHP: interpreter PHP (ako CGI alebo serverový modul), webový server a prehliadač. Interpreter je program, ktorý číta a vykonáva kód PHP. Spôsob, akým je prepojený s webovým serverom, určuje režim prevádzky.
Ako funguje PHP? Sedem krokov jednej požiadavky
- Požiadavka: Prehliadač pošle na server požiadavku HTTP, napríklad
GET /kontakt.php. - Webový server: Apache, Nginx alebo LiteSpeed požiadavku prijmú. Statické súbory ako obrázky odovzdávajú samy. Pre súbory
.phpvolajú PHP. - Odovzdanie cez SAPI: Serverové rozhranie (SAPI) odovzdá PHP údaje požiadavky, ako hlavičky, parametre a údaje formulára. Pri PHP-FPM sa to deje cez protokol FastCGI, pri mod_php priamo v procese Apache. Podrobnosti v časti SAPI vysvetlené.
- Príprava požiadavky: PHP uloží údaje požiadavky do premenných ako
$_GET,$_POST,$_COOKIEa$_FILESa vyhradí pamäť pre požiadavku. - Preklad: Skript sa rozloží na stavebné prvky (tokeny), z nich vznikne abstraktný syntaktický strom (AST) a z neho opcódy, akýsi strojový jazyk pre PHP. Ak je OPcache aktívna, tento krok sa preskočí, ak už skript leží v cache.
- Vykonanie: Virtuálny stroj Zend Engine spracúva opcódy, dopytuje databázy, číta súbory a vytvára výstup.
- Odpoveď a upratanie: Výstup ide cez SAPI späť webovému serveru a odtiaľ prehliadaču. Potom PHP uvoľní pamäť požiadavky a obnoví stav.
AST existuje od PHP 7. Podľa príslušného RFC vytváral parser predtým opcódy priamo počas načítavania; rozdelenie na tri fázy zjednodušilo údržbu kompilátora.
Príklad: čo skript vidí z požiadavky
Nasledujúci neškodný skript ukazuje, aké informácie PHP z požiadavky dostáva a v akom režime beží:
<?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";
Na serveri s PHP-FPM vypíše PHP_SAPI hodnotu fpm-fcgi, pod Apache s mod_php apache2handler. Takéto kontrolné súbory ukladajte do verejného adresára len nakrátko a nikdy nie natrvalo, pretože údaje o verzii pomáhajú aj útočníkom pri orientácii.
Kde vstupuje do hry bytecode cache a JIT
Preklad v kroku 5 stojí čas. OPcache podľa príručky ukladá vopred skompilovaný bytecode do zdieľanej pamäte a ušetrí PHP načítavanie a rozkladanie skriptov pri každej požiadavke. Od PHP 8.0 dokáže navyše kompilátor JIT vytvárať z opcódov skutočný strojový kód. Podľa RFC k JIT je to takmer samostatná súčasť OPcache.
| Fáza | Výsledok | Ukladá sa do cache? |
|---|---|---|
| Lexing | tok tokenov | nie |
| Parsing | abstraktný syntaktický strom (AST) | nie |
| Kompilácia | opcódy (op-arrays podľa súboru a funkcie) | áno, v OPcache |
| JIT (voliteľné) | strojový kód | áno, v pamäti OPcache |
| Vykonanie | výstup stránky | nie |
Cache sa týka iba preloženého kódu. Údaje jednotlivej požiadavky, napríklad vstupy formulára alebo hodnoty relácie, sa cez OPcache nezdieľajú.
Prečo PHP2Shell zasahuje práve do tohto priebehu
Obe zraniteľnosti PHP2Shell sa netýkajú jednej aplikácie, ale samotného priebehu. Pri CVE-2026-109618 môže stav Out-of-Memory prerušiť PHP vo chvíli, keď sú údaje požiadavky pripravené len sčasti, teda v kroku 4. Pri následnom upratovaní sa potom môžu neplatné údaje spracovať ako platné.
Pri CVE-2026-109619 môže vnútorný stav požiadavky zostať po uvoľnení pamäte zachovaný. Neskoršia požiadavka v tom istom workeri ho môže použiť skôr, než sa obnoví. To sa týka kroku 7, upratovania. Súvislosti nájdete na stránke CVE-2026-109619 a v príspevku o životnom cykle požiadavky.
Z toho vyplýva: ochranné opatrenia v kóde aplikácie, napríklad bezpečnostné zásuvné moduly, zasiahnu až v kroku 6. Pri mod_php sa podľa tímu PHP ukázal exploit dokonca ešte predtým, než vôbec beží kód aplikácie. Účinná je len aktualizácia PHP na 8.5.12, 8.4.27, 8.3.36 alebo 8.2.35 a reštart všetkých procesov PHP, pretože dlhodobo bežiace workery by inak ďalej vykonávali starý kód.
Ako konkrétne pomáha PHP SOS?
- Priebeh urobiť viditeľným: Zisťujeme, aký režim prevádzky, aká konfigurácia a aká cache sú na vašom serveri skutočne aktívne.
- Aktualizovať správne: Nasadíme aktualizáciu PHP a podľa časov spustenia overíme, že už nebeží žiadny starý proces.
- Zabezpečiť vrstvy: V rámci zabezpečenia servera (hardening) obmedzujeme veľkosti požiadaviek, pamäť a práva tam, kde pôsobia: pred kódom aplikácie.
- Skontrolovať stopy: Pri serveroch dostupných bez ochrany hľadáme známky prieniku.
Časté otázky
Prekladá sa kód PHP pri každom volaní odznova?
Bez cache áno: PHP rozloží skript, zostaví syntaktický strom a vytvorí z neho opcódy. Pri aktívnej OPcache ležia opcódy v zdieľanej pamäti a používajú sa opakovane, kým sa súbor nezmení.
Čo zostane v pamäti po požiadavke?
V zásade sa stav požiadavky na konci upratuje, aby ďalšia požiadavka začala čistá. Dlhodobé sú len veci ako OPcache alebo perzistentné spojenia. Práve pri tomto upratovaní zasahuje CVE-2026-109619.
Prečo sa PHP po aktualizácii musí reštartovať?
Pri PHP-FPM a mod_php procesy bežia trvalo a majú načítaný starý programový kód. Nové súbory na disku na tom nič nemenia. Opravený kód sa načíta až po reštarte.
Je webový server bez PHP bezpečnejší?
Má menšiu útočnú plochu, pretože na požiadavky nereaguje žiadna programová logika. Pre čisto statický obsah je to skutočná možnosť. Pre obchody, formuláre a prihlasovanie však potrebujete jazyk na strane servera a vtedy záleží na jeho údržbe.