Co je XSRF
CSRF
(Cross-Site Request Forgery) v Sunlight CMS označováno jako XSRF
je typ útoku, kdy útočník zneužije přihlášeného uživatele, aby poslal nějaký zpravidla škodlivý požadavek na server bez jeho vědomí.
Např. přihlášený uživatel klikne na podvržený odkaz a tím neúmyslně odešle požadavek typu: „smaž vlastní účet“, „změň heslo na jiné heslo“ apod. Dnešní prohlížeče se snaží pomáhat s ochranou i samy, například pomocí atributu SameSite u cookies mohou zabránit odesílání cookies při cross-site požadavcích, ale pro plnou ochranu je i nadále nutné používat XSRF tokeny.
Jak se XSRF bránit?
Jedním z nejčastěji používaných způsobů jak požadavky ochránit je pomocí tokenů. Jedná se o náhodně vygenerovaný řetězec znaků vázaný na přihlášeného uživatele nebo relaci. Tyto tokeny se používají pro ověření požadavku z odeslaného formuláře a slouží i k ochraně odkazů, které na serveru provádějí nějaké akce. V případech ochrany odkazů se často používá časově omezený, náhodný token v URL odkazu. Tento token je citlivý údaj – může se uložit do historie prohlížeče, logů serveru, atp. Proto je tedy potřeba, aby měl krátkou platnost a nebyl zneužitelný opakovaně.
Které formuláře a odkazy potřebují XSRF token?
Stručně se dá říci, že všechny formuláře a ty odkazy, které provádějí nějaké změny stavu na serveru (např. mazání, potvrzení, odhlášení), protože by mohly být zneužity k neúmyslnému spuštění nechtěné akce skrze podvržený požadavek od útočníka.
Ochrana formulářů a odkazů v Sunlight CMS
Všechny formuláře a odkazy, které to potřebují jsou v systému automaticky chráněny proti škodlivým XSRF požadavkům. U vlastních pluginů nebo HCM modulů pokud nepoužíváte systémově sestavováný formulář je potřeba tuto ochranu přidat do kódu formuláře. V opačném případě systém vypíše hlášku “Formulář nebyl odeslán s platným tokenem” nebo se požadavek prostě vůbec nezpracuje.
Pojďme si ukázat jak to napravit…
Do nechráněného formuláře stačí přidat pouze systémovou funkci Xsrf::getInput()
. která do formuláře přidá skrytý prvek s bezpečnostním tokenem, který následně server validuje po odeslání formuláře.
Na začátek souboru pokud to tam ještě není vložte za značku <?php
import knihovny use Sunlight\Xsrf;
Klasický HTML formulář
Jedná se o klasicky zapsaný HTML formulář, kamkoliv mezi značky <form></form>
přidejte zápis zmíněné funkce.
<?php
use Sunlight\Xsrf;
?>
<form name="send" method="post" enctype="multipart/form-data" action="">
<?= Xsrf::getInput(); ?> <!-- vloží ochranný input s tokenem //-->
<input name="Submit" type="submit" value="Odeslat">
</form>
String formulář
Ovšem v případech, kdy formulář vypisujete “ze stringu” (formulář vypisovaný PHP skriptem) se zápis trochu funkce liší. Protože je potřeba použít spojování řetězců pomocí teček.
<?php
use Sunlight\Xsrf;
echo '<form name="send" method="post" enctype="multipart/form-data" action="">
' . Xsrf::getInput() . ' <!-- vloží ochranný input s tokenem //-->
<input name="Submit" type="submit" value="Odeslat">
</form>';
Je nutné dát pozor jaké používáte uvozovky
Ochrana odkazů
U odkazů je situace trochu jiná, do nich nich se manuálně nic nevkládá. V tomto případě se odkaz vloží do funkce Xsrf::addToUrl()
, které do odkazu sama automaticky XSRF token přidá.
<?php
use Sunlight\Xsrf;
$unprotectedLink = 'script.php?delete=123';
$protectedLink = Xsrf::addToUrl($unprotectedLink);
echo '<a href="' . _e($protectedLink) . '">...</a>'
Příklad neřeší použití Routeru, článek se věnuje XSRF ochraně