Cross-site Request Forgery (CSRF) je zranitelnost webových aplikací, která za určitých podmínek umožňuje autentizované uživatele donutit k tomu, aby provedli nezamýšlenou akci. Podstata zranitelnosti tkví v tom, že aplikace nedokáže rozlišit požadavky, které uživatel „zavolal“ neúmyslně. Než odhalíme podstatu CSRF, seznámíme se nejdříve s mechanizmem cookies, který webové aplikace využívají k identifikaci relace uživatele.

Identifikátor relace uživatele

Představme si eshop, kde se můžeme zaregistrovat, přihlásit a nakoupit. Když poprvé navštívíme stránky eshopu, dostaneme tzv. „session“ – identifikátor relace. Najdeme jej v hlavičce HTTP odpovědi v části Set-Cookie, zde se nachází cookie proměnné, které nám webová aplikace doporučuje uložit, aby s nimi mohla příště pracovat. Právě jedna z cookie proměnných bude sloužit k identifikaci relace a zpravidla nese jméno PHPSESSID, JSESSIONID nebo SessionId.

Následující výpis ukazuje hlavičku HTTP odpovědi serveru, kde vidíme v sekci Set-Cookie definici cookie proměnné JSESSIONID s unikátní hodnotou.

Nyní se podíváme, jak webový prohlížeč s touto informací pracuje.

Webový prohlížeč a cookies

Přijde-li od webového serveru odpověď s HTTP hlavičkou „Set-Cookie“, webový prohlížeč si uloží všechny cookies a poznačí si jejich doménu.

Prohlížeč dále sleduje nové HTTP požadavky a přibaluje k nim hlavičku „Cookie“ se všemi uloženými cookies, které jsou pro doménu platné.

Pomocí tohoto mechanizmu aplikace rozpozná identifikátor relace uživatele a zpřístupní mu data, které během relace vytvořil.

Cross-site Request Forgery (CSRF)

Nyní si ukážeme příklad realizace zranitelnosti CSRF. Vraťme se k našemu příkladu s eshopem a představme si, že máme v eshopu funkci, která přidá uživateli do nákupního košíku zboží. Aby se taková funkce zavolala, stačí navštívit speciální adresu http://eshop.example.com/basket/add/product.php?id=1.

Problém nastává, pokud uživatel takovou adresu zadá přímo do adresního řádku prohlížeče, klikne na podvržený odkaz, nebo navštíví stránku, která takové volání zprostředkuje. V tom okamžiku webový prohlížeč uživatele:

  • Vytvoří nový HTTP požadavek, který ukazuje na adresu
    http://eshop.example.com/basket/add/product.php?id=1
  • Přibalí existující cookie včetně identifikátoru relace k HTTP hlavičce.
  • Odešle požadavek na server.

Funkce, která v eshopu na požadavek HTTP GET reaguje, nejdříve zkontroluje, zda je uživatel přihlášen, následně dohledá číslo produktu podle parametru (id=1) a pokud je vše v pořádku, přidá tento produkt uživateli do nákupního košíku. Běžnému uživateli nedochází, že by klikáním na odkazy z emailu nebo na webu mohl v eshopu něco způsobit.

Bezpečnostní dopad

Bezpečnostní dopad zranitelnosti CSRF závisí na konkrétní aplikační funkci, která je na tuto chybu zranitelná. V našem případě se naší oběti pouze přidávají nové produkty do nákupního košíku, což zní docela zábavně. Pokud bychom ale byli schopni podobným způsobem resetovat uživateli heslo, tak to už je jiná káva. Je potřeba zmínit, že útočník se k samotné cookie nedostane, pouze oběť navede, aby dotaz uskutečnila.

Zranitelnost CSRF je často přehlížena. Není vždy snadné si útok představit a pokud ano, tak se setkáme s argumentací, že je to chyba uživatele, který kliká na podvržené odkazy. Pojďme si projít varianty z pohledu útočníka, abychom lépe pochopili, jak donutit oběť k vygenerování nového požadavku a realizovat CSRF.

