Cross Site Request Forgery

Zdroj: SOOM.cz [ISSN 1804-7270]
Autor: .cCuMiNn.
Datum: 19.5.2008
Hodnocení/Hlasovalo: 1.22/37

Na Internetu se můžete chovat jakkoliv obezřetně, ale jakmile jednou navštívíte webovou stránku nebo kliknete na odkaz, nemůžete si již být jisti, zda jste se právě nestali obětí CSRF útoku. Při něm můžete například nevědomky přijít o svůj účet na webovém serveru, nebo vložit do některé z diskuzí příspěvek, který byste jinak vědomě nikdy nenapsali.

Z historie CSRF

První zmínka o zranitelnosti, kterou bychom dnes označili za zranitelnost CSRF, pochází již z roku 1988, kdy Norm Hardy publikoval dokument popisující podobné chování a nazval jej zmatený zástupce (confused deputy). V roce 2000 se pak v mailové konferenci Bugtrag objevil příspěvek, který popisoval, jak je pomocí této metody zranitelné ZOPE. O rok později byl pak ve stejné konferenci zveřejněn příspěvek Petera Watkinse, který v odpovědi na jiný thread nazvaný The Dangers of Allowing Users to Post Images poprvé použil termín CSRF.

V tomto článku si přiblížíme zranitelnost Cross Site Request Forgery, která se také jinak nazývá Cross Site Reference Forgery, CSRF nebo XSRF. Zranitelností tohoto druhu trpí v současnosti většina webových aplikací. Možná to je způsobeno tím, že povědomí o této zranitelnosti není dosud na takové úrovni, na jaké by mělo být, nebo proto, že obrana před tímto typem útoku není tak lehká, jak by se mohlo na první pohled zdát. Dříve, než se podíváme na jednotlivé typy útoků CSRF a možné způsoby obrany proti nim, povíme si něco o tom, jak takový standardní útok vypadá, na koho je namířen a jaké může mít jeho zdárné provedení následky.

Co se naučíte

Útoky pomocí CSRF

Útoky CSRF jsou obdobou známých útoků XSS. Ačkoliv nefungují na stejném principu, protože nevyužívají skriptovací jazyk, jsou stejně jako XSS útoky namířeny proti koncovým uživatelům (návštěvníkům webových aplikací). Každý CSRF útok je tvořen speciálním odkazem, na který se útočník snaží nalákat své oběti, aby tak pod jejich identitou provedl skrytou akci, kterou by za běžných okolností samotní návštěvníci nikdy neudělali. Použije-li útočník pokročilých metod útoku, může oběť donutit, aby následovala odkaz dokonce bez jejího vědomí a aktivní spoluúčasti, která jinak v kliknutí na odkaz spočívá.

Co byste měli znát

Jak servery kontrolují identitu uživatelů

Pokud chceme dobře porozumět útokům CSRF, musíme si nejprve povědět něco o tom, jak webové servery ověřují identitu svých návštěvníků. Vzhledem k tomu, že je http protokol bezstavový a při přechodu z jedné webové stránky na jinou by si sám o sobě nezapamatoval identitu návštěvníka, byly vyvinuty různé metody, které serveru identifikaci umožňují. Nejčastěji je při přihlášení k webovému serveru vytvořeno na serveru sezení (session), které přiřadí návštěníkovi jednoznačný identifikátor relace. Tím pak návštěvník při každém vstupu na novou stránku prokazuje svou identitu.

Předávání tohoto řetězce zabezpečují webové servery různými způsoby. Některé tento identifikační řetězec předávají jako parametr v url, jiné jej mají zakomponován již v samotné adrese webové stránky. Asi nejčastějším a nejznámějším způsobem je pak pro uložení tohoto řetězce použít cookies. Vždy, když návštěvník provádí na serveru nějakou akci, je podle tohoto řetězce ověřena jeho identita a podle práv, která má daný uživatel přiřazeny, je mu akce buďto povolena nebo odepřena.

