Aktuální situace: PHP2Shell. Dvě kritické zranitelnosti PHP (CVSS 9.2) umožňují spustit škodlivý kód bez přihlášení. Záplaty od 21. 10. 2026.Co nyní udělat →

Jak PHP vytváří webovou stránku: cesta požadavku

Co se děje mezi kliknutím a hotovou stránkou: webový server, SAPI, kompilátor, OPcache a Zend VM v sedmi krocích a proč PHP2Shell útočí právě v tomto průběhu.

Stav 4 min čteníZnalosti o PHP

Stručně: Když prohlížeč požádá o stránku PHP, webový server požadavek přijme a předá ho přes rozhraní (SAPI) do PHP. PHP skript přeloží do bytecodu, provede ho v Zend Engine a výsledek, většinou HTML, vrátí webovému serveru. Poté se stav požadavku uklidí, aby další začal s čistým stavem.

Co se stane, když někdo otevře váš web?

Pro návštěvníky je to jedno kliknutí. Na serveru proběhne během milisekund mnoho kroků. Kdo tento průběh zná, lépe chápe, proč jsou aktualizace, restarty a konfigurace tak důležité a proč zranitelnost v samotném PHP váží víc než zranitelnost v pluginu.

Příručka PHP uvádí tři součásti, které jsou pro web v PHP nutné: interpret PHP (jako CGI nebo serverový modul), webový server a prohlížeč. Interpret je program, který čte a provádí kód PHP. Provozní režim určuje, jak je propojen s webovým serverem.

Jak funguje PHP? Sedm kroků požadavku

  1. Požadavek: Prohlížeč pošle na server požadavek HTTP, například GET /kontakt.php.
  2. Webový server: Apache, Nginx nebo LiteSpeed požadavek přijmou. Statické soubory, například obrázky, vydají samy. Pro soubory .php zavolají PHP.
  3. Předání přes SAPI: Serverové rozhraní (SAPI) předá PHP data požadavku, jako jsou hlavičky, parametry a data formulářů. U PHP-FPM se to děje přes protokol FastCGI, u mod_php přímo v procesu Apache. Podrobnosti v článku SAPI vysvětleno.
  4. Příprava požadavku: PHP uloží data požadavku do proměnných jako $_GET, $_POST, $_COOKIE a $_FILES a vyhradí paměť pro požadavek.
  5. Překlad: Skript se rozloží na stavební prvky (tokeny), z nich vznikne abstraktní syntaktický strom (AST) a z něj opcody, jakýsi strojový jazyk pro PHP. Je-li OPcache aktivní, tento krok se přeskočí, pokud už skript leží v cache.
  6. Provedení: Virtuální stroj Zend Engine zpracuje opcody, dotazuje se databází, čte soubory a vytváří výstup.
  7. Odpověď a úklid: Výstup se vrací přes SAPI webovému serveru a od něj prohlížeči. Poté PHP uvolní paměť požadavku a vynuluje stav.

AST existuje od PHP 7. Podle příslušného RFC vytvářel parser dříve opcody přímo při čtení; rozdělení do tří fází usnadnilo údržbu kompilátoru.

Příklad: co skript z požadavku vidí

Následující neškodný skript ukazuje, jaké informace PHP z požadavku získá a v jakém režimu běží:

<?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 serveru s PHP-FPM vypíše PHP_SAPI hodnotu fpm-fcgi, pod Apache s mod_php apache2handler. Takové kontrolní soubory ukládejte do veřejného adresáře jen krátce a nikdy trvale, protože údaje o verzi pomáhají v orientaci i útočníkům.

Kde přichází ke slovu bytecode cache a JIT

Překlad v kroku 5 stojí čas. OPcache podle příručky ukládá předkompilovaný bytecode do sdílené paměti a ušetří PHP načítání a rozklad skriptů při každém požadavku. Od PHP 8.0 může navíc kompilátor JIT vytvářet z opcodů skutečný strojový kód. Podle RFC k JIT je téměř samostatnou součástí OPcache.

Fáze Výsledek Ukládá se do cache?
Lexikální analýza proud tokenů ne
Syntaktická analýza abstraktní syntaktický strom (AST) ne
Kompilace opcody (op-arrays pro soubor a funkci) ano, v OPcache
JIT (volitelný) strojový kód ano, v paměti OPcache
Provedení výstup stránky ne

Cache se týká jen přeloženého kódu. Data jednotlivých požadavků, například vstupy formulářů nebo hodnoty relací, se přes OPcache nesdílejí.

Proč PHP2Shell útočí právě v tomto průběhu

Obě zranitelnosti PHP2Shell se netýkají jedné aplikace, ale samotného průběhu. U CVE-2026-109618 může stav nedostatku paměti přerušit PHP ve chvíli, kdy jsou data požadavku připravena jen částečně, tedy v kroku 4. Při následujícím úklidu pak mohou být neplatná data považována za platná.

U CVE-2026-109619 může vnitřní stav požadavku přetrvat i po uvolnění paměti. Pozdější požadavek ve stejném workeru ho může využít dříve, než se vynuluje. To se týká kroku 7, úklidu. Souvislosti najdete na stránce CVE-2026-109619 a v článku o životním cyklu požadavku.

Z toho plyne: ochranná opatření v kódu aplikace, například bezpečnostní pluginy, zasahují až v kroku 6. U mod_php byl podle týmu PHP předveden exploit dokonce ještě předtím, než se spustí vůbec nějaký kód aplikace. Účinná je jen aktualizace PHP na 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35 a restart všech procesů PHP, protože dlouhodobě běžící workery by jinak dál prováděly starý kód.

Jak konkrétně pomáhá PHP SOS?

  • Zviditelnit průběh: Zjistíme, jaký provozní režim, jaká konfigurace a jaká cache jsou na vašem serveru skutečně aktivní.
  • Aktualizovat správně: Nasadíme aktualizaci PHP a podle časů spuštění ověříme, že už neběží žádný starý proces.
  • Zabezpečit vrstvy: V rámci zpevnění serveru omezíme velikosti požadavků, paměť a oprávnění tam, kde působí: před kódem aplikace.
  • Zkontrolovat stopy: U serverů dostupných bez ochrany hledáme známky průniku.

Časté dotazy

Překládá se kód PHP při každém zavolání znovu?

Bez cache ano: PHP skript rozloží, sestaví syntaktický strom a z něj vytvoří opcody. S aktivní OPcache leží opcody ve sdílené paměti a znovu se používají, dokud se soubor nezměnil.

Co zůstane v paměti po skončení požadavku?

V zásadě se stav požadavku na konci uklidí, aby další požadavek začal s čistým stavem. Dlouhodobě přetrvávají jen věci jako OPcache nebo trvalá spojení. Právě na tomto úklidu staví CVE-2026-109619.

Proč je nutné PHP po aktualizaci restartovat?

U PHP-FPM a mod_php běží procesy trvale a mají načtený starý programový kód. Nové soubory na disku na tom nic nemění. Opravený kód se načte až po restartu.

Je webový server bez PHP bezpečnější?

Má menší útočnou plochu, protože na požadavky nereaguje žádná programová logika. Pro čistě statický obsah je to skutečná možnost. Pro e-shopy, formuláře a přihlášení je ale potřeba jazyk na straně serveru a pak záleží na jeho údržbě.

Zdroje

Okamžitý kontakt

Každá hodina se počítá. Napište nám hned.

Stručně popište systém, verzi PHP a pozorování. Ozveme se, vyjasníme situaci a budeme pracovat na dálku, dokud nebude incident uzavřen a zdokumentován.

Okamžitá pomoc