Hackerem sám sobě (3) - CSRF

Cross-Site Request Forgery navazuje na XSS. Zatímco u techniky XSS se snaží uživatel obelstít stránky, tak u CSRF je to naopak – stránky se snaží nachytat uživatele. Využívá se toho, že návštěvník stránek je přihlášen na jiném serveru – třeba někde do administrace – tudíž má v prohlížeči uložené cookies a může směle bez dalšího vyplňování hesla pracovat s celou administrací. Útočníkovy stránky pak usnadňují tomuto uživateli práci a například za něho mažou položky v administraci na serveru, kde je přihlášen.

Když jsem zkoušel pomocí této techniky napadnout stránky restaurace, které jsem celé napsal já, tak jsem za pár vteřin smazal hrachovou kaši z denního menu. Inu člověk se pořád učí…

Na začátku je nutné mít adresu přímo na nějakou akci v administraci – například:

www.domena.cz/administrace/delete.php?id=2

Tuto adresu můžete zkusit uhádnout nebo sednout před cizí počítač a otevřít si historii v prohlížeči. Pokud se vám nechce ani jedno, tak můžete zkusit strýčka Google a vyhledat třeba tento výraz:

allinurl:admin delete.php id=2

Pak stačí na svou stránku umístit například falešný obrázek s adresou, kterou se nám podařilo zjistit:

<img src="http://www.domena.cz/administrace/delete.php?id=2" />

Teď už jen sehnat člověka, který tuto administraci používá a nalákat ho na svou stránku a je vymalováno ! Pokud se vám zdá, že někoho navádím na hackování cizích stránek, tak špatně čtete – chce to lepší brýle, takhle se ty písmenka strašně mažou a člověk vidí i to, co tam není. Takže si to zkuste na svých stránkách a uvidíte, jestli jste obstáli či ne. Pokud ne, můžete pokračovat ve čtení…

Obrana proti šikulům

Možná vás napadlo, že místo $_GET stačí použít $_POST, ale to útok jen trochu stíží – útočník pouze musí uhádnout, jak jste pojmenovali kolonky ve formuláři. Pak už jen umístí na stránku stejný formulář, který se odešle JavaScriptem při načtení stránky.

Referer

Řešením je testovat, zda je v hlavičce Referer adresa mé stránky s administrací:

if ( !substr( $_SERVER[ "HTTP_REFERER" ], 0, 34 ) == "http://www.domena.cz/administrace/" ) {
  echo "Mě neoblafneš kámo !";
  exit;
}

Hlavičku Referer posílá prohlížeč (obsahuje adresu stránky, ze které jsem se dostal na aktuální) a není ji možné obelstít na útočníkově stránce. Bohužel posílání této hlavičky se dá vypnout v prohlížeči, tudíž se nelze na ni spolehnout. Další nevýhoda spočívá v nemožnosti vstoupit do administrace přímo přes externí odkaz – například jsem pořád přihlášen a v záložkách mám odkazy na pravidelné snížení prémií. Jsou to nevýhody relativně malé a toto řešení je i tak použitelné.

Autorizační token

Lepší metodou, ale náročnější na implementaci jsou tzv. autorizační tokeny. Před odkázáním na další stránku dáte do URL nebo formuláře autorizační proměnnou – např. md5 hash z cookie (doporučuji solit) nebo náhodně vygenerovaný řetězec, který uložíte do databáze a v dalším skriptu porovnáte poslaný token s tokenem v databázi.

Praktické použití by mohlo vypadat nějak takto:

<?php
session_start();
?>
<form action="delete.php" method="post">
  <input type="hidden" name="id" value="2" />
  <input type="hidden" name="token" value="<?php
    echo sha1( session_id( ) + $_SESSION[ "password" ] ) ?>" />

  <input type="submit" name="btn" value="Smazat" />
</form>

Protože má session omezenou platnost (vyprší za několik minut), myslím, že toto opatření je dostačující.

Budu rád, když napíšete komentář, jestli o této technice slyšíte poprvé nebo jste už zkušený geek a tento článek vám nic nedal.

Vloženo: 21. 10. 2007 16.44RSS komentářů tohoto článku

Komentáře:

[1] Max8 (max888@seznam.cz) 21. 10. 2007 17.02

Tak článek je moc pěkně napsaný, o této technice jsem neslyšel, takže mě to něco dalo. Dík

Michal


[2] Radek Tomášek 21. 10. 2007 19.47

O této technice slyším poprvé, vyzkouším, jestli obstojím… Díky za pěkný článek…


[3] Aleš Janda (kyblicek@kyblsoft.cz) 21. 10. 2007 20.23

Pěkný článek :-) O této technice jsem věděl, akorát jsem neznal ten šílený název – CSRF.

Jo a s tou hrachovou kaší je to fakt dobrý ;-)


[4] $#@ 1. 1. 2008 06.59

tady si nekdo plete hacking (tj. v dnesni dobe kradeni kreditnich karet, kradeni emailu, kradeni accountu, kradeni ci poskozovani cehokoli) se script-kiddies (to jsou ty deticky jako ty, co si hraji s JS a PHP, pricemz ani netusi, jak funguje kuprikladu ioctl(), lamo)


[4] $#@: Já se taky nesnažím o žádný hacking, já se zabývám vývojem internetových stránek a v tomto seriálu se snažím ukázat techniky, jakými lze nabourat weby a jak se jim bránit. Žádné programování se sockety tady nepředstavuju… ;-)


[6] Kvaky (michalkv@seznam.cz) 28. 2. 2008 21.52

Ahoj, seriál (jestli se tomu dá tak říkat) Hackerem sám sobě je úplně super. Díky němu jsem si spravil jednu XSS díru. Jinak o technice CSRF slyším poprvé ale nějak mi to nedochází (poslední dobou po 8. hodině mi to nějak nemyslí :-)). Jinak ale super miniseriál…


[7] Lukyer (lukyer@gmail.com) 21. 2. 2009 08.02

Tuto techniku jsem sam objevil pri „otukavani“ jednoho z mych prvnich webu co jsem chtel prolomit … pote asi tak rok nato se o tom zacalo vsude mluvit a vsude slychavam CSRF ;) Je to sice pekne napsane, ale docela nevychytane. Priklad na situaci – mam forum kde si rozkliknu topicy koleckem mysi do 10ti tabu … a fungovat bude odeslani formulare jen pri poslednim tabu. Tady se musi pouzit jineho reseni (nejjednodusi je pole hodnot, ale o x polozek je to xkrat mene bezpecne), nebo svazat primo ke kazdemu id formulare jeho csrf token coz uz je lepsi. Jinak moje reseni je ukladat primo do session vicerozmerne pole s nazvem csrf a pak vygenerovavat k formularum tyto tokeny a zase je odebirat pri pouziti …


Přidat komentář