Příkladem nám může být například návštěva webmailu. Legitimní návštěvník se zadáním svého uživatelského jména a hesla přihlásí k webmailovému serveru, na kterém má zaregistrován svůj e-mailový účet. Na straně serveru bude vytvořena relace a uživateli bude přiřazen a předán identifikační řetězec. Ten se na straně uživatele zapíše například do cookie a návštěvník se jím bude až do odhlášení od serveru identifikovat. Tímto způsobem má uživatel zaručeno bezproblémové procházení svým účtem. Může psát pod svou identitou zprávy, upravovat adresář, nebo provádět jakékoliv změny v nastavení účtu. Je samozřejmostí, že může pracovat pouze se svým e-mailovým účtem, protože server podle identifikátoru pozná, že k jinému účtu uživatel oprávnění nemá. Útočníci se často snaží na serverech nalézt XSS zranitelnosti, pomocí níž by se jim podařilo ukrást oběti obsah těchto cookie. Tím by získali právě zmiňovaný identifikátor session a mohli by tak přistoupit k účtu pod identitou oběti.

Pokud server nemá jiné kontrolní mechanismy, kterými by detekoval unesené sezení (například kontrola ip adresy), může si útočník provádět s účtem vše, co jej napadne. Ke krádeži cookie je často útočníky používán kód podobný některému z těch, které uvádím ve Výpisu 1. Tímto se však dostáváme k útokům XSS, kterým tento článek určen není, a proto se jimi zatím nebudeme více zabývat. Tam kde útoky typu XSS možné nejsou, přichází útočníci právě s útoky CSRF a proto je potřeba, aby o nich měli tvůrci webových aplikací jasnou představu.






Jaké mohou mít zdárné útoky následky

Již jsme se zmínili o tom, že útoky CSRF jsou tvořeny převážně speciálně upravenými odkazy nebo pomocí normálně vyhlížejících odkazů, které však směřují na stránky s přesměrováním nebo se speciálně připravenými skripty. Oběti tak nemusí z pohledu na odkaz získat vůbec žádné podezření a dokonce nemusí provedený útok ani nijak zaregistrovat. Vrátíme se zpět k našemu příkladu s webmailovou službou a představíme si, že útočník zašle oběti odkaz na stránku s adresářem. Sám útočník, kdyby chtěl, tak se do adresáře oběti nedostane. Není pro něj však problém zjistit si návštěvou vlastního účtu, jaký je celý obsah url při procházení adresáře. Řekněme, že je touto adresou http://www.webmail.cz/addressbook/view.php. Tento odkaz pak útočník pouze zašle své oběti a ta se, pokud na odkaz klikne, ocitne rázem ve svém adresáři. Jak jsme již uvedli, běžně útočník přístup do cizího adresáře nemá, ale může donutit k návštěvě prostřednictvím odkazu svou oběť, jejíž identitu využije.

Tento příklad možná není zvolen zrovna nejšťastněji, protože nepředstavuje pro uživatele žádné nebezpečí. Pomohl nám však představit si, jakým způsobem se může útočník s identitou oběti dostat na místa, kam by se za normálních okolností nedostal. Daleko horší následky může mít odkaz, jehož následování vede k vymazání adresáře nebo doručených zpráv, k nastavení přesměrování příchozí pošty, nebo dokonce ke změně přístupového hesla. Všechny tyto akce může pouze prostřednictvím odkazu, na který oběť klikne, útočník provést a to už je dle mého dostatečně velké nebezpečí, které stojí za to, si blíže přiblížit.

Cíle CSRF útoků

Metody útoků CSRF

