Oprava chyby Nette: jak jsme si poradili se zranitelností nejvyšší závažnosti

29. 10. 2020
Doba čtení: 10 minut

Sdílet

 Autor: Nette
V článku se s vámi podělíme o to, jak jsme se vypořádali s největší známou bezpečnostní zranitelností Nette v posledních letech, známou jako CVE-2020–15227, která postihla nejenom naše projekty.

Aktuálně touto kritickou zranitelností trpí desítky tisíc webů v ČR i zahraničí – ujistěte se, že mezi nimi není i nějaký vámi vlastněný či provozovaný web.

Rychle odhalit a záplatovat

Vývoj každého softwaru doprovází po celou dobu jeho provozu bezpečnostní rizika. Nezáleží na tom, jestli používáte open-source nebo closed-source technologie či frameworky. Jedno je jasné – dřív nebo později se objeví bezpečnostní chyba (ať už v kódu aplikace, nebo třeba v architektuře procesoru), kterou dokáže útočník zneužít.

Následkem zneužití může být narušení chodu software a v nejhorším případě odcizení citlivých dat. Důležité je proto dbát na bezpečnost nejen v průběhu vývoje, ale zároveň mít nástroje a procesy pro rychlé odhalení a záplatování takové zranitelnosti. A to ideálně v plném provozu.

Efektivní vývoj vyžaduje jednu platformu

V SiteOne vyvíjíme webové stránky a aplikace pro desítky různých klientů, o jejichž vývoj se stará více než třicet našich FE/BE vývojářů. Jejich produkční provoz zajišťují naši správci serverů, kteří se starají o desítky našich fyzických serverů ve třech datacentrech v Praze. Na nich běží zhruba 120 virtuálních serverů a celkem přes 1 100 produkčních i náhledových domén pro stovky projektů, které jsme za 20 let existence vyvinuli a pořád je provozujeme.

Abychom naší práci pro naše klienty dokázali dělat kvalitně, efektivně i konkurenceschopně, museli jsme se včas rozhodnout při výběru technologií a frameworků, nad kterými naši „platformu“ postavíme a kterou budou naší stávající i budoucí kolegové skvěle ovládat. Podle našich zkušeností nejde dělat kvalitní a zároveň efektivně vyvinutý software bez toho, aby byli vývojáři „kovaní“ v konkrétním frameworku a aby nad ním ideálně měli i různé generátory kódu, které ušetří otročinu typu „CRUD“, práci na vrstvě nad relační DB, tvorbu procesů na pozadí, vytváření aplikačních monitoringů či jiné denní rutinní úkoly.

V oblasti bezpečnosti celá naše platforma poskytuje různé námi vyvinuté nebo konfigurované úrovně ochrany – od firemních procesů (zálohování a aktivních či pasivních monitoringů, nasmlouvaných ochran od ISP, přes routery, síťové firewally, WAF, webservery) až po aplikační či databázové servery a další provozní technologie. Vždy si uvědomujeme rezervy v různých oblastech a vkládáme do nich každoročně velké množství energie, času i peněz. Absolutní bezpečnost totiž neexistuje. Útočníci i dostupné nástroje jdou neustále kupředu, proto musíme i my. Není ale rozhodně denní chleba, aby se objevovaly zranitelnosti, které lze zneužít plošně (navíc triviálně) a jde jimi napáchat největší škody. Pokud tedy pomineme platformy typu Wordpress a zejména jeho různé 3rd-party pluginy.

Od roku 2010 tvoří jednu z našich hlavních součásti BE framework Nette. Nad ním máme desítky vlastních composer balíčků a generátorů tvořících základ SiteOne CMS i různých generací našich API backendů (SOAP, AMF, RPC, REST, GraphQL) a ORM vrstev nad různými databázemi. Díky tomu všemu jsme schopni skutečně reusovat některá hotová řešení mezi projekty a zároveň ho zpětně v projektech vylepšovat a aktualizovat.

Kritická zranitelnost