Útočník – příprava útoku

Útočník ví, že aplikace je zranitelná na CSRF a zná konkrétní URL adresu, kterou potřebuje uživateli podstrčit. Poslední podmínka útoku je, že je uživatel v aplikaci přihlášen.

Útočník má tři možnosti, jak realizovat CSRF:

  1. Útok na aplikaci – útočník objeví  v aplikaci zranitelnost XSS, která mu umožní provolat požadavek za uživatele, až zranitelnou stránku v aplikaci navštíví. Z hlediska objemu poškozených uživatelů, je to nejhorší varianta.
  2. Útok na uživatele – cílená emailová zpráva s maskovaným odkazem na výhodnou nabídku. Útočník potřebuje kontaktovat oběť emailem nebo jiným způsobem, který končí otevřením stránky v prohlížeči.
  3. Útok na uživatele – „naslepo“ – útočník připraví zajímavý obsah a čeká, až se někdo chytne. Navštíví-li oběť stránku útočníka, prohlížeč bez vědomí uživatele vygeneruje nový požadavek.

Ochrana – POST

Na příkladě eshopu jsme popisovali funkci, která se volala HTTP metodou GET. Pokud bychom tuto funkci přepsali na HTTP metodu POST, nepatrně tím ztížíme podmínky útoku. Útočník navede oběť odkazem v emailu na vlastní stránky, kde odešle POST požadavek pomocí JavaScriptu nebo donutí uživatele odeslat HTML formulář.

Přechod na POST je vhodný pro všechny případy, kdy v aplikaci měníme data, nebo provádíme destruktivní operace. Metody GET bychom v tomto kontextu měli opustit, protože je celkem snadné tyto požadavky generovat, např. pomocí HTML.

Ochrana – Token

Intuitivně nám v aplikaci stále chybí bezpečnostní mechanizmus, který by poznal legitimní požadavek. Jak to ale udělat? Identifikátor relace je vždy stejný a všechny HTTP požadavky zasílá skutečný přihlášený uživatel, přesněji jeho prohlížeč.

Nabízí se dvě řešení. První z nich je zastavit akci uživatele pomocí ověřovacího kódu (CAPTCHA, SMS) nebo zadáním hesla. Přepisování kódu je však pro uživatele utrpením, zvláště je-li v aplikaci takových obrazovek více.

Druhé řešení používá také ověřovací kódy, ale bez vstupu uživatele. Můžeme jim říkat „Anti CSRF tokeny“. Tyto tokeny se nejprve v aplikaci vygenerují a svážou s relací uživatele, následně se předají klientovi (prohlížeči), aby si jej pamatoval a přeposílal zpět. Přeposílání tokenu zpět aplikaci nesmí využívat mechanizmus cookie, jinak bychom si nepomohli.

Pro zvýšení bezpečnosti můžeme platnost tokenu omezit nebo jej generovat znovu s každým přechodem na stránku.

Implementace

Implementace varianty „Anti CSRF tokenu“ bude záviset na použité technologii, frameworku a front-endu. Z pohledu návrhu budeme potřebovat v back-endu centrální místo, kde se budou tokeny kontrolovat, případně zamítat neoprávněné požadavky.

Většina moderních frameworků podporuje ochranu proti CSRF, stačí prozkoumat jejich dokumentaci. Projděte si také stránku OWASP projektu CSRF – Prevention Cheat Sheet, která shrnuje dostupné praktiky a upozorňuje, čemu se zcela vyhnout.

Závěr

V příspěvku jsme se seznámili se zranitelností CSRF a jaké podmínky potřebuje pro realizaci útoku. Nastínili jsme možnosti ochrany zavedením ověřovacích kódů.

To je pro dnešek vše. Zvažujete-li cestu etického hackera od začátku, rád uvidím na hacking kurzech.