Je jasné, že pouhé navedení oběti na určitou stránku by pro útočníka moc velký smysl nemělo a jen stěží by se něco takového dalo pokládat za útok. Nebezpečí přichází teprve v případě, kdy útočník začne pod identitou své oběti odesílat v url hodnoty parametrů, které se mu hodí nebo začne vyplňovat a odesílat formuláře umístěné na webových stránkách. Kdo někdy na své stránky umisťoval nějaký ten formulář, ví, že jsou data předávána na webový server ke zpracování buďto metodou GET nebo POST. O obou těchto metodách si nyní povíme trochu více a uvedeme si na příkladech konkrétní útoky CSRF.

Útoky přes požadavek GET

Pokud jsou data odesílána pomocí metody GET, je provedení CSRF útoku naprosto jednoduchou záležitostí. Hodnoty jednotlivých proměnných jsou totiž předávány jako parametry v url a není problém si sestavit odkaz včetně předávaných hodnot, které se útočníku hodí. Jako příklad útoku nám nyní poslouží jednoduchá anketa, kterých jsou na webu tisíce. Někdy má výsledek ankety celkem zásadní význam, například v různých soutěžích, kdy návštěvníci rozhodují o vítězi soutěže. V takovém případě dělají tvůrci ankety všechno proto, aby návštěvníkům zamezili v několikanásobném hlasovaní. Používají k tomu různě složité metody od ukládání informace o proběhlém hlasování do cookie, přes kontrolu ip adresy a jiných atributů, které návštěvníka jednoznačně identifikují, až po umožnění hlasování pouze registrovaným návštěvníkům.

V našem případě se zaměříme na fiktivní anketu, která obsahuje všechny výše zmíněné ochrany. V této anketě rozhodují registrovaní návštěvníci o vítězi soutěže, který získá hodnotnou cenu. Zkuste se nyní zamyslet, jakým způsobem by útočník mohl ovlivnit hlasování a přidat třeba 1000 hlasů jedné z možností. Ano, může se například tisíckrát zaregistrovat a zkoušet obejít kontrolu o již proběhlém hlasování. Všem však musí být jasné, že toto je extrémní řešení, kterému se každý raději vyhne. Pokud se hlasy z ankety přenáší od hlasujících do skriptu plus.php metodou GET, může útočník prostřednictvím CSRF útoku nechat nevědomky hlasovat ostatní registrované uživatele. Udělá to například tak, že do diskuze na webu s anketou vloží odkaz, který v sobě již bude obsahovat parametr s jedou z možností pro hlasování. Takový odkaz by mohl vypadat takto: http://www.soutez.c/plus.php&option=3.

Do diskuze může k odkazu uvést nějaký upoutávkový text, kterým se pokusí přesvědčit ke kliknutí na odkaz co nejvíce návštěvníků. Návštěvník, který se nechá zmást a na odkaz klikne, pak uvidí jen poděkování za účast v anketě a u zvolené možnosti přibude jeden hlas. O tom, jak by mohl útočník svou činnost zamaskovat, aby odkaz nebyl tak nápadný a aby se oběť nedozvěděla o tom, že byla právě podvedena si povíme níže. Z výše uvedeného je patrné, že přenášet hodnoty metodou GET je snadno zneužitelné a to nejen pro útoky tohoto typu. Ačkoliv, jak si za chvíli ukážeme, není sebemenší problém uskutečnit zdárný CSRF útok ani při použití metody POST, je dobré se metodě GET co nejvíce vyhýbat a pokud to není z nějakého důvodu vyloženě nutné, nepoužívat ji.

Útoky přes požadavek POST

Aplikace, které si předávají data pomocí metody POST, jsou na tom o poznání lépe. Bohužel je ale ani toto před útoky CSRF neuchrání. Vrátíme se zpět k našemu webmailu a pokusíme si popsat postup, který by mohl použít útočník, pokud by chtěl přesměrovat nově příchozí poštu zvolené oběti na svůj e-mail. Útočník si založí na stejném serveru, jaký používá jeho oběť, účet, aby prozkoumal jeho architekturu. Tím zjistí, na jakých adresách se nacházejí jednotlivé skripty, které mají s přesměrováním pošty nějakou souvislost. Navštíví stránku, která obsahuje formulář pro zadání adres k přesměrování nově příchozí pošty a zobrazí si její zdrojový kód. Pokud je zdrojový kód špatně čitelný a útočník se v něm nemůže rychle zorientovat, může použít některý z doplňků ke svému webovému browseru, který mu rychle podá všechny dostupné informace o jednotlivých formulářích. Pro FireFox je takovým vhodným doplňkem například Web developer, který podá o formulářích informace například v podobě, která je znázorněna na Obrázku 1.