Framework Nette je na trhu 13 let a kritická zranitelnost CVE-2020–15227 byla objevená v kódu, který byl součásti frameworku od roku 2011. Byla součástí všech jeho „malých“ i „velkých“ verzí. Zranitelnost objevil jistý Cyku Hong z asijské společnosti Devco.re, který pravděpodobně prováděl penetrační testy nějakého webu postaveného nad Nette frameworkem a evidentně se velmi detailně zaměřil i na veškerý kód frameworku.

Riziko této zranitelnosti spočívá v tom, že prostřednictvím speciálně sestrojené URL adresy bylo možné na serveru spustit nežádoucí funkce a za jistých okolností dokonce nahrát a spustit třeba i vlastní kód. Tento typ zranitelnosti je považován za jeden z nejzávažnějších, skrze něj je totiž možné získat přístup do databáze nebo k jiným citlivým projektovým datům.

Hned po objevení prvních informací o této zranitelnosti postupovali vývojáři Nette frameworku vhodným způsobem. Potichu a bez velkého upozorňování vydali opravné verze a to i u těch nejstarších verzí frameworku, které už mají dávno ukončený čas podpory (a za to jim patří velké dík). Záhy informovali všechny známé partnery frameworku, aby měli prostor svoje projekty aktualizovat záplatovanou verzí. Až následně se o zranitelnosti dověděla široká veřejnost. V tento moment již došlo k většímu „odtajnění“ a tím pádem i k impulzu pro white/grey/black hat hackery, kteří začali tvořit různé automatizované nástroje pro odhalení či zneužití této zranitelnosti.

Některé subjekty zasažené touto zranitelností by si samozřejmě představovali i „lepší“ postupy řešení čí informování, ale vzhledem k tomu, že jde o svobodný software, nelze nikomu nic zazlívat.

Na stránce od autorů Nette jsou k dispozici i opravné skripty od Michala Špačka (odborníka v oblasti webové bezpečnosti), které umí prohledat celý server a zranitelnost „ošetřit“. To je užitečné například pro hostingové společnosti, které hostují na serverech stovky či tisíce zasažených klientů a vědí, že není reálné, aby si všichni jejich klienti tuto zranitelnost ošetřili v dohledné době.

Jak jsme postupovali my

Krátce po publikování zranitelnosti si na tuto problematiku a reálnou možnost zneužití posvítil náš kolega Míra Hančík, který se o oblast bezpečnosti aktivně dlouhodobě zajímá. V 05:07 ráno odeslal týmu e-mail, ve kterém upozornil na skutečnou závažnost. Tu demonstroval přiložením konkrétních adres URL, skrz které bylo možné naše významné projekty kompromitovat a získat např. konfiguraci aplikace nebo jiné závažné informace.

Hned ráno odstartovala brigáda nejvyšší důležitosti, do které byli zapojení všichni BE vývojáři a správci serverů. Brigáda běžela ve čtyřech následujících proudech, které měly za cíl v řádu jednotek hodin ošetřit plošně zranitelnost na několika úrovních, zkontrolovat případné už proběhlé zneužití a informovat klienty.

1. Zabránění zneužití zranitelnosti na úrovni webserverů

V SiteOne všech našich zhruba 120 serverů spravujeme pomocí Ansible, takže nejrychlejší cesta jak zranitelnost ošetřit na nejvyšší úrovni byla jasná. Zjistili jsme různé formáty URL, jejichž přičiněním bylo možné zranitelnost zneužít, a skrze Ansible jsme do všech webserverů (Nginx a u starších projektů Apache) nasadili pravidla, která takové požadavky rovnou blokují a nenechají je ani doputovat do aplikace (PHP).

Zároveň jsme pomocí Ansible ze všech serverů a konfigurací webserverů vytáhli seznam přibližně 1 100 domén, na kterých nám běží různé projekty. Abychom se ujistili, že plošná pravidla zafungovala správně, naprogramovali jsme si skript, který provolal na všech doménách 4 zneužitelné varianty URL. Našli jsme pouze jeden zranitelný projekt, který se v minulosti odstěhoval na infrastrukturu klienta, takže ošetření tohoto projektu trvalo o trošku déle.

