Accendo > Publikované > ASPX Úvod do ochrany – 01 Session

Autor:                  Libor Bešenyi

Dátum:                2012/07/18

Zmena:                                2012/07/18

ASPX Úvod do ochrany - Session

V tomto blogu by som chcel začínajúcich programátorov zasvätiť do jednoduchých praktík ochrany webových stránok postavených na Microsoft ASPX technológií.

Vytvoríme si teda jednoduchý web s dvoma stránkami: WebForm1 a WebForm2. Po spustení sa zobrazí jedna zo stránok nastavených ako spúštacia stránka. V prehliadači môžeme vidieť niečo ako:

http://localhost:57394/WebForm1.aspx

Hlavná myšlienka ochrany je zneprístupnenie stránok neautorizovanému užívateľovi. Jedná vec je tá, že na stránke nemáme žiaden odkaz, iná ale povolenie prístupu na tú stránku prepísaním Url v prehliadači:

http://localhost:57394/WebForm2.aspx

Session ochrana

Akonáhle toto urobíme, stránka je prístupna. Teraz si ukážeme jednoduchý príklad „ochrany“ modulov. Predpokladajme, že obe stránky zdieľajú rovnaký master page. Vytvorme si teda jeden formulár (čistý – neodvodený od master pagu) s názvom WebFormLogin.aspx. Označme ho ako defaultnú stránku (Set as startup page). Vytvorme tam tlačidlo Login, ktoré automaticky prihlási užívateľa.

Informácie o prihlásení budeme držať v Session. Session je „pamäť“ vyhradená komunikácii medzi prehliadačom a serverom na strane servera. To zjednodušene znamená, že kedykoľvek sa prihlási váš prehliadač, server alokuje pamäť pre toto „sedenie“ (ak to je potrebné). Prehliadačom môžeme surfovať po stránkach našej aplikácie a ukladať do tejto pamäte rôzne stavy, napr. na jednej obrazovke môžeme od užívateľa opýtať telefónne číslo a pri práci s aplikáciou na inej obrazovke toto číslo vieme zobraziť. Prípadne to môže byť nákupný košík v eShope, ktorý nemá zmysel ukladať v DB.

POZOR: Používatenie session je ľahkým spôsobom pre programátora a tak sa to často zneužíva. Prácu so session je vhodné centralizovať, aby sme vedeli koľko a čoho vlastne v session držíme (už aj kvôli refaktoringu). Veľa programátorov si uľahčí prácu tým, že prechody medzi stránkami uloží do session aj vtedy, ak to nie je nevyhnutné. Niekedy sa tomu samozrejme nedá vyhnúť, ale treba pamätať na to, že session stavy „viažu“ postupnosť ku stránke (užívateľ musí byť navigovaný našou aplikáciou – nesmie použiť „Favorit“ alebo posledné URL v prehliadači, ináč by mohol preskočiť nejakú zo stránok, ktorá vkladá niečo do session, čo sa očakáva na danej stránke).

V našom prípade my session taktiež zneužijeme na to, aby sme vedeli, či je užívateľ prihlásený. Do Session si teda natrieskame flag „JePrihlaseny“ na true na udalošt OnClick tlačidla Login:

protected void ButtonLogin_Click(object sender, EventArgs e)

{

       Session["JePrihlaseny"] = true;

       Response.Redirect("WebForm1.aspx");

}

 

Teraz je tento flag viditeľný pre všetky stránky v rámci práce so serverom pre daný prehliadač. Týmto flagom ale musíme zakázať prístup na stránky odvodené od našeho masterpagu (budú to zdieľať všetky stránky a tak to nemusíme programovať zakaždým keď pridáme modul):

protected void Page_Load(object sender, EventArgs e)

{

       if (!IsPostBack)

       {

             if (!((bool?)Session["JePrihlaseny"] ?? false))

                    throw new SecurityException("Pristup odmietnuty!");

       } // if

}

 

Ak teraz spustíme aplikáciu, dostaneme sa na formulár Login. Pred tým, ako stlačíme tlačídlo, skúsme sa dostať na URL WebForm1. Bez prihlásenie dostaneme chybu:

Až ked sa vrátime na login obrazovku, klikneme na Login tlačidlo, WebForm1 aj 2 budú pre nás prístupné.

Ako ale prehliadač vie, že je prihlásený, keď túto informáciu drží server? Veď na serveri môže byť prihlásených N užívateľov. Ako je to možné, že to server nepomotá a pridelí „session“ správnemu prehliadaču?

Na to nám vie odpovedať Firefox (napríklad). Otvorme si cookie prehliadač a sledujme, čo sa deje, keď aplikáciu spúšťam:

Ako vidno... nič. Po prihlásení ale (aplikácia využila session servera) sa v cookies objavuje nová položka:

Ako môžeme vidieť – prehliadač si v cookies pamätá nejaký reťazec (Content), ktorým sa potom na strane servera páruje s pamäťou. Teda užívateľ niečo vykoná na stránke (spojenie je prerušené, kým sa nevykoná postback). Prehliadač pozbiera dáta (aktivita) a posiela ich na server spolu s cookies. Server príjma požiadavku, pozrie do cookies, či neobsahuje session ID kľúč. Ak áno, pozrie sa, či vo svojej pamäti má niečo uložené pre daný kľúč. Ak áno, server side kód pre daný request pracuje s tým, s čo bolo uložené dávnejšie.

Tu sa natíska otázka, je môžná konštrukcia „ak kľúč server nenašiel...“? Áno je. Záleží od rôznych nastavení (web.config / IIS) ako dlho má server pre daný request držať dáta. Predstavme si, že zavrieme prehliadač cez ALT+F4 alebo vypne elektrický prúd. Server ani len netuší, že je užívateľ odrezaný (a ten po opätovnom zapnutí prehliadača bude mať vygenerovaný nový session key). Takáto pamäť by sa na serveri hromadila, až by server vydochol na nedostatok pamäte.

Preto existujú nastavenie session, ktoré dovoľujú serveru uznať za vhodné, že pri dlhšej neaktivite je daný uživateľ off a proste sa z pamäte táto časť uvoľní. Toto sa volá expirácia session. Nie je ale cieľom tohto článku sa o tom viacej rozpisovať.

Zaujímavejšou otázkou ale je, čo ak prehliadaču vynútim nejaký session key. S najväčšou pravdepodobnosťou taký kľúč nebude existovať, ale teoreticky sa takto dá ukradnúť „spojenie“ niekomu inému. Teda niekto sa prihlási (a pracuje na stránke). My zistíme nejakým sôsobom aký kľúč pre párovanie používa jeho prehliadač v danej chvíli. Ak takýto kľúč použijeme na inom PC, server nebude mať ani zdanie, že sme niekto iný. Takýto útok sa volá MITM (men in the middle). Niekto odpočúva komunikáciu medzi prehliadačom a serverom a potom sa vie tváriť ako my.

Takto sa javí session security ako nevhodné riešenie pre prácu s ochranou. Ono to ale zasa také zle nie je. Hacker určite nesedí pri našej klávesnici a teda jediný spôsob ako môže zistiť kľúč je nejakým spôsobom sniffrovať sieť (keďže nemá prístup ku nášmu prehliadaču v čase keď s ním pracujeme my). Ak však naše spojenie so serverom prebieha kryptovane (SSL), až také jednoduché to zasa pre neho nebude...

Webová aplikácia ale nie je len webová stránka. Môžu to byť aj webové služby (SOAP). Tam použitie session security môže byť trochá obtiažné ak nie nemožné (pre WCF proxy). Session security tiež je absolútne nevhodná pri SSO systémoch (ak máme niekoľko webových aplikácii a užívateľ sa medzi nimi prepína bez toho, aby sa musel do každej prihlasovať). Preto si nabudúce povieme niečo o jednoduchej  .Net Security Policy.

Demo projekt na stiahnutie je tu: http://www.accendo.sk/Download/AspxOchranaDemo01.zip