Obrázek 1. Zobrazení informací o formuláři pomocí doplňku Web developer pro FireFox
Web developer

Další možností, jak zjistit data odesílaná serveru po odeslání formuláře, je použití síťového snifferu, jak ukazuje Obrázek 2.

Obrázek 2. Výpis zachycených dat programem Ethereal po odeslání formuláře
Ethereal

Má-li útočník štěstí a zdrojový kód stránky je napsán jednoduchým a přehledným způsobem, může v něm vyhledat kód formuláře. Ten může ve zjednodušené podobě vypadat podobně jako kód na Výpisu 2. Podívá se na názvy jednotlivých vstupních polí a poznačí si adresu cílového skriptu, kterému jsou data po vyplnění odesílána. V našem případě obsahuje formulář pouze dvě pole. První pro zadání e-mailové adresy pro přesměrování a druhé pro volbu, zda ponechat na serveru doručenou zprávu, nebo zda ji po přeposlání odstranit. Data jsou po stisku tlačítka uložit předávána metodou POST skriptu http://www.webmail.cz/forward.php.

Útočník nyní nemůže předat data tím, že je vloží do url, protože je vyžadována metoda POST a tak na to půjde trochu oklikou. Vytvoří si na svých webových stránkách kopii uvedeného formuláře, kterou umístí na adresu http://www.utocnik.cz/atackform.html. Hodnoty jednotlivých polí již předem naplní požadovanými hodnotami a formulář nasměruje na původní skript starající se o přidání adresy k přesměrování na serveru www.webmail.cz. Kód formuláře poté vypadá tak, jak uvádí Výpis 3. Nyní už jen stačí, aby útočník zaslal své oběti e-mailovou zprávu, ve které uvede odkaz na svůj podvržený formulář.


  

Oběti, která je přihlášená ve svém webmailovém účtu a klikne na odkaz, se zobrazí stránka s formulářem a po kliknutí na tlačítko uložit pak hlášení: Vaše pošta byla přesměrována na adresu atacker@domena.cz. Útok se sice zdařil, ale sami vidíte, že by potřeboval ještě pořádně dopilovat. Za prvé by pro útočníka bylo jistě fajn, pokud by oběť, nemusela kliknout na formulářové tlačítko s popisem odeslat, ale aby se obsah formuláře odeslal automaticky po vstupu oběti na stránku. Za druhé, aby oběť vůbec neviděla obsah formuláře, ale byl jí namísto toho zobrazen například nějaký vtipný obrázek. V neposlední řadě by se útočníkovi jistě také hodilo, pokud by se oběti nezobrazila zpráva o provedeném přesměrování. Je tedy načase říci si něco o metodách, pomocí niž mohou útočníci své CSRF útoky maskovat.

Maskování CSRF útoků

Začneme postupně a jako první si řekneme něco o tom, jak může útočník maskovat podezřelý odkaz, pokud předává data metodou GET (hodnoty parametrů jsou čitelné z url). Pro útočníka není nic jednoduššího, než použít přesměrování a místo přímého odkazu, který vede k provedení akce, vloží odkaz na svou stránku s nenápadným url.

