Dnes jsem se rozhodl proklepnout tento populární programátorský portál ohledně chyby Cross-site request forgery. Chcete vědět, jak jsem dopadl?
Nejdříve jsem se přihlásil ke svému účtu, který mám na Programujte.com již delší dobu. V pravém sloupci se mi otevřela nabídka nadepsaná mým jménem. Většina záložek se týká registrací do kurzů a věcí ohledně úkolů (btw. Tyto úkoly jsou pro nováčky výborná věc). Pro případného útočníka by největší cenu měla samozřejmě záložka Nastavení. Zde můžete měnit své osobní údaje, včetně hesla. Pro změnu hesla je však potřebná znalost původního. To znamená, že i v případě, že by CSRF na Programujte.com fungovalo, útočník by heslo změnit nemohl, protože by neznal heslo původní. Ověření původního hesla při jeho změně je z hlediska bezpečnosti nutnost. Pokud je tato otázka neřešena, je zde nebezpečí, že by to mohlo dopadnout jako před rokem na slovenském portálu Blackole.sk (paradoxně zabývajícím se IT security), kdy stačil jeden klik a mohli jste zcela přijít o svůj účet.
Na změnu hesla tedy musí útočníka přejít chuť. Ze zlomyslnosti by se však mohl snažit změnit jiný údaj, nevyžadující znalost hesla, jako například jméno, email, věk, adresu,… Kritická chyba by to sice nebyla, ale uživatelům by se jistě nelíbilo, kdyby se jim některý z těchto údajů měnil bez jejich přičinění. Zkouším si tedy změnit jeden z těchto údajů a přitom zachytit odesílané informace pomocí Firefox pluginu LiveHTTPHeaders. Odesílání dat na server se realizuje pomocí POST požadavku. To znamená, že útočník údaje sice nevyčte z URL, ale má jiné možnosti, jak je zjistit. Viz například již výše zmíněný FF plugin. Prohlížím si tedy parametry a jejich hodnoty, které se odesílají na server. Mé pozornosti neunikne hned druhý parametr s názvem ridc, jehož hodnota je totožná s hodnotou variabilního symbolu, který vám je konstantně přidělen.
Navíc hned další parametr je HASH vašeho hesla. To znamená, že ke vzdálené změně těchto údajů byste potřebovali vědět jak id, tak heslo (přesneji jeho HASH) oběti, což je velmi nepravděpodobné.
Zde má tedy Programujte.com další bod. Přidělování unikátního id každému uživateli je podle mě dokonalou ochranou proti Cross-site request forgery. Útočník si nemůže zjistit konstantní URL, kterou by podstrkoval všem návštěvníkům webu, kam by umístil svůj zákeřný kód. Tímto id nejsou chráněny pouze akce vedoucí ke změně osobních údajů uživatele, ale také akce vedoucí k registraci do kurzů. Chráněno je tedy vše, co by útočník mohl vzdáleně změnit a URL pro změnu osobních údajů je navíc chráněna HASHem uživatelova hesla.
Jeden druh útoku by však stále byl možný. Představme si situaci, že útočník chce poškodit přímo konkrétního uživatele, registrovaného na Programujte.com. Nějakým způsobem získá jeho id. Se znalostí cizího id se mu otevřou dveře k záložkám ohledně kurzů a úkolů. URL pro výkon těchto akcí totiž nejsou chráněny tak jako URL pro změnu osobních údajů pomocí HASHe hesla. Vše co útočník potřebuje, je znalost id oběti. To nějakým způsobem získá. Nyní si na Programujte.cz založí svůj účet, ze kterého bude provádět útoky. Poté rekonstruuje URL vedoucí k určité HASHem nechráněné změně (například přihlášení se do kurzu), své id nahradí id oběti a odešle. Co se stane? Oběti se skutečně nastavení změní. Znovu připomínám, že tímto způsobem lze měnit jen nabídky ohledně kurzů a úkolů, protože ostatní jsou chráněné pomocí parametru URL, ve kterém se předává HASH hesla oběti. Tato chyba sice není kritická, nelze měnit heslo ani osobní údaje, ale i tak není pro uživatele příjemná. Jediná překážka pro útočníka je tedy pouze zjistit id oběti. Jako příklad uvedu URL, pomocí které lze uživatel pod daným id přihlásit do kurzu C++, aniž by o tom měl ponětí:
CLICK
S vědomím, že tento portál o programování není plně zabezpečen, jsem se odhlásil (btw, odhlašování doprovázela chyba headers already sent, což by si také zasloužilo ošetřit) a již jsem chtěl zavřít okno Firefoxu. Všiml jsem si však ankety v levém sloupci. Všiml jsem si jí sice již dříve, ale nevěnoval jsem jí pozornost. Po zkušenostech s Blueboard anketami jsem si řekl, že vyzkouším, jak jsou na tom ankety na Programujte.com. Hlasování se posílá přes GET požadavek, čili URL odpovědi je stejně lehce čitelná jako u Blueboardu. Zkouším tedy hlasovat. Můj hlas započten. Zkouším znovu. Další hlas započten. Zkouším hlasovat zadáním konkrétní URL odpovědi, hlas započten. Překvapení. Anketa je ještě více odfláknutá než u Blueboardu. Žádná kontrola přes IP či cookie čili nulová ochrana proti vícenásobnému hlasování. Ani snad nemusím dodávat, že CSRF je na tuto anketu také použitelné. Pokud by toho však někdo hodlal zneužít, CSRF je pro tento případ zbytečně komplikované. V tomto případě by si stačilo napsat skript, který by neustále odesílal požadavek na danou URL, čímž by automaticky hlasoval. Anketa si tedy zaslouží opravu.
Neošetřená anketa však na Programujte.com není taková chyba jako neošetřená anketa u Blueboard. U portálu Programujte.com je totiž anketa pouze jednou z vychytávek (přesto by tu alespoň ta kontrola přes IP být měla), kdežto u společnosti Blueboard jsou ankety jednou z jejich služeb, proto je v zájmu dobrého jména společnosti, aby byly zabezpečeny co nejlépe.
Jaký je tedy závěr? Anketa zcela propadla, avšak ta nebyla hlavním předmětem testování. Uživatelské rozhraní znemožňuje útočnikovi vzdáleně měnit osobní údaje a heslo diky parametru s HASHem hesla. Náchylné k útoku jsou však volby k příhlášení uživatele do kurzu. Přitom k ošetření této chyby by pomohla stejná metoda jako u osobního nastavení. Curo, admin portálu, byl na tento článek upozorněn a věřím, že všechny výše jmenované chyby a nedostatky budou brzy opraveny.