CSRF ( anglicky cross-site request forgery – „cross-site request forgery“, známé také jako XSRF) je typ útoku na návštěvníky webu , který využívá nedostatky protokolu HTTP . Pokud oběť navštíví web vytvořený útočníkem, je jménem oběti tajně odeslán požadavek na jiný server (například na server platebního systému), který provádí nějaký druh škodlivé operace (například převod peněz útočníkovi účet). K provedení tohoto útoku musí být oběť autentizována na serveru, na který je požadavek odeslán, a tento požadavek nesmí vyžadovat žádné potvrzení od uživatele , což nemůže být ignorováno nebo zfalšováno útočícím skriptem .
Tento typ útoku, na rozdíl od populární mylné představy, se objevil již poměrně dávno: první teoretické úvahy se objevily v roce 1988 [1] , první zranitelnosti byly objeveny v roce 2000 . A samotný termín zavedl Peter Watkins v roce 2001 .
Hlavním využitím CSRF je vynutit provedení jakékoli akce na zranitelném webu jménem oběti ( změna hesla , tajná otázka pro obnovení hesla, pošta, přidání správce atd.). Je také možné využít odražené XSS detekované na jiném serveru pomocí CSRF .
Útok se provádí umístěním odkazu nebo skriptu na webovou stránku , která se pokouší vstoupit na stránku, na které je napadený uživatel známý (nebo pravděpodobně) již ověřen. Uživatelka Alice může například procházet fórum, kde jiný uživatel, Bob , zveřejnil zprávu. Nechte Boba vytvořit tag <img> , ve kterém jako zdroj obrázku zadal URL , po kliknutí na něj se na webu Alice's banky provede akce, například:
Bob: Ahoj Alice! Podívejte se, jak je tato kočka roztomilá: <img src="http://banka.example.com/?account=Alice&amount=1000000&for=Bob">Pokud Aliceina banka uloží Aliciny autentizační informace do cookie a pokud cookie ještě nevypršela, při pokusu o stažení obrázku Aliciin prohlížeč odešle cookie v požadavku na převod peněz na Bobův účet, který potvrdí Alicinu autentizaci. Transakce tak bude úspěšně dokončena, ačkoli k jejímu potvrzení dojde bez vědomí Alice.
Všechny požadavky, které mění data na serveru, stejně jako požadavky, které vrací osobní nebo jiná citlivá data, musí být chráněny.
Nejjednodušší způsob, jak se chránit před tímto typem útoku, je vyžadovat, aby webové stránky vyžadovaly potvrzení většiny uživatelských akcí a zkontrolovat pole HTTP_REFERER , pokud je v požadavku uvedeno. Tato metoda však může být nebezpečná a nedoporučuje se [2] .
Další běžnou metodou ochrany je mechanismus, ve kterém je s každou uživatelskou relací spojen další tajný jedinečný klíč, určený ke splnění požadavků. Tajný klíč by neměl být předán v čisté podobě, například u požadavků POST by měl být klíč předán v těle požadavku, nikoli v adrese stránky. Prohlížeč uživatele odešle tento klíč jako součást parametrů každého požadavku a server před provedením jakékoli akce tento klíč zkontroluje. Výhodou tohoto mechanismu oproti kontrole Referer je zaručená ochrana proti CSRF útokům. Nevýhodou je požadavek na možnost organizace uživatelských relací, požadavek na dynamické generování HTML kódu pro stránky webu a také nutnost ochrany před XSS a dalšími útoky, které umožňují útočníkovi získat unikátní klíč.
Specifikace protokolu HTTP/1.1 [3] definuje metody zabezpečeného požadavku jako GET, HEAD, které by neměly měnit data na serveru. U takových požadavků, pokud server vyhovuje specifikaci, není potřeba používat ochranu CSRF.
Možná budete chtít hrát na jistotu a ke každému požadavku přidat klíč, ale mějte na paměti, že specifikace HTTP/1.1 [3] umožňuje přítomnost těla pro jakýkoli požadavek, ale pro některé metody požadavku (GET, HEAD, DELETE) sémantika těla požadavku není definována a měla by být ignorována. Klíč tedy může být předán pouze v samotné URL nebo v hlavičce HTTP požadavku. Musíte chránit uživatele před neúmyslnou distribucí klíče jako součásti adresy URL, například na fóru, kde by mohl být klíč zpřístupněn útočníkovi. Požadavky s klíčem v URL by proto neměly být používány jako adresa, na kterou se mají přejít, to znamená, že se vyhněte přechodu na takovou adresu klientským skriptem, přesměrováním serveru, akcí formuláře, hypertextovým odkazem na stránce atd. za účelem skrytí klíč obsažený v adrese URL. Mohou být použity pouze jako interní požadavky skriptem používajícím XMLHttpRequest nebo wrapper, jako je AJAX .
Podstatné je, že klíč (CSRF token) nesmí být určen pro konkrétní požadavek nebo formulář, ale obecně pro všechny požadavky uživatelů. Stačí tedy uniknout CSRF token z URL, které provede jednoduchou akci nebo žádnou akci, takže jakákoli akce, nejen ta, ke které je nyní známá URL přidružena, ztratí ochranu proti podvržení požadavku.
Existuje tužší verze předchozího mechanismu, ve které je s každou akcí spojen jedinečný jednorázový klíč. Tato metoda je náročnější na implementaci a je náročná na zdroje. Metodu využívají některé weby a portály, např. Livejournal , Rambler atd. Pro rok 2016 nebyly žádné informace o výhodě rigidnější varianty oproti variantě, která používá pro každou relaci jeden tajný klíč [4] .