Session fixationÚtok fixací na relaci (session fixation attack) je v informatice typ útoku, ve kterém se útočník snaží zneužít zranitelnost systému, která umožňuje jiné osobě zafixovat (vytvořit) na identifikátor relace (session ID, dále SID) jiné osoby. Většina těchto útoků se odehrává na webu a většina spoléhá na přijímání SID v rámci HTTP protokolu pomocí URL nebo POST dat. Příklad útokuPoužity jména z příkladu Alice a Bob. Alice má účet u banky na adrese http://nebezpecny.priklad.cz/ . Alice bohužel není ohledně zabezpečení moc svědomitá. Mallory chce získat peníze z účtu Alice. Mallory si získal důvěru (lhaní, phishing) Alice, která následuje odkazy poskytnuté Mallorym. Jednoduchý postup útoku
Útok za použití serverem generovaného SIDNěkteří lidé mají falešný dojem že servery, které akceptují pouze serverem generované identifikátory, jsou proti této metodě chráněné, není to však pravda. Příklad:
Útok pomocí cross-site cookingDalší útok tohoto typu lze provést pomocí cross-site cooking, využívající chyby prohlížeče, která dovolí stránce http://zlá.příklad.cz/ uložit cookie do Aličina prohlížeče pro jinou doménu http://dobrá.příklad.cz/, která je důvěryhodná. Tento útok může uspět dokonce i když nemá stránka http://dobrá.příklad.cz/ žádnou velkou bezpečnostní díru, jelikož stránka předpokládá, že spravování cookies v prohlížeči je zabezpečeno. Příklad:
Z bezpečnostních důvodů by žádný moderní prohlížeč neměl dovolovat cross-domain cookies. Útok pomocí cross-subdomain cookingToto je stejné jako předchozí příklad, s tím rozdílem že se nespoléhá na bezpečnostní díru v prohlížeči ale na faktu že cookies mohou být na daném serveru nastaveny tak, aby byly platné na všech subdoménách. Příklad:
Každý z těchto příkladů vyústil v úspěšné získání práv udělených Alici, Mallorymu. V alternativním příkladu by se Alice nemusela přihlásit na stránce. Mallory by mohl špehovat Alici a zneužít data která zadává. Mallory například použije předchozí útok a dát Alici jeho vlastní autentizované sezení, takže Alice by používala stránku s účtem Malloryho. Pokud se Alice rozhodne něco nakoupit a zadá údaje o platební kartě, Mallory by mohl být schopný získat tato (nebo jiná) data, prohlížením historie dat uloženým k účtu. ProtiopatřeníNepřijímat identifikátory sekcí přes GET / POSTNení doporučeno přijímat Identifikátory sekcí v URL (metoda GET) nebo proměnné v POST, jelikož mohou usnadnit tento útok - je velmi jednoduché vytvořit odkazy nebo formuláře které nastaví hodnotu proměnných přes GET / POST. Identifikátory sezení (SID) také umožňují:
Poznámka: Cookies jsou sdíleny mezi listy a okny prohlížeče. Mohou mezi sebou mít konflikt (adresy www.příklad.cz?code=site1 a www.příklad.cz?code=site2). Může být tedy nutné poslat identifikátor v URL aby se obešla tato limitace. Pokud je to možné, použijte subdomény (www.site1.příklad.cz místo www.příklad.cz?code=site1), abyste se vyhnuli konfliktu cookies. To může ale vyústit v potřebu více certifikátů SSL. Toto chování lze pozorovat na mnoha webech, pokud otevřeme více listů a snažíme se na nich zároveň vyhledávat. Některé z těchto sekcí poté mohou vracet nesmyslné výsledky. Nejlepší řešení: ověření identityTomuto útoku se lze většinou vyhnout pokud webový server změní uživatelovo SID když se přihlásí. Pokud je každý požadavek vázán na přihlášení ke stránce, útočník by musel znát SID přihlášeného uživatele. Když ale oběť navštíví odkaz poskytnutý útočníkem a přihlásí se, ID sezení se změní a původní odkaz nebude obsahovat platné SID oběti. Podobné řešení lze taky použít jako ochranu před phishingovými a CSRF útoky. Řešení: Uložení identifikátoru sezení v cookiesSID je na většině moderních systémů uložen v cookies které mají rozumnou míru zabezpečí pokud systém ignoruje hodnoty GET/POST. Toto řešení je ale náchylné na CSFR útok a nesplňuje požadavky REST. Řešení: Využít SSL / TLS identifikací sezeníPokud se povolí zabezpečení HTTPS, některé systémy dovolí obdržet SSL / TLS identifikátor sezení. použití SSL / TLS sezení je velmi bezpečné, ale mnoho jazyků pro vývoj webu neposkytuje plnou integrovanou funkcionalitu k tomuto zabezpečení. SSL / TLS sezení mohou být vhodné pouze pro kritické aplikace jako správa financí kvůli složitosti aplikace. Vytvoření nového SID při každém požadavkuPodobné řešení jako v prvním případě, ale nové SID se generuje při každém požadavku pro server. Pokud v tomto případě útočník uživatele přiměje k použití jemu známého SID, bude toto sezení neplatné pokud se ho útočník pokusí použít znovu. Implementace je jednoduchá:
Příklad: Pokud Mallory naláká Alici k navštívení GET /?SID=
HTTP/1.1 200 OK Set-Cookie: SID=3134998145AB331F Alice nyní bude používat Toto řešení bohužel nelze použít vždy, jsou známy problémy kdy problémy dělá software třetích stran jako například ActiveX nebo Java Applety. Když se pluginy pokouší komunikovat se serverem, může to způsobit odhlašování nebo rozdělení relace na dvě oddělené. Pokud implementace obsahuje odesílání SID pomocí GET nebo POST, nemusí v některých prohlížečích fungovat tlačítko zpět, jelikož by se uživatel snažil dostat na stránku s již nevalidním SID. Přijímání pouze serverem generovaných SIDDalší řešení je odmítnutí identifikátorů které nebyly generovány serverem. Toto ale nezabrání všem útokům tohoto typu. if (!isset($_SESSION['SERVER_GENERATED_SID'])) {
session_destroy(); // destroy all data in session
}
session_regenerate_id(); // generate a new session identifier
$_SESSION['SERVER_GENERATED_SID'] = true;
Funkce odhlášeníOdhlašování je užitečné pro zabezpečení jelikož dovolí uživateli říct že toto sezení už nebude možno použít. Útok je tedy možný pouze dokud je sezení aktivní. Zde je ukázka kódu, která však neposkytuje žádnou kontrolu na CSRF, a potenciálně útočníkovi umožňuje násilně odhlašovat uživatele z aplikace. if ( logout )
session_destroy(); // destroy all data in session
Ničit vypršelá SIDToto jednoduché opatření zvyšuje zabezpečení proti neoprávněnému přístupu k sezení, které bylo volně zanecháno. Pro realizaci je potřeba ukládat poslední čas přístupu k sezení. Když je SID znovu použito, zkontroluje se rozdíl času a pokud je rozdíl větší než povolená hodnota, sezení se zničí, jinak se nastaví nová hodnota času posledního přístupu. Zničení sezení pokud je podezřelá vstupní stránkaPokud navštěvujete stránku, většina prohlížečů předá hodnotu referrer - stránku obsahují odkaz, ze které jste se na aktuální stránku dostali. Pokud se tedy uživatel dostane na stránku, u které není pravděpodobné, že by byla odkazována z jiného webu (bankovnictví, mail, ...), a stránka není toho typu, kde by byly uživatelé přihlášení delší dobu, uživatel by měl pocházet pouze z oné stránky. Každá jiná návštěva by měla být brána za podezřelou. Pokud je ale původní požadavek z HTTPS stránky, referrer se nepředává, tudíž se na toto zabezpečení nelze spoléhat. Pro příklad stránka if (strpos($_SERVER['HTTP_REFERER'], 'http://vulnerable.example.com/') !== 0) {
session_destroy(); // destroy all data in session
}
session_regenerate_id(); // generate a new session identifier
Ověřit zda jsou přídavná data v sezení konzistentníDalší možnost jak vylepšit zabezpečení je ujistit se že data (například verze prohlížeče) klienta patří stejnému uživateli. Toto opatření dělá tento a další útoky o něco těžší. Jelikož se čím dál více sítí drží RFC 3704 a dalších anti-spoofing opatření, IP adresa se stává spolehlivým identifikátorem. Zabezpečení webové stránky může být vylepšeno ověřováním konzistence IP adresy v průběhu sezení. Toto ověřování může vypadat například takto: if($_SERVER['REMOTE_ADDR'] != $_SESSION['PREV_REMOTEADDR']) {
session_destroy(); // destroy all data in session
}
session_regenerate_id(); // generate a new session identifier
$_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Před použitím je potřeba zvážit tyto body:
User AgentWebové prohlížeče se identifikují pomocí HTTP hlavičky "User-agent". Tato hlavička se v normálním případě nemění, pokud se tak stane, je to velmi podezřelé. Webová aplikace se může pokusit o identifikaci pomocí této hlavičky aby zabránila zlomyslným uživatelům v kradení sezení. Toto se dá ale velmi jednoduše obejít pokud útočník zaznamená řetězec user-agent oběti a poté napodobí během útoku. Toto řešení spoléhá na systému "security through obscurity". if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['PREV_USERAGENT']) {
session_destroy(); // destroy all data in session
}
session_regenerate_id(); // generate a new session identifier
$_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
Body na zvážení při implementaci:
Hloubková ochranaPro nejvyšší ochranu je vhodné kombinovat některé z uvedených opatření. Zatímco jednu ochranu může být lehké překonat, vhodnou kombinací lze docílit dobrého zabezpečení. Taková ochrana může obsahovat:
Je potřeba poznamenat že HTTP hlavička referrer není předána při použití SSL. Následující skript demonstruje několik takových opatření pro dosažení hloubkové ochrany: if (isset($_GET['LOGOUT']) ||
$_SERVER['REMOTE_ADDR'] !== $_SESSION['PREV_REMOTEADDR'] ||
$_SERVER['HTTP_USER_AGENT'] !== $_SESSION['PREV_USERAGENT'])
session_destroy();
session_regenerate_id(); // generate a new session identifier
$_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Všimněte si že tento kód kontroluje aktuální IP adresu (REMOTE_ADDR) a hlavičku user-agent a porovnává je z hodnotami z předchozího požadavku. To může být nevhodné kvůli některým důvodům uvedeným výše. ReferenceV tomto článku byl použit překlad textu z článku Session fixation na anglické Wikipedii. |