PHP2Shell: dvě kritické díry v PHP, které nejde odložit
Dvacátého října ohlásilo PHP na další den mimořádnou bezpečnostní opravu. Šlo o dvě chyby, přes které může útočník bez přihlášení spustit na serveru vlastní kód. Co to je, proč to vzniklo a co s tím udělat.
Opravy PHP obvykle vycházejí potichu. Tentokrát ale tým PHP 20. října dopředu varoval, že druhý den vydá opravu dvou kritických zranitelností s hodnocením CVSS 9,2 z 10. Pro jistotu dodal, že ji vydá dřív, kdyby podrobnosti unikly. Ty skutečně unikly a útočníci je začali zkoušet ještě před zveřejněním opravy.
Chyby dostaly přezdívku PHP2Shell. Útočník přes ně může bez hesla spustit na serveru vlastní kód, a to s oprávněními webu: vidí jeho soubory, heslo k databázi a může zapisovat, kam smí PHP. Týká se to prakticky každého webu na PHP, ať jde o WordPress, Laravel, Nette nebo vlastní kód. Nejvíc ohrožený je Apache s mod_php, kde útok proběhne dřív, než se spustí aplikace.
Opravené verze: 8.5.12, 8.4.27, 8.3.36 a 8.2.35. Pro PHP 7.4 až 8.1 existují jen zdrojové záplaty a starší verze opravu nedostanou.
Jak to funguje
Obě chyby jsou typu use-after-free: PHP použije paměť, kterou už uvolnilo a ve které mezitím mohou být data útočníka.
CVE-2026-109618 si představte jako kuchaře, který při nedostatku místa na lince všeho nechá a odejde. Uklízečka pak uklízí podle lístku, který kuchař stihl napsat jen napůl. PHP se při vyčerpání paměti chová podobně: okamžitě vyskočí z rozdělané práce a úklid se pak řídí napůl nastavenými daty.
CVE-2026-109619 připomíná hotel, kde se pokoj mezi hosty neuklidí celý. Server na PHP používá stejné procesy pro další a další návštěvníky. Když se požadavek nečekaně přeruší, zůstane v procesu „lístek“ odkazující na paměť, která už patří někomu jinému. Další požadavek se podle něj řídí.
Proč to vzniklo
PHP od začátku stojí na pravidle, že se na konci požadavku všechno zahodí a další začíná načisto. Jenže kvůli výkonu se procesy používají opakovaně a pravidlo přestane platit, jakmile se někde zapomene něco vynulovat. K tomu přistupuje zkratka „při nedostatku paměti hned utéct“, která předpokládá, že je na to připravené každé místo v kódu. A PHP je napsané v C, které nehlídá, jestli paměť ještě patří vám. Chyba tak vznikla ze souběhu tří starých rozhodnutí v situacích, které nikdo běžně netestuje.
Z praxe
Podle Amazonu přišel první pokus o zneužití už 17. října, tedy čtyři dny před vydáním opravy. Hned po ní se na GitHubu objevily stovky „exploitů“, z velké části falešných. Bezpečnostní firmy přesto zachytily skutečné pokusy, mimo jiné snahu podstrčit na server webshell, skript, přes který útočník server ovládá.
Typická oběť vypadá nenápadně: malý e-shop na levném VPS, PHP naposledy aktualizované v létě. Automatický skener ho po pár pokusech prolomí, přečte heslo k databázi a do pokladny vloží skript, který kopíruje platební karty. Web přitom nemusí mít žádnou chybu ve vlastním kódu.
Není to přehnaná obava. Chybu CVE-2024-4577 z června 2024 začal ransomware zneužívat necelé dva dny po zveřejnění.
Co dělat
- Aktualizujte PHP a restartujte všechny jeho procesy (PHP-FPM, Apache). Debian a Ubuntu opravu často vracejí do starší verze, takže nižší číslo z
php -vnemusí znamenat zranitelnost. Ověřte ji v bezpečnostním přehledu distribuce. - V Dockeru obraz znovu sestavte se staženým základem (
docker compose build --pull), samotnéup -dnestačí. Pak zkontrolujte verzi přímo v kontejneru. - Na sdíleném hostingu se zeptejte poskytovatele, jestli už aktualizoval.
- Když aktualizovat hned nejde, pomohou dočasná opatření z oficiálního upozornění, třeba vypnutí
session.upload_progress. Úplně ale díru neuzavřou. - Zkontrolujte server. Pokud běžel na zranitelné verzi, hledejte nové soubory ve složce webu, nové úlohy v cronu a padající procesy PHP.
Bezpečnost webu nestojí jen na vlastním kódu, ale i na prostředí, ve kterém běží. Proto se vyplatí mít nasazení připravené tak, aby oprava byla otázkou jednoho příkazu.
Zdroje: php.net – upozornění · php.net – opravy · Root.cz · GHSA-w8hw-w9fx-j79w · GHSA-6wmf-4rv5-p3rp · Censys