Do hry navíc vstupuje AI, která bezpečnostním výzkumníkům umožňuje hledat chyby rychleji a odhalovat i takové, které mohly zůstat skryté dlouhá léta. PHP2Shell je názorným příkladem: zranitelnosti v samotném PHP zasahují kód sahající až k verzi 5.4, tedy do roku 2012. Jde o chyby ve správě paměti a práci s interním stavem runtime, nikoliv o nějakou novou funkci, kterou někdo zapomněl správně zabezpečit. Chyby, které v softwaru přežívaly více než desetiletí, se najednou stávají kritickým bezpečnostním problémem.
To neznamená, že AI nutně způsobuje vznik většího množství chyb. Může ale zásadně změnit rychlost, s jakou se ty existující odhalují — a potenciálně i zneužívají. Organizace tak mohou čelit kritickým zranitelnostem v technologiích, které dlouhé roky považovaly za prověřené a stabilní. A pokud mezitím přestaly aktualizovat, přešly na nepodporované verze nebo odkládaly modernizaci, může být cesta k nápravě podstatně složitější než samotná instalace bezpečnostní záplaty.
Čekají nás velmi zajímavé časy, o tom není pochyb.
Proč je PHP2Shell tak závažný problém?
Důvod, proč je PHP2Shell tak významná událost, je vlastně jednoduchý. PHP stále pohání obrovské množství webových aplikací. Najdeme ho v redakčních systémech, e-shopech, interních firemních aplikacích i ve vlastních řešeních, která vznikala dlouhé roky.
PHP2Shell označuje dvojici kritických zranitelností přímo v PHP runtime. Za určitých podmínek umožňují útočníkovi vzdáleně spustit libovolný kód bez autentizace. Nejde tedy o chybu konkrétního redakčního systému nebo jednoho pluginu. Problém je v samotném prostředí, ve kterém aplikace běží.
Pro útočníky je to příležitost získat přístup k velkému množství serverů. Zneužitý server může posloužit k těžbě kryptoměn, vybudování botnetu, krádeži dat nebo jako výchozí bod pro další útoky na infrastrukturu organizace.
Důležité je také to, že aktualizace samotné aplikace problém neřeší. Pokud běží na zranitelné verzi PHP, může být zranitelná i nadále, přestože je její vlastní kód aktuální.
Aktualizace jako zkouška připravenosti
V případě PHP2Shell je zásadní, že úplné odstranění zranitelností vyžaduje nasazení opravené verze PHP. Existují opatření, která mohou riziko dočasně snížit, ale nenahrazují samotnou opravu.
Bezpečnostní oprava přitom nemusí vždy znamenat přechod na novou hlavní verzi PHP. U některých starších větví jsou dostupné také backporty, tedy opravy přenesené do starší verze. alší opravené balíčky poskytují někteří distributoři a dodavatelé dlouhodobé podpory po “vlastní ose”.
Prvním krokem je proto ověřit konkrétní nasazenou verzi PHP a jestli pro ni vyjde oficiální aktualizace, neoficiální od distributora nebo se s aktualizací nepočítá..
Ne všechny systémy lze aktualizovat okamžitě. Některé vyžadují testování, jiné koordinovanou odstávku. A pokud aplikace závisí na staré verzi runtime, může být aktualizace mnohem složitější, než se na první pohled zdá.
A právě tady se celý problém ještě prohlubuje. Nejde totiž vždy o zranitelnost, kterou lze vyřešit instalací několika běžných aktualizací nebo návratem o dvě či tři minor verze zpět. Pokud chyba zasahuje samotné základy runtime a zranitelnost se týká i historických verzí, může být nutné přejít na podporovanou verzi PHP — a s ní upravit aplikaci, její závislosti a někdy i část provozní infrastruktury. Je ale důležité rozlišovat mezi okamžitým odstraněním zranitelnosti a dlouhodobou modernizací. Dostupná bezpečnostní záplata může umožnit rychlou nápravu, zatímco rozsáhlejší změny proběhnou plánovaně. Nezapomínejme na to, že i když oprava těchto zranitelností byla masivně backportována i do velmi starých verzí, nijak to neovlivňuje jiné nalezené zranitelnosti. Např. pro PHP5.6, které je aktuálně nejstarší, pro které se backport objevil, eviduje komunita přes 300 dalších zranitelností, které tato oprava nijak neřeší.
Jenže aplikace, která deset let fungovala na starém PHP, nemusí - a velmi pravděpodobně ani nebude - na současné verzi vůbec fungovat. Závislosti už nemusí být udržované, původní vývojáři nemusí být k dispozici a nikdo nemusí přesně vědět, proč některé části systému fungují právě tak, jak fungují. Z bezpečnostní aktualizace se pak v takovém prostředí může stát migrační projekt s nejistým rozsahem, náklady a termínem dokončení.
Firma tak neplatí jen za opravu konkrétní zranitelnosti. Platí i za všechny roky, během kterých se technologický dluh postupně hromadil.
V praxi se tak ukazuje, jak moc která firma investuje do dlouhodobé údržby svého IT. A jakou prioritu jí ve skutečnosti přikládá.
Firmy se v tomto ohledu dají rozdělit do dvou skupin.
Když je prostředí připravené na aktualizace
Firmy, které průběžně udržují operační systémy, běhová prostředí i aplikace, mají při řešení podobných událostí výhodu. Znají své závislosti, mají zajištěnou bezpečnostní podporu a počítají s aktualizacemi jako s běžnou součástí provozu.
I pro ně ale představuje PHP2Shell především organizační a provozní problém. Potřebují zmapovat dotčené systémy, připravit aktualizace, otestovat je a postupně nasadit.
Ani rozsáhlá automatizace neodstraní všechny provozní překážky. Některé systémy vyžadují regresní testy, jiné koordinaci s dodavateli nebo servisní okno.Rozhodující je, zda má firma připravený proces, kterým podobnou situaci dokážou zvládnout.
Neznamená to, že tyto firmy nemají žádný technický dluh nebo že je nemůže potkat komplikace. Mají ale výrazně větší šanci problém vyřešit rychleji a s menším dopadem na provoz.
Když se údržba dlouhodobě odkládá
Obtížnější situace nastává tam, kde firma provozuje technologie bez bezpečnostní podpory a závislosti, které se roky neaktualizovaly.
Odklad přitom často začíná zdánlivě rozumnou úvahou:
„Úprava aplikace teď není na pořadu dne. Je příliš drahá a příliš náročná.“
A nemusí to být pouze vina samotné firmy. Často jde o softwarové agentury a vývojářské společnosti, které vytvářejí aplikace pro své zákazníky. Po dokončení projektu a předání do provozu ale další investice do rozvoje a údržby narážejí na odpor. Zákazník přece dostal funkční aplikaci, všechno funguje, tak proč by měl platit za další vývoj?
Dodavatel se tak dostává do nepříjemné situace. Aby aplikaci udržel bezpečnou a kompatibilní s aktuálními technologiemi, musí do ní dál investovat. Jenže zákazník za tuto práci nechce platit a náklady nemá kdo pokrýt. Údržba se odkládá, technologický dluh narůstá a riziko zůstává.
Jenže pak přijde PHP2Shell.
Staré verze PHP už nemusí dostávat bezpečnostní opravy. Pro zastaralé distribuce nemusí být k dispozici opravené balíčky. A aplikace napsaná pro dávno nepodporované prostředí nemusí po aktualizaci vůbec fungovat.
Najednou stojí dodavatel před problémem, který musí vyřešit v řádu dnů, přestože na jeho prevenci nebyl zákazník ochoten vynaložit peníze po několik let. Musí najít způsob, jak opravit nebo aktualizovat celý stack, zajistit kompatibilitu aplikace a všechno důkladně otestovat. A to ideálně dřív, než někdo zranitelnost zneužije.
Může se pokusit najít opravu pro starou verzi PHP, nechat ji naportovat, nebo urychleně aktualizovat celý stack včetně samotné aplikace. Žádná z těchto možností ale není zadarmo a ne každou lze provést v řádu hodin.
AI může část práce výrazně urychlit. Pomůže s analýzou starého kódu, hledáním nekompatibilit i přípravou některých úprav. Neodstraní ale automaticky problémy s architekturou, nedostatek testů ani odpovědnost za bezpečnost výsledného řešení.
A pak je tu ještě jeden problém: dodavatel pravděpodobně není jediný, kdo podobnou situaci řeší. Pokud spravuje desítky aplikací pro různé zákazníky, může se během několika dnů ocitnout pod tlakem, který jeho kapacity jednoduše neumožňují zvládnout. Zákazníci najednou požadují urgentní zásah, ale lidé, kteří rozumějí starému kódu, jsou jen jedni.
Celý problém, jehož řešení se roky odkládalo, se najednou stává nejvyšší prioritou. A musí být vyřešen v termínu, který si nikdo zúčastněný nevybral.
Tohle je okamžik, kdy se z odkládané údržby stává akutní business problém. Nejen pro zákazníka, jehož aplikace je zranitelná, ale také pro dodavatele, který musí řešení zajistit, přestože na jeho průběžnou údržbu dlouhodobě nedostával odpovídající rozpočet.
Jak jsme postupovali ve vshostingu
Běžně se zranitelnosti veřejně oznamují společně s vydáním opravy. To dává správcům systémů možnost ihned reagovat na situaci a jejich startovní čára je vlastně stejná, jako u útočníků. V případě PHP2Shell ale samotná zranitelnost byla oznámena několik hodin před dostupnou aktualizací, čímž útočníci získali nemalý náskok.
Náš tým samozřejmě monitoruje seznamy oznámených zranitelností a ihned po oznámení jsme začali sestavovat seznam afektovaných systémů a odhadovat, kde bude aktualizace bezproblémová a kde můžeme čekat problémy. Ihned po zveřejnění opravy jsme začali plošně nasazovat nové verze na servery našich klientů. Priorita přitom byla jasná - co lze opravit ihned, opravit. Přirozeně tedy byly v první vlně servery, které mají nasazeny aktuální verze PHP a distribuce, kde stačilo pouze nasadit nový balíček. Jak se začaly objevovat další a další backporty, nasazovali jsme je na nově opravené verze.
Ani toto ale nestačilo k záplatování všech afektovaných systémů. V následujících hodinách jsme tedy přistoupili k vlastním backportům oprav pro verze, na které se opravy z jiných zdrojů nepřipravovaly. Díky tomu jsme už během středeční noci zvládli aktualizovat vetšinu dotčených systémů a další v průběhu čtvrtka. Samozřejmě platí, že čím starší distribuce a verze PHP, tím komplikovanější backport je a tedy dojde k pozdějšímu nasazení.
Pro některé velmi staré verze distribucí a PHP je backport bohužel nereálný. V těchto případech nezbývá než v úzké spolupráci s klientem připravit distribuční update celého serveru. Tento krok je ovšem nejen časově mnohem náročnější než pouhý upgrade PHP, ale zároveň vede k mnohem výraznějším zásahům do infrastruktury jako celku. Někteří klienti se tedy radši rozhodli jít cestou instalace nového serveru s aktuální distribucí a migraci aplikace a dat.
Technický dluh není zadarmo
Technický dluh sám o sobě není špatně. Někdy dává smysl odložit refaktoring, ponechat stabilní komponentu na starší verzi nebo vědomě přijmout určité omezení. Důležité je vědět, proč to děláme, jaká rizika tím vznikají a kolik bude stát jejich odstranění.
Problém nastává ve chvíli, kdy firma přestane cenu technického dluhu sledovat, nepočítá s náklady na jeho splácení a začne se tvářit, že neexistuje.
V takovém případě už nejde o vědomý kompromis, ale o neřízené riziko.
Představme si aplikaci, kterou její dodavatel vytvořil před osmi lety. Funguje, zákazníci ji používají a firma z ní má příjmy. Průběžná údržba by stála peníze, takže ji vedení opakovaně odkládá.
Na první pohled je to ekonomicky výhodné rozhodnutí. Firma ušetří na vývoji a aplikace dál vydělává.
Jenže tento výpočet má jeden zásadní nedostatek: ignoruje budoucí náklady a rizika.
Čím déle se aktualizace odkládají, tím více se mohou rozcházet používané technologie s aktuálními verzemi. Přibývají nekompatibility, zastaralé knihovny a části kódu, kterým už nikdo pořádně nerozumí. Původně jednoduchá aktualizace se postupně může měnit v náročnou modernizaci.
A když potom přijde kritická zranitelnost, firma neřeší jen bezpečnostní opravu. Musí současně řešit kompatibilitu aplikace, dostupnost dodavatele, testování, provozní rizika a termín nápravy.
K tomu se přidávají možné náklady na odstávku, incident response, obnovu systémů, komunikaci se zákazníky nebo řešení úniku dat.
Firma ve skutečnosti neušetřila náklady na údržbu. Jen je přesunula do budoucnosti, kde mohou být násobně vyšší a kde už nemusí mít možnost rozhodnout, kdy je zaplatí.
A právě to je na podobných událostech nejhorší.
U regulovaných organizací jde také o plnění povinností
Kromě finančních a provozních dopadů může mít zanedbaná údržba také legislativní důsledky. V souvislosti se směrnicí NIS2 a novým českým zákonem o kybernetické bezpečnosti už nejde pouze o to, zda firma dokáže svůj systém opravit, když se objeví kritická zranitelnost. U regulovaných organizací jde také o to, zda má odpovídajícím způsobem nastavené řízení kybernetických rizik, bezpečnostní opatření a procesy pro zvládání incidentů.
To se týká i přístupu k aktualizacím a zranitelnostem. Pokud organizace dlouhodobě provozuje nepodporované technologie, ignoruje dostupné bezpečnostní opravy a nemá plán, jak tato rizika řídit, může se dostat do rozporu s požadavky, které se na ni vztahují. Samotné použití starší technologie automaticky neznamená porušení zákona. Rozhodující je konkrétní situace, režim regulace a přijatá opatření.
Nová právní úprava navíc klade větší důraz na odpovědnost vedení za řízení kybernetické bezpečnosti. Bezpečnost tak přestává být pouze technickým tématem, které lze odsunout na IT oddělení. Stává se součástí řízení organizace a jejích rizik.
A právě tady se může dlouhodobě odkládaná údržba stát ještě dražší. Firma totiž nemusí řešit pouze samotnou zranitelnost, náklady na nápravu a případné škody. Podle konkrétních okolností může řešit také plnění regulatorních povinností, dohled příslušných orgánů a případné sankce.
NIS2 samozřejmě neznamená, že každá zranitelnost automaticky vede k pokutě. Je ale dalším důvodem, proč by firmy měly mít technický dluh pod kontrolou a být schopné doložit, jak bezpečnostní rizika identifikují, vyhodnocují a řeší.
Kdo za technický dluh odpovídá?
Je snadné ukázat na vývojáře a správce infrastruktury. Jenže ti často nemají pravomoc rozhodnout o rozpočtu ani o prioritách.
Pokud vedení firmy opakovaně odmítá financovat aktualizace, protože aplikace přece funguje, nejde o technické selhání. Jde o obchodní rozhodnutí.
Takové rozhodnutí může být legitimní. Firma nemusí mít neomezený rozpočet a ne každý systém si zaslouží okamžitou modernizaci.
Měla by ale vědomě přijmout také riziko, které tím vzniká.
Pokud se rozhodne provozovat nepodporovanou aplikaci, měla by vědět, jak je vystavená útokům, jaká existují dočasná ochranná opatření, jak rychle dokáže reagovat na kritickou zranitelnost a jaký má plán pro případ, že se aplikace stane neudržitelnou.
Odpovědnost má ale i dodavatel: měl by srozumitelně vysvětlit rozsah údržby, upozorňovat na končící podporu a včas předkládat možnosti nápravy. Rizika a rozhodnutí o jejich přijetí je vhodné dokumentovat.
Mezi zákazníkem, vývojářem a poskytovatelem infrastruktury musí být jasně určeno, kdo spravuje operační systém a PHP, kdo udržuje aplikační kód a knihovny a kdo ověřuje funkčnost po změně. Rozdělení se může lišit podle služby a smlouvy. Samotné označení „managed“ proto nenahrazuje konkrétní vymezení odpovědností.
Ve vshosting se snažíme klienty na používání verzí na konci nebo po konci oficiální podpory upozorňovat a navrhovat včasnou aktualizaci. Konečné slovo je ale vždy na klientovi, kdy a za jakých okolností aktualizaci naplánuje. Dokud je klid, má klient čas aplikaci s novou verzí PHP otestovat a odladit bez časové tísně. Pokud ale čeká příliš dlouho, může být k aktualizaci donucen těmito událostmi a prostor pro testování a opravy se dramaticky snižuje. První pokusy o zneužití zranitelnosti PHP2Shell se objevily několik desítek minut po zveřejnění, času tedy je opravdu málo.
Co by si z PHP2Shell měly firmy odnést?
Ne každá firma potřebuje kompletně přepsat své aplikace. Ne každá starší technologie představuje automaticky nezvládnutelné riziko. A ne každou aktualizaci lze provést okamžitě.
Existuje ale několik principů, které výrazně pomáhají podobné situace zvládat.
1. Mějte přehled o tom, co skutečně provozujete.
Potřebujete vědět, kde všude používáte PHP, jaké verze běží na jednotlivých serverech a které aplikace jsou dostupné z internetu. Nezapomínejte na kontejnery, interní systémy, zapomenuté virtuální stroje ani aplikace provozované externími dodavateli.
Co nemáte pod kontrolou a nedokážete identifikovat, to nemůžete spolehlivě zabezpečit.
2. Udržujte aplikace na podporovaných verzích.
Průběžné aktualizace runtime, operačního systému a knihoven nejsou volitelný bonus. Jsou součástí životního cyklu aplikace.
Pokud aplikace přestává být kompatibilní s podporovanými verzemi svých závislostí, je to signál, že potřebuje investici do údržby nebo modernizace.
3. Počítejte s bezpečnostními opravami už při návrhu systému.
Automatizované nasazování, reprodukovatelná prostředí, regresní testy a pravidelně ověřovaný postup aktualizace dokážou výrazně zkrátit dobu potřebnou k nápravě.
Nejde jen o rychlost deploymentu. Jde také o schopnost ověřit, že aktualizace nezpůsobila další problémy.
4. Rozlišujte mezi dočasnou mitigací a skutečnou opravou.
WAF, omezení přístupu, segmentace sítě nebo vypnutí nepotřebných funkcí mohou být důležitou součástí obrany. Jejich účinnost ale závisí na konkrétní zranitelnosti a způsobu nasazení. U PHP2Shell nenahrazují opravu PHP.
Pokud je k dispozici bezpečnostní oprava, musí být jasné, kdo ji nasadí, v jakém termínu a jak se ověří výsledek.
5. Mějte plán pro systémy, které už nelze rozumně aktualizovat.
Někdy je správným řešením modernizace, jindy migrace na jinou platformu nebo vyřazení aplikace. Dočasně může pomoci také izolace systému od veřejné sítě, pokud to jeho provozní účel dovoluje.
Důležité je nepovažovat dočasné řešení za trvalý stav jen proto, že aktuální problém přestal být viditelný.
Plán by měl mít konkrétního vlastníka, rozpočet a termín.
O termínu údržby by neměla rozhodovat krize
Poučení z PHP2Shell je vlastně jednoduché.
Neodkládejte průběžné aktualizace jen proto, že dnes všechno funguje tak, jak má. Neodkládejte modernizaci jen proto, že vás teď bude stát několik dnů vývoje. A nepovažujte údržbu za zbytečný náklad, který lze donekonečna přesouvat na příští rok.
Dříve nebo později budete muset zastaralý stack aktualizovat tak jako tak. Čím déle budete čekat, tím větší a dražší problém si pravděpodobně připravíte.
Technický dluh může být vědomým kompromisem. Nesmí se ale stát neviditelným závazkem, o kterém firma neví, dokud není pozdě.
Osobně tomu říkám Prů*er-driven development.
A je to jedna z nejdražších metodik, kterou můžete ve firmě implementovat.