V závěru dne jsme ale měli jistotu, že jsme z nejhoršího venku.

2. Aktualizace verze Nette do všech projektů a nasazení na servery

Správci serverů připravili tabulku se všemi produkčními i náhledovými doménami našich projektů, které jsou postavené nad Nette frameworkem, rozčlenili je mezi jednotlivé vývojáře a zároveň určili priority, abychom nejvíce navštěvované projekty nebo projekty s hodně citlivými daty ošetřili jako první. Vývojáři následně procházeli projekt po projektu, aktualizovali verzi Nette, otestovali funkčnost a nasazovali ošetřenou verzi do produkčního, ale i do všech náhledových prostředí.

Tento proces byl poměrně zdlouhavý, protože za posledních 10 let jsme u takového počtu projektů používali několik způsobu deploymentů a ne u všech bylo možné migrovat na aktuální best-practices v této oblasti. Některé z nejstarších projektů se deployovaly ještě SVN updatem přes Sambu, některé git pullem, naštěstí většina již automatizovaným deploymentem přes Deployer nebo přes GitLab CI.

Velké díky zde patří všem BE vývojářům. U některých starých a již moc neudržovaných projektů totiž bylo skutečně nutné si „vyhrnout rukávy“. Ale povedlo se to.

3. Analýza historie a možného již uskutečněného zneužití

Žádný z našich honeypotů ani různých nástrojů či procesů pro odhalení kyberútoků nám žádné zneužití prozatím nenahlásil.

Access logy našich projektů mj. agregujeme do ELK Stacku, takže jsme zpětně a plošně analyzovali logy posledních měsíců a hledali požadavky na zranitelné URL. Našli jsme naštěstí pouze požadavky z IP adresy kolegu, který na zranitelnost upozornil jako první, a několik požadavků z jednoho českého serveru, kde už jistý známý z Nette komunity prováděl skenování všech českých domén. (Naštěstí šlo pouze o ověření, zda je daný web zranitelný, bez cíle provést něco nekalého. Navíc v případě tohoto skeneru byly volané URL adresy, které doputovaly na NodeJS frontend, nikoliv PHP backend.)

Ke dni 21. října 2020 je na grafech za posledních 14 dní vidět, že z IP adres z celého světa již přichází požadavky, které se snaží této zranitelnosti zneužít. To je situace typická po každém objevení zásadní zranitelnosti ve frameworcích.


4. Komunikace ke klientům

Na závěr jsme informovali všechny své klienty, aby věděli, že jsme jejich projekt před touto zranitelností ošetřili. Zároveň jsme je informovali o výsledku našeho pátrání – tuto zranitelnost nestihl nikdo zneužít k žádnému útoku.

Vybrané klienty navíc za pár týdnů informujeme se shrnutím pokusů o útoky na jejich projekty za předešlé období. Již teď je ale jasné, že jsme útok skrz tuto zranitelnost odvrátili v desítkách případů.

Ponaučení a co můžeme zlepšit

Riziko, které tato zranitelnost představovala pro nejen naše projekty, bylo obrovské. Abychom toto riziko do budoucna minimalizovali, rozhodli jsme se podniknout následující kroky:

Rozšířili jsme svůj aktivní monitoring o sledování CVE a zranitelností nad Nette frameworkem, abychom se o objevení nové zranitelnosti dozvěděli v řádu jednotek minut od jejiho zaregistrování. Aktuálně je to první objevená zranitelnost v Nette. Jenom pro zajímavost, konkurenční frameworky jich už mají na kontě desítky, díky jejich globálnějšímu použití – Symfony (54), Laravel (21), CodeIgniter (27), CakePHP (12).

Zavádíme security-checker do CI procesu i u projektů, kde aktuálně není.