Na své stránce pak nastaví automatické přesměrování a oběť tak oklikou navede k cíli útoku. Nyní se však vrátíme k našemu webmailu a nastíníme si metody, které by mohl použít útočník z uvedeného příkladu, aby svůj útok co nejvíce utajil. Nejprve se podíváme, jak může útočník odeslat data z formuláře automaticky, okamžitě po té, co oběť klikne na odkaz a navštíví útočníkem připravenou stránku. Využit může být například javascript, pomocí něhož se provede submit() formuláře. Následně útočník zamění typ vstupních polí na hidden a odstraní potvrzující tlačítko. Kód po provedené úpravě je k dispozici na Výpisu 4.


  

Poslední vadu na kráse, totiž skrytí odpovědi o proběhlém přesměrování, může útočník odstranit otevřením stránky s formulářem ve skrytém rámu. To od útočníka bude vyžadovat přípravu dvou webových stránek. Jednu, jejíž obsah bude zobrazen oběti. Na té bude kromě jiného obsahu umístěn i iframe o rozměrech 1x1 pixel. Do tohoto iframu bude nahrána druhá stránka, která se postará o neviditelné provedení přesměrování příchozí pošty. Zdrojový kód obou stránek můžete vidět na Výpise 5 a Výpise 6.


  


Omlouváme se, ale požadovaná stránka nebyla na serveru nalezena.

Celý útok v konečné fázi vypadá tak, že útočník zašle své oběti e-mailovou zprávu s textem, který se pokusí zapůsobit na oběť takovým způsobem, aby klikla na zaslaný odkaz. Jakmile oběť na odkaz klikne, navštíví útočníkem připravenou stránku, která bude obsahovat informace slibované v textu e-mailové zprávy, nebo také třeba fiktivní chybové hlášení, podobné tomu z Výpisu 6. Na pozadí tohoto děje je ve stránce otevřen i prvek iframe o miniaturních rozměrech. Do něho je načten a následně i automaticky odeslán formulář, který zařídí přesměrování nově příchozí pošty. Zpráva o proběhlém přesměrování bude ze strany serveru vrácena zpět do tohoto iframu a proto proběhne celý útok zcela automaticky a nepozorovaně. Nyní je snad síla CSRF útoků jasná každému a to jsme ještě neprobrali všechny možnosti, které má útočník k dispozici.

Odkazy na externí zdroje

Když jsem se zmiňoval o útocích založených na požadavcích zasílaných metodou GET, záměrně jsem neuvedl další ze způsobů, pomocí něhož může útočník zaútočit. Tato metoda je natolik závažná, že jsem se jí rozhodl věnovat vlastní odstavec. Celý trik, při použití odkazů na externí zdroje, vychází z vložení tagu, který načítá svůj obsah z jiného umístění. V adrese požadavku na externí zdroj stačí pouze uvést cestu k webové stránce, kterou hodlá útočník napadnout, včetně požadovaných hodnot parametrů. Zaměříme-li se opět na příklad s anketou, kde se hlasy jednotlivým volbám přičítali zasláním požadavku na adresu http://www.soutez.cz/plus.php?option=3 (v parametru se uvádí jedna možností, pro kterou hlasujeme), pak vložením tagu img se zdrojem, který odpovídá adrese hlasovacího skriptu http://www.soutez.cz/plus.php?option=3, může útočník donutit server, aby se pokusil stáhnout neexistující obrázek z daného umístění. Stačí, umístí-li na stránku odkaz na obrázek v této podobě:

<img src=' http://www.soutez.cz/plus.php?option=3' width='0' height='0'/>

Všem je jasné, že k načtení obrázku nikdy nedojde, ale automaticky po zobrazení webové stránky dojde k odeslání požadavku a tím k započtení hlasu v anketě. V místě, kde by měl být zobrazen obrázek zůstane prázdné místo, což by mohlo upoutat nechtěnou pozornost a tak útočníci u obrázků nastavují jeho nulové rozměry nebo jej skrývají pomocí css. Tagů, které může útočník použít existuje hned několik a proto si je uvedeme v Výpisu 7. Pokud by měl útočník možnost vložit na stránky tag <script> nebo <iframe>, pak může provést útok i pokud je pro předání parametrů použito metody POST.