Stručně: Superglobály jsou předdefinovaná pole, která PHP při každém požadavku automaticky plní a která jsou dostupná všude v kódu. $_GET obsahuje parametry z adresy, $_POST data formulářů, $_FILES nahrané soubory, $_COOKIE cookies a $_SERVER údaje o požadavku a serveru. PHP tato pole vytváří dříve, než se spustí kód vaší aplikace. Proto zranitelnosti právě v tomto zpracování, jako u PHP2Shell, nelze zachytit kontrolami v aplikaci.
Co jsou superglobály?
V PHP platí proměnná normálně jen ve funkci, ve které byla vytvořena. Superglobály jsou výjimka: jsou dostupné v každém oboru platnosti, aniž by je bylo nutné získávat pomocí global. Příručka PHP jich uvádí devět.
Pro netechniky to lze popsat takto: superglobály jsou poštovní schránka aplikace. Vše, co návštěvník pošle, se tam dostane dříve, než to aplikace přečte. A vše ve schránce potenciálně pochází od cizího člověka.
Superglobály v přehledu
| Superglobál | Obsah | Původ |
|---|---|---|
$_GET |
parametry z adresy (query string) | klient |
$_POST |
pole formuláře požadavku POST | klient |
$_FILES |
údaje o nahraných souborech | klient, zpracováno PHP |
$_COOKIE |
cookies zaslané prohlížečem | klient |
$_REQUEST |
směs GET, POST a případně cookies | klient |
$_SERVER |
hlavičky požadavku, metoda, cesty, údaje o serveru | webový server a klient smíšeně |
$_ENV |
proměnné prostředí | server |
$_SESSION |
data aktuální relace | úložiště serveru |
$GLOBALS |
všechny globální proměnné | skript |
Obzvlášť záludné je $_SERVER. Podle příručky vytváří PHP pro každou hlavičku požadavku položku začínající HTTP_, například HTTP_USER_AGENT. Tyto hodnoty nastavuje sám klient. Také SERVER_NAME může podle příručky obsahovat název hostitele dodaný klientem a pro bezpečnostní rozhodnutí není spolehlivý.
Jak PHP superglobály plní
Dříve než se provede první znak vašeho skriptu, PHP už pracovalo. Přečte adresu, hlavičky a obsah požadavku, rozloží je a výsledky uloží do polí. Tento krok řídí několik nastavení:
variables_order(výchozíEGPCS) určuje, která superglobální pole se vůbec vytvoří: Environment, GET, POST, Cookie, Server.request_order(výchozí prázdné) určuje, z čeho se sestaví$_REQUEST. Je-li prázdné, platívariables_order. Dodávané soubory php.ini podle příručky cookies z bezpečnostních důvodů vynechávají.max_input_vars(výchozí1000) amax_input_nesting_level(výchozí64) omezují počet a vnoření vstupních proměnných.post_max_size(výchozí8M) omezuje obsah požadavku. Je-li požadavek větší, zůstanou$_POSTa$_FILESprázdné.enable_post_data_reading(výchozí zapnuto) řídí, zda PHP obsah požadavků POST vůbec automaticky vyhodnocuje.
Je-li enable_post_data_reading vypnuto, aplikace čte surový obsah sama přes php://input. Od PHP 8.4.0 existuje navíc request_parse_body(), které vyhodnocuje data formulářů a nahrávání i pro jiné metody než POST a umožňuje vlastní mezní hodnoty. Jak podrobně probíhá část nahrávání, vysvětluje stránka Jak PHP zpracovává nahrávání souborů.
Bezpečné zacházení s daty požadavků
Zásada je jednoduchá: každá hodnota z $_GET, $_POST, $_COOKIE, $_FILES a z položek HTTP_ v $_SERVER je cizí vstup. Při přijetí se ověřuje a při výstupu se vhodně escapuje.
<?php
declare(strict_types=1);
// Očekává se celé číslo: ověřit místo slepého převodu
$seite = filter_var($_GET['seite'] ?? '1', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 500],
]);
if ($seite === false) {
http_response_code(400);
exit('Ungültige Seitenzahl');
}
// Povolit jen přípustné hodnoty
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
? $_GET['sort']
: 'datum';
// Výstup vždy escapovat
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');
Častým úskalím jsou údaje o původu požadavku. Pokud před webovým serverem stojí reverzní proxy, load balancer nebo CDN, obsahuje $_SERVER['REMOTE_ADDR'] adresu tohoto prostředníka, nikoli návštěvníka. Skutečná adresa je pak v hlavičce jako X-Forwarded-For, kterou si ale může nastavit každý klient sám. Aplikace smí takové hlavičky vyhodnocovat jen tehdy, pokud požadavek prokazatelně přichází z vlastní, známé proxy. Jinak lze blokování podle IP adresy nebo protokoly snadno oklamat. Podobně platí pro HTTPS: končí-li šifrování na proxy, musí aplikace výslovně vědět, že původní spojení bylo šifrované.
Další vzory pro validaci a filtrování ukazuje článek Validace a filtrování vstupů v PHP. Pro data relace v $_SESSION platí vlastní pravidla; najdete je na stránce Relace a cookies v PHP.
Superglobály a PHP2Shell: co se děje před vaším kódem
Zde leží souvislost s aktuální situací. CVE-2026-109618 popisuje, že stav nedostatku paměti může přerušit PHP ve chvíli, kdy jsou data požadavku inicializována jen částečně; při úklidu požadavku pak mohou být neplatná data považována za platná. U CVE-2026-109619 může vnitřní stav požadavku přetrvat po uvolnění paměti a může jej využít pozdější požadavek ve stejném workeru.
Obě zranitelnosti tedy leží ve zpracování, které PHP samo provádí kolem požadavku, nikoli v kódu aplikace. Tým PHP hodnotí riziko u mod_php nejvýše; tam byl předveden exploit dříve, než se vůbec spustí kód aplikace. Žádné filter_var() ani kontrola v aplikaci tomu nezabrání.
Povinná je aktualizace na PHP 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35 a restart všech procesů PHP. Přechodná opatření z php.net, například užší meze pro post_max_size, nejsou úplnou ochranou.
Jak konkrétně pomáhá PHP SOS?
- Zkontrolujeme účinné mezní hodnoty pro data požadavků u každého webu a nastavíme je podle aplikace.
- Nasadíme aktualizaci PHP, restartujeme všechny workery a doložíme stav záplat v rámci naší služby PHP-Patch.
- Individuální vývoj ověříme, zda se hodnoty ze superglobálů nedostávají neověřené do databáze, souborového systému nebo výstupu.
- Zajistíme logy webového serveru od 20. 10. 2026, aby bylo možné pozdější vyhodnocení.
Časté dotazy
Kolik superglobálů v PHP existuje?
Příručka PHP uvádí devět: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST a $_ENV. Jsou dostupné v každém oboru platnosti, i ve funkcích a metodách.
Jsou hodnoty v $_SERVER důvěryhodné?
Jen zčásti. Položky začínající HTTP_ pocházejí z hlaviček požadavku klienta. Příručka například varuje, že SERVER_NAME může odrážet název hostitele dodaný klientem a pro bezpečnostní rozhodnutí není spolehlivý.
Proč je $_POST někdy prázdné, i když byl formulář odeslán?
Nejčastější příčinou je požadavek větší než post_max_size. Pak zůstanou $_POST a $_FILES podle příručky prázdné. Vede k tomu i vypnuté nastavení enable_post_data_reading.
Měl by se používat $_REQUEST?
Raději ne. $_REQUEST míchá data z různých zdrojů a který zdroj vyhraje, závisí na request_order a variables_order. Hodnoty čtěte cíleně z $_GET nebo $_POST.