Máme projekt, který komunikuje s našim GitLabem – interně mu říkáme „Matice projektů a závislostí“, neboli „Project Dependency Matrix“ (náhled na obrázku), kde je přehled všech hlavních aktivních projektů a detailní přehled jejich závislostí na našich i externích balíčcích, společně s jejich aktuálností a případným doporučením aktualizace. Tento nástroj rozšíříme tak, aby poskytoval i plugin pro náš Nagios, díky čemuž se bude každých pár minut provádět výše zmíněný security-checker nad kódem všech projektů. Když už se objeví zranitelnost, vývojáři dotčených projektů budou okamžitě informováni.


Budeme důslednější v plnění role hlavního vývojáře projektu, jejíž součástí je i pravidelná aktualizace všech závislostí projektu. To bude mít dopad i na definici SLA s jednotlivými klienty.

Budeme znovu revidovat a prověřovat další možnosti hardeningu PHP – například možnosti zakázat volání některých nativních funkcí PHP, které jednotlivé projekty nutně nepotřebují.

Revidujeme i proces v deploymentu, který by mohl být ještě striktnější v tom, jakým způsobem jsou nastavená oprávnění na filesystému vzhledem k možnostem zápisu či modifikace souborů. To by mělo pomoct zabránit zneužití podobným typem zranitelnosti, alespoň u vybraných forem útoků.

Připravíme další dashboardy, které budou ještě detailněji detekovat, vyhodnocovat a vizualizovat útočné požadavky. Již teď naši vývojáři u všech hlavních projektů dostávají každé ráno detailní screenshoty z desítek dashboardů, kde jsou všechny dostupné metriky k provozu jejich projektů – od zátěže z pohledu hardware, až po vnitřní metriky jednotlivých používaných technologií.

Popíšeme interní proces, jak postupovat v situaci, kdy dojde k plošné hrozbě u většiny projektů. Díky tomu by se měla snížit režie nutná na řízení takové situace a koordinaci všech lidí zapojených do řešení. To by mělo ještě více zkrátit čas potřebný k vyřešení situace.

Jako poslední bod, který je jedno z našich nejkontroverznějších témat – budeme dále s vývojáři revidovat a diskutovat nad tím, zda jsme pořád na správné a dlouhodobě strategické technologické cestě. Ať už jde o výběr aplikačních či serverových technologií, programovacích jazyků, frameworků, knihoven či postupů. To ale je (a vždy bude) nelehký úkol s mnoha různě vážnými pro a proti.

Odhalení slabých míst

Výskyt nových zranitelností je poměrně běžný jev a pravidelně musíme na servery plošně nasazovat různé aktualizace – obvykle týkající se zranitelností na úrovni webserverů či SSL/TLS.

S touto kritickou a navíc plošnou zranitelností se nám podařilo vypořádat relativně dobře a to bez následků pro naše klienty. Nicméně nám celá událost odkryla některé oblasti, kde můžeme zvýšit jak prevenci, tak aktivní ochranu před dalšími útoky a snažit se minimalizovat možné dopady.

Jsme za tuto událost vlastně „šťastní a vděční“, protože bezpečnost a ochrana našich projektů je pro nás v oblasti provozu téma číslo jedna – ačkoliv to zní jako klišé. My si taková selhání bereme osobně a jsou pro nás otázkou cti. Všechno, co může poškodit naše dobré jméno a naše řemeslo, to bude vždy důležité téma a každý „úder reality“ je příležitost zlepšit se v obraně nebo protiútoku.

bitcoin_skoleni

Jako ohromně důležité vidíme si řešení nenechávat pro sebe a podělit se s ostatními s možným návodem, postupem nebo i jen nápadem a myšlenkou, jak lépe pochopit a uchopit ty skutečné bezpečnostní hrozby a jak kvalitně zabezpečit (i vaše) prostředí nebo projekty.

(Původně vyšlo na webu SiteOne.)

Autor článku

Vedoucí vývoje a infrastruktury ve společnosti SiteOne.cz. Od roku 2004 vyvíjel, vede vývoj a zodpovídá za provoz stovek webových projektů s miliony denních pageviews.