Lekce 9 - Session hijacking a jak se proti němu bránit
V předchozí lekci, Útok DDoS a jak se před ním bránit, jsme se seznámili s útokem DDoS a také jsme si uvedli způsoby, jak před tímto útokem svou aplikaci chránit.
V této lekci kurzu bezpečnost webových aplikací se seznámíme s útokem Session hijacking. Session hijacking je typ útoku, pomocí kterého útočník ukořistí tzv. Session ID (zkráceně SID). SID je náhodně vygenerovaný token, pomocí kterého se útočník může vydávat za uživatele (neboli nás).
SID
SID uživatele je náhodně vygenerovaný token, pomocí kterého server páruje požadavky konkrétních uživatelů. Obecně se k SID váží informace jako je přihlášení uživatele či objednávka na e-shopu. Jeho odcizení je proto veliké bezpečnostní riziko. V dnešní lekci si lehce zmíníme odcizení SID uhodnutím a poté se zaměříme na samotný Session hijacking.
Proč vůbec SID používat
HTTP je samo o sobě bezstavová komunikace. Při každé návštěvě nějaké stránky si server nepamatuje, zda ji uživatel již navštívil či jestli na ní třeba nebyl přihlášen pár sekund na zpět. Z tohoto důvodu se vyvinulo SID. SID je hodnota, díky které si může server v HTTP komunikaci uchovávat jakési stavy. Server si tak může uchovat obsah košíku zákazníka či zapamatovat, že byl zákazník před krátkou dobou na tomto zařízení autorizován a nebude tak vyžadovat přihlašovací údaje znova.
Metody zasílání SID
Nejdříve si uvedeme způsoby, jak si mezi sebou mohou klient a server SID vyměňovat. Uvedeme si základní 3 způsoby:
- Parametr v URL adrese
- Skryté formulářové pole
- Cookies
Parametr v URL adrese
V tomto případě si server přidá do odkazu parametr s hodnotou SID v
požadavku GET
, jako příklad si můžeme uvést:
stranka.cz?SID=clientSID
Při otevření takového dotazu se předává hodnota SID. Na straně
serveru můžeme potom k hodnotě SID přistoupit pomocí super globálního
pole GET
:
$sid = $_GET['SID'];
Skryté formulářové pole
Tato metoda naopak využívá požadavku POST
, ve kterém zašle
SID. SID se typicky vloží do skrytého formulářového pole, které se
odešle v těle požadavku serveru. Příklad formuláře může být
následující:
<form action="welcome.php" method="get"> <input type="hidden" name="sid" id="sid" value="$clientSID" /> Name: <input type="text" name="name"><br> E-mail: <input type="text" name="email"><br> <input type="submit"> </form>
V prohlížeči normálně skryté pole nevidíme:
Cookies
Poslední metodou je uložení cookie na straně klienta. Ta se pak s
každým dalším požadavkem serveru posílá v HTTP hlavičce požadavku. U
dotazu se posílá pomocí Cookie
a u odpovědi poté pomocí
Set-Cookie
. Ukládání SID za pomocí cookie je v dnešní době
nejpoužívanější varianta.
Session hijacking
Session hijacking je útok, při kterém se útočník snaží získat uživatelův SID. Způsobů, jak docílit odcizení SID, je hned několik, dnes si uvedeme:
- Útok hrubou silou
- Cross-site scripting (XSS)
- Session side jacking
- Session fixation
- Odcizení SID za pomocí malware
Útok hrubou silou
Při útoku hrubou silou útočník zkouší postupně různé kombinace SID, dokud se mu nepodaří validní SID uhodnout. Abychom zamezili tomu, že se útočník pokusí SID uhodnout nebo odhalit, měli bychom zajistit, aby každé vygenerované SID mělo následující vlastnosti:
- Unikátnost - Každý uživatel a každá jeho návštěva by měla dostat unikátní, dosud nepoužitý token.
- Náhodnost - Nemělo by být možné napodobit podmínky, které dovedou ke generaci SID, které je již přiděleno. Tomu se rozumí, že bychom neměli SID generovat například z IP adresy uživatele.
- Nezávislost - Jak bylo zmíněno u předchozí vlastnosti, SID by se nemělo vázat na žádný smysluplný údaj.
- Neodvoditelnost - Nemělo by být možno zjistit způsob generace SID z několika již vygenerovaných SID.
- Dostatečná délka - Čím delší je námi vygenerovaný SID, tím déle bude útočníkovi trvat, než ho uhodne.
- Expirace - SID by nemělo by mělo být obměňováno v intervalu 5-30 minut.
Společně s těmito vlastnosti můžeme například generovat taková SID, která neobsahují nějaký znak na počátku, například 0. Pokud dostaneme požadavek s tímto znakem, okamžitě můžeme prohlásit, že se někdo snaží dostat do naší aplikace pomocí útoku hrubou silou.
V PHP nám pro generování SID bohatě stačí obsluha SESSION
,
která výše uvedené vlastnosti zohledňuje. Avšak tyto vlastnosti neplatí
pouze pro generování SID, ale také pro jakýkoliv jiný náhodně generovaný
token. Pod tímto tokenem si můžeme například představit token,
používaný pro obranu proti CSRF
útoky z jedné předešlé lekce.
V PHP se session ID vygeneruje automaticky po provedení příkazu
session_start()
. Samotný SID můžeme dostat pomocí funkce
session_id()
. Následující kus kódu tedy vygeneruje SID a
vypíše ho:
session_start(); echo session_id();
Můžeme také vygenerovat SID, který neobsahuje námi zvolený znak. To uděláme třeba takto:
session_start(); $sid = session_id(); while ($sid[0] == 0) { session_regenerate_id(); $sid = session_id(); }
Pro generování náhodných tokenů bychom měli využít vestavěných funkcí. Relativně bezpečnou cestou jak vygenerovat náhodný token v PHP je:
$token = md5(uniqid(mt_rand()) . $_SERVER['REMOTE_ADDR']);
Náhodně vygenerované číslo připojíme k IP adrese uživatele a z
kombinací těchto čísle vygenerujeme náhodné id pomocí
mt_rand
, výsledek ještě zahashujeme pomocí funkce
md5
.
Cross-site scripting (XSS)
Cross-site scripting útok lze použít pro odcizení SID, na tento typ útoku již existuje v tomto kurzu samostatná lekce, více detailů se proto můžeme dozvědět právě v lekci o XSS, kde je také uveden příklad s ukradením session admina. XSS je v rychlosti typ útoku, při kterém útočník (například do komentáře na stránce) uloží kus kódu, který poté uživatelův prohlížeč interpretuje v útočníkův prospěch.
Session side jacking
Při tomto typu útoku útočník využije software, pomocí kterého lze zobrazit pakety proudící v síti a přímo z nich dostane SID uživatele. Hodně stránek používá SSL/TLS kódování pouze pro přihlašovací formulář, ze zbytku komunikace může útočník SID bez problému vyčíst a dále ho zneužít. Útočník ale potřebuje přístup do sítě uživatele, tento typ útoku je proto typický pro veřejné Wi-Fi sítě.
Session fixation
Session fixation využívá weby, které zasílají SID v požadavku
GET
pomocí parametru v URL. Toho může útočník poměrně
jednoduše využít. Může například uživateli zaslat falešný e-mail nebo
ho jiným způsobem nalákat k přihlášení na takto zranitelný web přes
jeho vytvořený odkaz. Takový odkaz by mohl vypadat následovně:
<a href="http://www.zranitelnaStranka.cz/login.php?SID=UtocnikemDodanySID">Kliknutím se přihlaste</a>
Potom co uživatel klikne na takto vytvořený odkaz, je přesměrován na stránky takto zranitelného webu, kde se přihlásí s útočníkem dodaným SID. Pokud se tak stane, útočník má nyní k dispozici aktivní SID, pod kterým je jeho oběť přihlášená.
Odcizení SID za pomocí malware
Poslední metodou útoku Session hijacking je odcizení SID za pomocí
malware. Tato metoda je velice běžná, uživatel si nechtěně infikuje
počítač útočníkovým malwarem, ten je pomocí něho schopen odchytávat
cookies z internetového provozu uživatele nebo k nim dokonce může přímo
přistoupit. Cookies jsou často uloženy v dočasných souborech prohlížeče
ve složce cookieJar
.
Jak se před útokem Session hijacking bránit
Nyní si uvedeme několik způsobů, jak se před útokem Session hijacking bránit.
Použití HTTPS
protokolu
Použitím protokolu HTTPS
docílíme toho, že celá komunikace
v rámci session
naši aplikace bude šifrována za pomocí
SSL/TLS
. To zabrání útokům typu
Session side jacking
, protože uživatel nyní nebude schopen
jednoduše vyčíst SID z komunikace mezi klientem a serverem. Nejlépe můžeme
použít HSTS
protokol, který je ještě o něco striktnější
než HTTPS
.
Generování náhodného SID
Jak jsme si již uvedli v části o útocích hrubou silou, je důležité generovat SID, které nejdou lehce uhodnout či odvodit. Nejlépe uděláme, když do SID přidáme nějakou kombinaci znaků, která nám prozradí, že se někdo pokouší o útok hrubou silou.
Generování nového SID po přihlášení
Důležité také je, abychom po přihlášení uživatele vygenerovali SID znova, toto opatření zamezí útokům typu session fixation. Útočník totiž sice zná SID, pomocí kterého se uživatel přihlásil, ale protože ihned po přihlášení vygenerujeme SID nové, je tak staré SID útočníkovi k ničemu.
Další způsoby autorizace
Dalším způsobem jak zamezit session hijack útokům je přidat další
vrstvu ověření uživatele. Takové ověření může kontrolovat IP adresu,
ze které je uživatel většinou přihlášen a pokud přijde požadavek na
autorizaci z jiné IP adresy, bude uživatel muset potvrdit přihlášení přes
e-mail nebo 2FA
. Další takovou metodou je ukončení
session
po uplynutí určité doby, po kterou byl uživatel
neaktivní
V další lekci, SPAM a jak se proti němu bránit, se seznámíme s útokem SPAM.