Zabezpečení internetových aplikací .NET

© 2009 Ing. Roman Fischer

1. Úvod

Zabezpečení internetových aplikací je velmi důležité a diskutované, i když kolikrát opomíjené téma. Prakticky veškeré aplikace provozované v síti Internet vyžadují přenášení velkého množství informací. Takové informace jsou kolikrát nejen důvěrné, ale i citlivé natolik, že nelze připustit, aby je dostala do rukou nepovolaná osoba. Počínaje informacemi, které si předává internetový obchod s klientem, přes vnitropodnikové aplikace, v kterých kolují důvěrná firemní data, až po bankovní aplikace, kdy má jejich získání nepovolanou osobou katastrofální následky. Internetové aplikace jsou v provozu 24 hodin denně, 7 dní v týdnu. Pro hackery jsou vítaným pokušením právě díky jejich trvalému provozu a možnosti stále se snažit do nich pronikat.

Je nutno ovšem podotknout, že ani sebelepší nastavení používané dnes není stoprocentní, vždy existuje pravděpodobnost prolomení ochrany a je potřeba dbát na aktuálnost způsobů zabezpečení a stále je inovovat v souladu se současným vývojem v oblasti.

Velký rozmach používání internetových aplikací v současné době a snaha nahrazovat klasické aplikace internetovými s sebou samozřejmě přináší mnoho rizik. Tato rizika lze shrnout do konstatování, že vzhledem k tomu, že infrastruktura vnitropodnikových řešení v sobě obsahuje internetové aplikace ve stále větší míře, pokoušejí se i hackeři využít těchto aplikací k prolomení do vnitropodnikových databází čím dál víc.

1.1. Co je internetová aplikace?

Internetová aplikace, nebo též web aplikace, je aplikace, která je spuštěna na www serveru a ke které může přistupovat každý uživatel stejně jako k World Wide Web. Způsoby ochrany přístupu, tedy autentizace a autorizace uživatelů spolu s ochranou před záměrným napadením či náhodným zhroucením aplikace jsou cílem této práce.

Webová aplikace je dnes nejčastěji řešena jako třívrstvá. První vrstvu tvoří internetový prohlížeč (de facto kód, který se stará o zobrazení uživatelského prostředí), pomocí kterého klienti přistupují k obsahu. Druhou vrstvou je technologický nástroj generování obsahu a třetí vrstvu pak tvoří databáze.

Internetový prohlížeč vznáší prvotní požadavek na střední vrstvu, která pak přistupuje k databázi buď pro získání, uložení nebo aktualizaci dat. Díky tomu, že internetové aplikace jsou provozovány na serverech, ke kterým se uživatelé připojují, je jejich aktualizace velmi snadná. Není již zapotřebí aktualizovat všechny jednotlivé klienty - stačí provést změny na serveru. To je také jedním z hlavních důvodů jejich používání.

Zde je vhodné zmínit, že internetové aplikace, provozované nejen na technologiích společnosti Microsoft bývají rozšiřovány o vrstvu čtvrtou – aplikační. Nebo lze také říci, že technologie generování obsahu je dělena na dvě samostatné vrstvy. První se stará o vyřizovaní požadavků mezi serverem a klientem, kontrolu vstupů, ochranu před útoky, apod. a druhá pak obstarává hlavní činnosti, ke kterým je aplikace určena. V závislosti na nárocích, které jsou na aplikaci kladené, může být druhá dílčí vrstva dělena na mnoho dalších dílčích vrstev, starajících se o samostatné úkony při zajišťování odpovědi na požadavek klienta.

První části je tedy svěřena velmi důležitá funkce ochrany aplikace. Programy, obsažené v dílčích vrstvách již očekávají bezpečná data a mohou se starat jen o jejich validaci vzhledem k úkonům, které s nimi provádějí.

1.1.1. ASP.NET internetová aplikace

Internetová aplikace provozovaná na platformě .NET dokáže simulovat stavové prostředí na jinak bezstavovém protokolu HTTP. Na rozdíl od většiny ostatních aplikačních prostředí pro internet, která zvládají většinou jen model požadavek/odpověď, dokáže ASP.NET provozovat tzv. událostmi řízený model komunikace klient-server. Toho dosahuje kombinací HTML a Javascriptu, kterou dynamicky vkládá do stránek odesílaných uživateli. „Uchovává informace mezi postbacky (opakovaným odesíláním formuláře na server) v zakódovaném tvaru ve skrytých formulářových polích a oproti tomu ukládá veškeré informace na straně serveru a prohlížeči předává pouze jednoznačný identifikátor“ . Tato krkolomná definice v podstatě znamená, že server dokáže rozeznat, zda určitá posloupnost požadavků (a nemusejí být ani odesílány formulářem, stačí změny textu v polích, přejetí myši přes určité místo na stránce, atd.) pochází od určitého klienta. To velice usnadňuje sledování chování uživatele na stránce a nemusí se čekat až na finální odeslání formuláře.

Internetové aplikace ASP.NET lze stejně jako klasické aplikace pod .NET Framework vyvíjet v libovolném programovacím jazyce, který je běhovým prostředím podporován. Ve všech následujících ukázkách používám jazyk C#, který je Microsoft verzí jazyka C.

1.2. Oblasti, které je potřeba chránit

V celé práci se budu zabývat způsoby, jak webovou aplikaci ochránit. Nejen na úrovni samotné aplikace, ale v celém kontextu jejího provozu. Také se pokusím objasnit šifrování, jelikož mnoho oblastí zabezpečení tuto ochranu využívá. Následující tabulka ukazuje strukturu ochrany internetové aplikace. Záměrně je zde vynecháno zabezpečení databáze, jelikož by vydalo na samostatnou studii a není cílem mé práce. Zabezpečení přístupu k databázi bude zmíněno jen v případech, které se dotýkají programového kódu aplikace. Schéma se tedy skládá z částí, které se běhu aplikace přímo dotýkají, tj. programového kódu aplikace, nastavení serveru a služeb pro její provoz.

ČÁST SYSTÉMU ZPŮSOB ÚTOKU ZPŮSOB OCHRANY
Server Přístup nepovolených klientů Konfigurační správa
Attack surface
Attack surface
Služby a jejich knihovny
Odposlech komunikace s klientem SSL
Aplikace Nedovolený přístup Autentizace
Neoprávněný přístup Autorizace
Záměrné změny v session cookies Ochrana session
Cross site scripting Kontrola vstupů
Script injection
SQL injection SQL procedury s parametry
Chyby a výjimky Ošetření chyb a výjimek, trasování

Tabulka 1, Struktura ochrany internetové aplikace

2. Zabezpečení internetových aplikací ASP .NET

1.3. Základní pojmy

V úvodu by bylo dobré definovat několik pojmů, které se vztahují k zabezpečení internetových aplikací obecně a které budou v následujícím textu často používány.

1.3.1. Autentizace

Slouží ke zjištění identity uživatele, požadujícího načtení určitých stránek či informací. Uživatel je přitom identifikován na základě jeho identifikačních údajů, které mohou mít mnoho různých forem (nejčastěji se však jedná o kombinaci uživatelského jména a hesla). Proces autentizace zajistí, že do systému vstoupí opravdu jen definovaný uživatel. Pokud nemůže být uživatel na základě jím poskytnutých údajů identifikován, autentizace je neúspěšná a přístup je neznámému uživateli odmítnut. Jsou-li naopak uživatelské údaje (jméno, heslo, atd.) systému, do kterého vstupuje, známé, je uživateli přístup povolen a současně je mu přiřazena ona známá identita.

1.3.2. Autorizace

Jakmile je uživateli přidělena nějaká identita, je ještě zapotřebí určit, které oblasti www serveru může navštívit, které stránky smí vidět, které soubory může z www serveru získávat – obecně řečeno, ke kterým zdrojům má tato identita přístup. Proces, který nám požadované nastavení zajišťuje, se nazývá autorizace.

1.3.3. Impersonalizace

Tento proces je součástí řízení přístupu u ASP.NET aplikací a bývá též nazýván zosobnění. Umožňuje vykonávání ASP.NET stránek s identitou toho uživatele, který si přístupu k stránkám vyžádal. Bude-li například ověřen uživatel s identitou jan.novak, bude mu přidělen nebo naopak odepřen přístup podle přístupových oprávnění uživatelského účtu jan.novak. V zásadě proces zosobnění probíhá tak, že pokud je uživatel ověřen metodou autentizace a je mu přidělena identita, aplikace ASP.NET tuto identitu převezme a operační systém je pak schopen řídit přístup daného uživatele. Pokud však není uživatel identifikován, je mu přidělena identita Host (skupina účtů Guests systému Windows) a jako Host je také řízen jeho přístup.

Aplikace ASP.NET využívá pro svůj bezchybný chod v operačním systému rozsáhlá oprávnění, díky kterým může přistupovat ke všem prostředkům nabízeným systémem. Je však nutno si uvědomit, že ne vždy chceme dovolit uživateli disponovat tak rozsáhlými oprávněními. Pokud by neoprávněný uživatel získal kontrolu nad ASP.NET aplikací, mohl by pak bez problému přistupovat k celému operačnímu systému. Využijeme-li ale principu zosobnění, lze přístupová práva poměrně snadno omezit.

1.4. Nastavení www serveru

U serverové části je potřeba brát v úvahu nejen nastavení celého operačního systému a služeb zprostředkovávajících běh aplikace, ale i fyzické umístění serveru a ochranu datových linek. Výborně softwarově zabezpečený server nás neuchrání před fyzický odcizením. Taktéž přístup k serveru by měly mít jen kompetentní osoby. V zásadě by se dalo polemizovat i nad aplikacemi provozovanými formou ASP (Application Service Providing ) .

1.4.1. Služba IIS 6.0 a její nastavení pro bezpečný provoz aplikací ASP.NET

Hnacím motorem aplikací ASP.NET je IIS (Internet Information Services). Nejedná se jen o jedinou službu, ale jde o sadu aplikací společnosti Microsoft pro Internet. „IIS není jen webový server. Podporuje protokol FTP (File Transfer Protokol), NNTP (Network News Transfer Protocol) a také protokol SMTP (Simple Mail Transfer Protocol) pro email. Díky plné integraci na úrovni operačního systému se dobře integruje s aplikacemi Microsoft .NET a umožňuje organizacím přidávat internetové možnosti, které mohou snadno slučovat s dalšími součástmi své infrastruktury.“

1.4.1.1. Základní doporučení při instalaci IIS a Windows Server 2003
  • Používejte oddíly NTFS Server IIS je vystaven okolnímu světu, přistupují k němu různí uživatelé, které nemůžeme dopředu identifikovat. Systém souborů NTFS nabízí mnohem vyšší úroveň kontroly nad přístupem k souborům než systém FAT.
  • Oddělte soubory operačního systému od datových souborů Použití více oddílů má své nesporné výhody. Operační systém by měl mít svůj vlastní oddíl, soubory aplikace či aplikací by měly být umístěny na jiném oddílu a pokud je databáze provozována na stejném serveru, měla by mít taktéž vymezen svůj vlastní oddíl. V případě zhroucení jednoho oddílu je obnova provozu snazší, než při použití jediného oddílu na disku.
1.4.1.2. Účty používané službou IIS
  • IUSR_COMPUTERNAME - Tento uživatelský účet umožňuje anonymní přístup k webovému serveru, když se uživatel připojí k webové stránce bez vlastních informací o zabezpečení. Uživatelský účet IUSR_COMPUTERNAME je členem skupiny GUESTS.
  • IWAM_COMPUTERNAME - Tento uživatelský účet je využíván v prostředí Windows Server 2003 ke spouštění pracovních procesů. Je členem skupiny IIS_WPG.
  • Skupina GUESTS - Skupina účtů s nejnižším oprávněním přístupu k systémovým prostředkům.
  • Skupina IIS_WPG - "Členové této skupiny mohou spouštět pracovní procesy. Jedná se o účet s nízkou úrovní zabezpečení, který využívá oprávnění stejná jako uživatelský účet Network Service. Veškeré procesy, které používají tato oprávnění mohou přistupovat k serveru stejně, jako kdyby byly spuštěny mimo server. Nemusí mít tedy oprávnění přístupu přímo k operačnímu systému."
Obrázek č.1 v příloze ilustruje použití účtu IUSR_COMPUTERNAME v nastavení webového serveru ve Windows Server 2003. V případě, že chceme povolit přístup libovolnému uživateli ze sítě internet, je zapotřebí tento účet použít. V případě, že chceme přístup k serveru omezit, můžeme vybrat libovolného uživatele a tomu přístup povolit. Při přístupu k webovému serveru pak bude systém Windows vyžadovat přihlášení a v návaznosti na jeho úspěšnost přístup povolí nebo zamítne.

1.4.2. Nastavení způsobu ověřování

Na téže kartě IIS můžeme provést nastavení způsobu ověřování. Nejbezpečnější ověřování nabízí volba Integrované ověřování systému Windows. „Podporuje jak protokol Kerberos v5 , tak protokol NTLM (NT LAN Manager) v balíčku Negotiate. Pokud je používána služba Active Directory a prohlížeč ji podporuje (Internet Explorer verze 5 a vyšší se systémem Windows 2000), používá se protokol Kerberos. V opačném případě se používá protokol NTLM.“ Tato volba však má omezení v tom, že je potřeba jako klientský prohlížeč používat Microsoft Internet Explorer a nelze ji aplikovat v případě použití HTTP proxy serveru. Ačkoliv prohlížeče MS Internet Explorer tento způsob zabezpečení přihlašování podporují již od verze 2.0, některé prohlížeče, jako například Netscape, tuto možnost neumožňují. V takovém případě je vhodné provést zabezpečení pomocí Ověřování algoritmem Digest. „Ověřování algoritmem Digest představuje jednoduchý hash algoritmus , a proto je funkční v rámci bran firewall i u serverů proxy. Tato metoda dále vyžaduje, aby řadič domény uchovával kopii každého hesla ve formátu prostého textu, aby mohlo být heslo porovnáno s hodnotou hash odeslanou klientem.“ Je zřejmé, že právě tento požadavek představuje slabé místo zabezpečení, protože případné narušení přístupu k řadiči domény může potencionálnímu útočníkovi dovolit získat hesla uživatelů. Větší bezpečí přináší Ověřování algoritmem Advanced Digest. To se od předchozího liší tím, že uživatelské údaje již nejsou na řadiči domény uchovávána v podobě čistého textu, ale ve formě řetězce vytvořeného algoritmem MD5.

Dále lze zmínit volby Základní ověřování (Basic Authentication) a Ověřování službou .NET Passport. Základní ověřování je sice nejuniverzálnějším, avšak nejméně vhodným způsobem, protože jméno i heslo je v síti přenášeno jako prostý text. Volba Ověřování službou .NET Passport je sice pohodlný způsob ověření pro uživatele (postačuje jejich registrace do služby .NET Passport na serveru Microsoft), avšak vyžaduje spuštěný server služby .NET Passport a nepřináší vlastně jinou výhodu než tu, že uživateli stačí jedno přihlašovací jméno a heslo pro přístup na všechny webové servery, které podporují tuto službu. Tato služba umožňuje jen autentizaci uživatelů, nikoliv však jejich autorizaci. „Služba neumožňuje řízení přístupu ani autorizaci na serveru. Server může s využitím služby .NET Passport pouze potvrdit, že uživatel webu, který se představuje jako osoba zastoupená stanoveným profilem v serveru se službou .NET Passport, byl úspěšně ověřen jako osoba tímto profilem zastoupená. Výhodou je však uložení ověření v jiném serveru, za jehož vytváření a údržbu nejsme odpovědni. Problém služby .NET Passport je ale v tom, že mezi uživateli není moc populární. Webová společnost se obává poskytovat jí soukromé informace. Poskytovatelé obsahu webu a portály nepřijaly .NET Passport s velkým nadšením, protože obecně již mají své vlastní ověřovací systémy. Uživatelé se tak musí ověřovat vícekrát a výhody jediného přihlášení tak zůstávají nevyužity.“ Navíc je využívání této služby na webovém serveru ze strany společnosti Microsoft zpoplatněno.

1.4.2.1. Omezení přístupu podle IP nebo názvů domén

Pokud požadujeme, aby náš server zpracovával jen požadavky z určitých IP adres nebo jen z určitých domén, lze jej nastavit přidělením nebo odepřením přístupu. Lze nastavit jak jedinou IP adresu nebo doménu, tak i rozsah IP adres. Je však nutno brát v úvahu, že ověřování domény vyžaduje při každém příchozím požadavku zpětné hledání názvu domény, jelikož příchozí požadavek je identifikován IP adresou. Zpětné hledání DNS zatěžuje provoz serveru, nepatří mezi rychlé operace a není příliš vhodné je používat. Ukázka nastavení omezení přístupu k www serveru Microsoft Windows 2003 je na obrázku č. 2 v příloze.

1.4.2.2. Konfigurace knihoven a snížení attack surface

Zmenšení Attack surface web serveru lze provádět pomocí povolení odpovídajících web extensions , modifikací přiřazení web extensions k typům souborů nebo použitím Security Configuration Wizard (SCW). SCW je nástroj společnosti Microsoft dodávaný společně s Windows Server 2003. Není však součástí standardní instalace a pokud chceme využít pohodlného nastavení zabezpečení, je zapotřebí jej doinstalovat. Tento malý program nám pomocí průvodce usnadní nastavení zabezpečení celého serveru. Pomáhá s nastavením zabezpečení všech rolí serveru , s nastavením přístupu k jednotlivým portům i s nastavením již zmíněných web extensions.

Jak asi každý zkušený správce tuší, nelze se vždy na obdobné nástroje plně spolehnout, zvláště pak proto, že nenabízejí všechny možné dostupné kombinace nastavení a nejvhodnější je stejně nastavit vše osobně. Právě při snaze zmenšit attack surface webového serveru, je vhodné nejen povolit pouze ty web extensions, které hodláme používat, ale dobrým trikem je přiřadit soubory HTML knihovně aspnet_isapi.dll . Toto nastavení vlastně zajistí, že soubory HTML budou posílány ke zpracování knihovně aspnet_isapi.dll a mohou proto obsahovat programový kód. Nesporná výhoda pak tkví v tom, že návštěvník webových stránek na první pohled nepozná, že stránky obsahují dynamicky zpracovávaný programový kód. Samozřejmě z určitých znaků, jako jsou např. formuláře, lze tento fakt odvodit, ale nelze již zjistit, jaký dynamický obsah stránky obsahují (ASP.NET, ASP, PHP, JSP apod.) To dává serveru určitou ochranu, jelikož potencionální útočník nemá přehled o použitém skriptování a případný útok je tedy obtížnější, než když soubory končí koncovkou aspx, asp, php, jsp apod. Ukázka mapování HTML souborů na knihovnu aspnet_isapi.dll je v příloze v obrázku č.3.

1.5. Zabezpečená komunikace šifrováním (SSL, Certifikáty)

Zabezpečená komunikace je jistě nejvhodnější volbou, pokud přenášíme data, u nichž nechceme, aby je viděl kdokoliv jiný než vybraný uživatel. Data, která si klientský prohlížeč vyměňuje se serverem mohou být za určitých okolností odchycena nepovolanou osobou a zneužita. Tomu je zapotřebí se bránit.

Ve většině případů je sice požadován anonymní přístup k webovému serveru nebo lze případné odepření anonymního přístupu provést (zrušit řízení přístupu uživatelským účtem IUSR_COMPUTERNAME), ale v takovém případě pak k serveru mohou přistupovat jen vybraní uživatelé operačního systému na kterém www server běží nebo členové Active Directory. To je výhodné v případě řízení přístupu k vnitropodnikovému portálu, avšak ne v případě, když požadujeme, aby náš server byl dostupný komukoliv, a zároveň byla komunikace bezpečná a možnost zneužití odchycených dat byla neutralizována nebo nechceme všechny uživatele zavádět do služby Active Directory (což je samozřejmě zbytečné, když mají mít uživatelé přístup jen k aplikaci běžící na serveru a nikoliv k dalším souborům nebo jiným prostředkům). V tomto případě je namístě využít zabezpečení komunikace pomocí šifrovaného spojení za použití certifikátu. Taktéž je toto zabezpečení vhodné pro přenášení dokumentů, a to jak ze strany serveru ke klientovi, tak i opačně. Chceme mít zkrátka jistotu, že data, která odeslal server klientovi, nebudou po cestě změněna a data, která posílá klient serveru, budou opravdu ta, která odeslal.

1.5.1. SSL a digitální certifikáty

„Internetová informační služba (IIS) poskytuje prostřednictvím protokolu SSL (Secure Sockets Layer) dostatečnou úroveň zabezpečení. Zabezpečení se dosahuje prostřednictvím digitálních certifikátů.“

IIS disponuje třemi typy certifikátů:

  • Certifikát serveru - Zajišťuje šifrování přenášených dat (protokolem SSL) a identifikaci serveru. Klient tak má jistotu, že webový server je skutečně tím, za kterého se vydává.
  • Klientské certifikáty - Identifikují klienta, takže server má jistotu, že klientský počítač je skutečně tím, za kterého se vydává. Dále zajišťují bezpečnější způsob ověřování než Základní ověřování. Klientské certifikáty nezajišťují šifrování dat.
  • Certifikáty pro podpis kódu - Umožňují digitálně „podepsat“ svou aplikaci digitálním kódem ID na základě obsahu dané aplikace. Pokud se v aplikaci po podepsání cokoliv změní, nebude již ID kód odpovídat a uživatel bude na tento fakt upozorněn. (To ovšem platí pro klasické stand-alone aplikace nebo knihovny DLL, které lze takto podepsat. Kód ASP.NET je většinou ve formě textu a nelze pro něj tento způsob podpisu použít. Zkompilovaný kód ASP.NET do knihovny DLL již takto podepsat lze.)

Digitální certifikáty jsou šifrovány pomocí klíčů. Tyto klíče lze chápat jako jakási hesla, která jsou určena k šifrování prostého textu do textu zašifrovaného. Šifra nebo šifrování je pak matematickým algoritmem, který tuto transformaci provádí. Pro šifrování se používají dvě metody, které lze využívat samostatně nebo také dohromady.

  • Šifrování pomocí symetrického klíče - K šifrování i dešifrování se používá stejného klíče. Klient, který má zprávu rozšifrovat musí tedy vlastnit stejný klíč jako server nebo jiný prostředek, který zprávu zašifroval. Nespornou výhodou této metody je její rychlost a jednoduchost a určitý stupeň zabezpečení (klient musí vlastnit daný klíč, aby mohl zprávu rozšifrovat), ovšem na druhé straně je jasné, že pokud se zmocní klíče nepovolaná osoba, bude moci zprávy nejen rozšifrovávat a číst, ale i šifrovat a sama se vydávat za odesílatele.
  • Šifrování pomocí asymetrického klíče - "IIS umí vybrat mezi dvěma způsoby asymetrického šifrování. DH (Diffie-Hellman) a RSA (pojmenovaný po tvůrcích Ronu Rivestovi, Adi Shamirovi a Leonardu Adlemanovi). Při těchto způsobech šifrování je využíváno dvou klíčů. Klíče veřejného a klíče soukromého. Klíč veřejný je volně šiřitelný, avšak k dešifrování zprávy je nutné vlastnit klíč soukromý. „Jedinou osobou, která soukromý klíč vlastní je jeho majitel, jenž tak jako jediná osoba může data dešifrovat. Dokonce ani osoba, která data zašifrovala, je nemůže bez soukromého klíče dešifrovat."

Při srovnání šifrování symetrickým klíčem a asymetrickým klíčem je zřejmé, že šifrování metodou asymetrického klíče je náročnější na prostředky počítače a není tak zcela efektivní. Pokud toto šifrování použijeme v případě přihlášení k webovému serveru a dále již s uživatelem pracujeme jako s autentifikovaným, je tento způsob využitelný. Pokud bychom veškerou komunikaci mezi klientem a serverem chránili asymetrickou šifrou, byla by tato komunikace pomalá. Pokud ovšem použijeme asymetrické šifry pro výměnu symetrického klíče mezi klientem a serverem a poté budeme používat šifrování symetrické, nároky na prostředky se sníží při zachování dostatečně vysoké úrovně zabezpečení. A to je právě podstata protokolu SSL.

Síla šifrování závisí na délce a typu použitého šifrování. Zprávy vytvořené pomocí 128bitového klíče jsou 3x1026 odolnější proti prolomení než zprávy vytvořené pomocí 40bitového klíče. Zajímavostí může být zmínka o zákazu USA šířit za hranice technologie s šifrováním vyšším než se 128bitovým klíčem. Ještě donedávna vláda Spojených Států Amerických dovolovala vývoz technologií jen se 40bitovým klíčem. „Z bezpečnostních důvodů spoléhala na fakt, že bude moci dešifrovat zachycená zašifrovaná data. Pomocí 128bitových klíčů je však šifrování mnohem obtížnější.“ Tím je rozuměno, že statistická pravděpodobnost prolomení kódu je menší.

1.5.2. Digitální podpisy

Poté, co jsou data zašifrována, je potřeba znát způsob, jakým lze zjistit, že pocházejí od určitého odesílatele. Řešením jsou digitální podpisy. Technologie, na které jsou digitální podpisy založeny, vychází z jednosměrné transformace algoritmem hash a infrastruktury asymetrického šifrování.

Šifrování jednosměrnou transformací algoritmem hash je založeno na principu, že z textu je pomocí zmíněného algoritmu vytvořen výtah, který je pro daný text jedinečný. Pokud je v textu změněn jen jediný znak nebo přidána jediná mezera, nebude už výtah stejný jako před provedením změny. Šifrování pomocí algoritmu hash je označováno jako jednosměrné, protože není možné z výtahu zpětně sestavit původní text. Nejběžnějšími algoritmy hash jsou MD5 (Message Digest Algorithm) a algoritmus SHA (Secure Hash Algorithm).

Pokud soukromým klíčem zašifrujeme hash hodnotu vytvořenou z textu, který chceme chránit, vytvoříme tak digitální podpis. U příjemce je pak zašifrovaná hash hodnota rozšifrována pomocí veřejného klíče a porovnána s hash hodnotou z předávaného textu. Pokud se tento otisk shoduje s rozšifrovaným otiskem, je ověřen odesílatel dokumentu i pravost dokumentu samotného.

A jak získáme veřejný a soukromý klíč? Certifikační autorita vydá subjektu po ověření jeho pravosti certifikát, jehož součástí je sada dvou klíčů, veřejného a soukromého. Certifikát s veřejným klíčem certifikační autorita zveřejní a soukromý klíč nám předá uložený například na čipové kartě nebo v souboru. Veřejný klíč je podepsán soukromým klíčem certifikační autority, čímž je považován za důvěryhodný (je-li pro nás certifikační autorita důvěryhodnou).

Důvěryhodnost certifikátu si pak klient ověřuje u instalovaných důvěryhodných certifikačních autorit v počítači. Vyžádá si od serveru certifikát k digitálnímu podpisu a ten se bude snažit ověřit. V počítači může být uloženo více různých certifikátů, které jsou považovány důvěryhodné, stejně tak jako více certifikačních autorit považovaných za důvěryhodné. Pokud klientský počítač nenalezne přijatý certifikát mezi důvěryhodnými a ani se mu nepodaří ověřit pravost u některé instalované důvěryhodné certifikační autority, upozorní na nemožnost ověření pravosti certifikátu a neměli bychom pak tento certifikát přijímat. A právě přijetí certifikátu je nutnou podmínkou pro zahájení komunikace šifrovaným spojením SSL.

1.5.3. Průběh celé komunikace pomocí protokolu SSL

Ověřování a navázání spojení je sjednoceno do jedné metody, tzv. handshake (vyjednávání).

  1. "Klient odešle serveru svou verzi protokolu SSL, nastavení šifer, náhodně vygenerovaná data a ostatní informace, které server potřebuje pro komunikaci s klientem, jenž využívá protokol SSL.
  2. Server odešle klientovi svou verzi protokolu SSL, nastavení šifer, náhodně vygenerovaná data a ostatní informace, které klient potřebuje ke komunikaci se serverem prostřednictvím protokolu SSL. Server současně odešle svůj certifikát.
  3. Klient ověří server, jak je popsáno v části Certifikační úřady a vztahy důvěryhodnosti.
  4. Z informací, které má klient k dispozici, vytvoří pro tuto relaci řetězec (premas¬ter secret), zašifruje jej veřejným klíčem serveru a odešle.
  5. Pomocí řetězce premaster secret provede server řadu kroků a vytvoří řetězec master secret.
  6. Klient a server použijí řetězec master secret k vytvoření klíčů relace.
  7. Klient odešle serveru informaci, že další zpráva bude zašifrována klíčem relace.
  8. Klient odešle serveru zašifrovanou zprávu oznamující, že je dokončena metoda handshake (vyjednávání).
  9. Server odešle klientovi informaci, že následující zpráva bude zašifrována klíčem relace.
  10. Server odešle klientovi zašifrovanou zprávu oznamující, že je dokončena meto¬da handshake (vyjednávání).
  11. Proces je nyní dokončen. Klient a server použijí klíče relace k šifrování a dešifrování dat (symetrické šifrování)."

A co klient? Jakým způsobem ověříme pravost klienta přistupujícího k webovému serveru? I na něj lze aplikovat metodiku certifikátů a certifikačních autorit. Certifikační autorita může vystavit jakýkoliv certifikát pro jakýkoliv počítač nebo jakéhokoliv uživatele. Ve chvíli, kdy mají uživatelé u sebe instalovaný potvrzený certifikát, mohou se na serveru ověřovat bez použití hesel.

  1. "Klient odešle serveru svou verzi protokolu SLL, nastavení šifer, náhodně vygenerovaná data a ostatní informace, které server potřebuje pro komunikaci s klientem, jenž využívá protokol SSL.
  2. Server odešle klientovi svou verzi protokolu SSL, nastavení šifer, náhodně vygenerovaná data a ostatní informace, které klient potřebuje ke komunikaci se serverem prostřednictvím protokolu SSL. Server současně odešle svůj certifikát.
  3. Server si vyžádá certifikát klienta.
  4. Klient ověří server, jak je popsáno výše.
  5. Z informací, které má klient k dispozici, vytvoří pro tuto relaci řetězec (premas¬ter secret), zašifruje jej veřejným klíčem serveru a odešle.
  6. Klient opět pomocí dosud shromážděných informací podepíše část dat. Ta odešle spolu s řetězcem premaster secret a svým certifikátem serveru.
  7. Server se pokusí ověřit uživatele pomocí stejných kroků, které provedl uživatel k ověření serveru.
  8. Pomocí řetězce premaster secret provede server řadu kroků a vytvoří řetězec master secret.
  9. Klient a server použijí řetězec master secret k vytvoření klíčů relace.
  10. Klient odešle serveru informaci, že další zpráva bude zašifrována klíčem relace.
  11. Klient odešle serveru zašifrovanou zprávu oznamující, že je dokončena metoda handshake (vyjednávání).
  12. Server odešle klientovi informaci, že následující zpráva bude zašifrována klíčem relace.
  13. Server odešle klientovi zašifrovanou zprávu oznamující, že je dokončena meto¬da handshake (vyjednávání).
  14. Proces je nyní dokončen. Klient a server použijí klíče relace k šifrování a dešifrování dat (symetrické šifrování)."

Tyto postupy ukazují, jaký způsobem je navazováno a prováděno šifrované spojení mezi webovým serverem a klientským počítačem. Ale jak získáme certifikaci pro náš www server? Existují v podstatě dvě možnosti. Buď provozujeme na našem serveru vlastní certifikační autoritu a pak ji můžeme požádat o vydání certifikátu a nebo požádáme o vydání certifikátu komerční certifikační autoritu, která ho pro nás vystaví. Rozdíl je ale v tom, že klienti přistupující na náš www server budou nejspíš více důvěřovat komerčnímu certifikátu než certifikátu vystavenému vlastními prostředky. Český právní řád rozlišuje několik typů poskytovatelů certifikačních služeb v závislosti na jejich důvěryhodnosti a především v závislosti na jejich kontrole ze strany státu.

  • "Poskytovatelem certifikačních služeb je fyzická osoba, právnická osoba nebo organizační složka státu, která vydává certifikáty a vede jejich evidenci, případně poskytuje další služby spojené s elektronickými podpisy.
  • Kvalifikovaným poskytovatelem certifikačních služeb je poskytovatel certifikačních služeb, který vydává kvalifikované certifikáty nebo kvalifikované systémové certifikáty nebo kvalifikovaná časová razítka nebo prostředky pro bezpečné vytváření elektronických podpisů (dále jen "kvalifikované certifikační služby") a splnil ohlašovací povinnost podle § 6.
  • Akreditovaným poskytovatelem certifikačních služeb je poskytovatel certifikačních služeb, jemuž byla udělena akreditace podle tohoto zákona."

Je tedy zřejmé, že vydávání certifikátů může provádět téměř kdokoliv, ale nejvyšší stupeň důvěryhodnosti poskytují jen akreditovaní poskytovatelé certifikačních služeb. Certifikáty vydané těmito poskytovateli jsou také jako jediné uznávány při tvorbě elektronických podpisů pro komunikaci se státní správou. V současné době jsou v ČR jen tři akreditovaní poskytovatelé a to I.CA, PostSignum QCA České Pošty a eIdentity.

1.6. Konfigurace aplikací ASP.NET

Aplikace ASP.NET jsou konfigurovány pomocí souboru web.config. Konfigurace spočívá v nastavování mnoha různých možností, jako je způsob zobrazení stránek, způsob jejich kompilace, řízení přístupu k jednotlivým částem aplikace, nastavení stavu seance apod. Soubor web.config obsahuje XML značky a je umístěn v kořenovém adresáři každé aplikace ASP.NET. Není však nutné, aby ASP.NET aplikace obsahovala jen jediný soubor web.config. Tento soubor může být umístěn i ve více adresářích a podadresářích celé aplikace. ASP.NET využívá systému hierarchické konfigurace, což v praxi znamená, že informace o konfiguraci jsou načítány stejně jako systém adresářů aplikace. Web.config v nadřazených adresářích ovlivní konfiguraci i podřazených adresářů a jejich obsahu, ale pokud se v některém podřazeném adresáři bude vyskytovat nový soubor s konfigurací, bude aplikována konfigurace v něm uložená. „Ve skutečnosti všechny adresáře dědí konfiguraci ze souboru machine.config umístěného v adresáři Windows\Microsoft.NET\\CONFIG.“ Pokud tedy není některé nastavení ošetřeno v souboru web.config naší ASP.NET aplikace, použije se nastavení z machine.config. Nastavení v souboru machine.config se týká všech ASP.NET aplikací na daném serveru.

Pro účely zabezpečení aplikace je důležité nastavení autentizace, autorizace, impersonalizace, zobrazení chyb a nastavení seance, tedy sekce souboru web.config označené XML značkami , , , a .

1.6.1. Autentizace v praxi

Začneme s nastavováním autentizace. Následující kód ukazuje nastavení aplikace ASP.NET se zapnutou autentizací.

<configuration> <system.web> <authentication mode=”Režim”></authentication> </system.web> </configuration>

V ASP.NET aplikacích můžeme použít tři různé autentizační režimy. Jsou to režimy Windows, Forms a Passport. U režimů Windows a Passport spolupracuje IIS s operačním systémem. Režim Windows je založen na uživatelských účtech operačního systému, režim Passport je založen na placené službě Microsoft .NET Passport. Oba tyto režimy již byly popsány v kapitole Nastavení způsobů ověřování včetně forem Basic, Integrované ověřování Windows i Ověřování Digest. Autentizační režim Forms nabízí zajištění ověřování přístupu ve vlastní aplikaci ASP.NET. „Jeho výhodou je, že celý proces ověřování uživatelů, přistupujících k vaší aplikaci, můžete lépe a snáze řídit. Například databázi identifikačních údajů uživatelů můžete vytvořit v nějaké databázi či souboru ve formátu XML, nemusíte používat data zadané přímo do operačního systému řady Windows.“ Pokud použijeme tento způsob autentizace, bude uživatel, který požaduje zabezpečenou stránku, přesměrován na URL adresu s formulářem pro přihlášení. Přihlašovací postup pak je plně v kompetenci ASP.NET aplikace a je tedy pouze na nás, jakým způsobem jej ošetříme. Následuje ukázka části souboru web.config s nastavením autentizace Forms a kód stránky s přihlašovacím formulářem.

<configuration> <system.web> <authentication mode=”Forms”> <forms name=”AuthCookie” loginUrl=”login.aspx” /> </authentication> </system.web> </configuration> <%@ Page Language="C#" %> <script runat="server"> void Login(Object obj, EventArgs e) { if(tbUserName.Text="jan.novak" and ¬tbPassword.Text="heslo") { FormsAuthentication.SetAuthCookie("jan.novak",false); Response.Redirect("tajna_stranka.aspx"); } else { lblMessage.Text="Uživatelské jméno a heslo nejsou správné!”; } } </script> <html> <body> Zadejte své uživatelské jméno a heslo: <form runat="server"> <asp:Label id="lblMessage" runat="server" /> Uživatelské jméno:<asp:Textbox id="tbUserName" runat="server" /><br /> Heslo:<asp:Textbox id="tbPassword" TextMode="password" runat="server" /><p> <asp:Button id="Submit" runat="server" OnClick="Login" Text="Přihlásit" /> </p> </form> </body> </html>

Tento kód nám zajistí, že pokud bude zadáno uživatelské jméno jan.novak a heslo heslo bude uživatel přesměrován na stránku tajna_stranka.aspx a bude mu založeno cookie s názvem AuthCookie a hodnotou jan.novak. Hodnota false při zakládání cookie znamená, že toto cookie bude uchováno jen do ukončení prohlížeče. Pokud uživatel bude požadovat přístup v budoucnu, bude se muset znovu přihlásit. Hodnota true by pak znamenala trvalé přihlášení i kdykoliv v budoucnu.

Jinou možností je využití pevně stanoveného přihlašovacího jména a hesla, které jsou nastaveny v souboru web.config. Zápis pak vypadá následovně:

<configuration> <system.web> <authentication mode=”Forms”> <forms name=”AuthCookie” loginUrl=”login.aspx” /> <credentials passwordFormat=”Clear”> <user name=”jan.novak” password=”heslo” /> </credentials> </forms> </authentication> </system.web> </configuration>

A kód ASPX stránky pak takto (kód HTML zůstává stejný jako v předešlé ukázce):

<%@ Page Language="C#" %> <script runat="server"> void Login(Object obj, EventArgs e) { if(FormsAuthentication.Authenticate(tbUserName.Text, tbPassword.Text)) { FormsAuthentication.SetAuthCookie("jan.novak",false); Response.Redirect("tajna_stranka.aspx"); } else { lblMessage.Text="Uživatelské jméno a heslo nejsou správné!"; } } </script>

Všimněme si přidané značky credentials a atributu passwordFormat. Ten může nabývat hodnot Clear, MD5 nebo SHA a určuje, jaký způsob šifrování bude použit pro zasílání hesla. Hodnota Clear znamená zasílání v podobě čistého textu, druhé dvě hodnoty pak využití již zmíněných šifrovacích algoritmů.

Objekt FormsAuthentication obsahuje také metodu RedirectFromLoginPage(hodnota_cookie,doba_udržení_cookie), pomocí které lze náš kód ještě zdokonalit. Ta nám totiž nabízí možnost přesměrovat po přihlášení na původně požadovanou stránku. „Pokud dotazovací řetězec žádnou stránku neobsahuje, je uživatel přesměrován na stranu default.aspx umístěnou v kořenovém adresáři.“

1.6.2. Autorizace v praxi

V ASP.NET můžeme s autorizací pracovat dvěma různými způsoby. „Může spoléhat na operační systém řady Windows NT/2000/XP a na základě jejich nastavení určit, se kterými zdroji může daný ověřený uživatel pracovat. Tento způsob se nazývá souborovou autorizací (file authorization). Druhý způsob pak spočívá v tom, že celý proces autorizace bude spoléhat na URL-adresu požadovaného zdroje. V tomto případě se pak jedná o URL-autorizaci (URL-authorization).“ Jak již bylo několikrát zmíněno, operační systém Windows pracuje s mnoha uživatelskými účty a administrátor může přidávat další, včetně nastavení prostředků, ke kterým má daný uživatelský účet přístup (za podmínky souborového systému NTFS). Při souborové autorizaci jsou při přihlášení uživatele nalezeny v operačním systému povolené prostředky k danému uživatelskému účtu a je k nim umožněn přístup. Celý proces pracuje na principu impersonalizace (zosobnění) vysvětleného dříve.

URL-autorizace je obecnějším způsobem definování načítání přístupových oprávnění a zahrnuje také způsoby přístupu dle http protokolu. Nejčastěji používané metody HTTP protokolu jsou GET a POST. A právě rozdělení uživatelů a povolení či zakázání některé z těchto metod lze zajistit URL-autorizací. Podívejme se nejprve na určení celkového přístupu pomocí URL-autorizace. Následující kód souboru web.config zajišťuje řízení přístupu podle uživatelských účtů Windows.

<authorization> <allow users=”jan.novak” /> <deny users=”petr.novak” /> </authorization>

Povolení (allow) a odepření (deny) přístupu lze kromě jednotlivých uživatelů aplikovat i na celé skupiny. K tomu postačí místo konkrétního uživatele uvést název skupiny uživatelů operačního systému Windows. Taktéž lze využívat zástupných znaků pro definování jiných skupin uživatelů. Zástupný znak ? vyjadřuje jakéhokoli uživatele, který nebyl ověřen, čili se vlastně jedná o anonymního uživatele, znak * pak značí každého přistupujícího uživatele. Pokud chceme řídit přístup jednotlivých metod protokolu HTTP, rozšíříme XML značku a o klíčové slovo verb. Obsah souboru web.config pak může vypadat takto:

<authorization> <allow verb=”GET” users=”*” /> <allow verb=”POST” users=”petr.novak” /> </authorization>

Toto řešení zajistí, že všichni uživatelé mohou získávat stránky z www serveru, ale odesílat informace na server může jen uživatel jan.novak. Různými kombinacemi pak lze dosáhnout různých požadavků. V ASP.NET aplikaci, jak již bylo řečeno, je sdílení nastavení v souboru web.config předáváno hierarchicky dál i do podadresářů adresáře, který soubor web.config obsahuje. Pokud tedy budeme požadovat různá řízení přístupu v různých podadresářích, bude tato metoda neefektivní, vzhledem k nutnosti spravovat velké množství samostatných souborů web.config pro jednotlivé adresáře s různým řízením přístupu. Východiskem je ale přidání XML značky , která definuje konkrétní adresář (a to relativní cestou), jehož se nastavení týká. Celý soubor web.config pak má následující podobu:

<configuration> <system.web> <location path=”\administrace”> <authorization> <allow users=”petr.novak” /> </authorization> </location> <location path=”\.”> <authorization> <allow users=”*” /> </authorization> </location> </system.web> </configuration>

Kód nám zajistí, že do adresáře administrace může vstoupit jen uživatel jan.novak, zatímco do aktuálního může kterýkoliv uživatel. „Všimněme si, že návěští location jsou umístěna vně návěští authorization. Častou chybou začátečníků je, že vkládají návěští location právě dovnitř návěští authorization. Nezapomeňme také, že každý adresář, k němuž chceme specifikovat nějaká přístupová oprávnění, potřebuje další návěští location.“

1.6.3. Impersonalizace v praxi

Princip impersonalizace byl již popsán v úvodu. Nyní se podíváme na to, jak tuto metodu využít v praxi. Opět se bude jednat o nastavení v souboru web.config.

<configuration> <system.web> <identity impersonate=”true” username=”jan.novak” password=”heslo” /> </system.web> </configuration>

Průběh procesu imperonalizace je ukázán na obrázku č.4 v příloze.

Proces zosobnění se však v praxi příliš nevyužívá a to nejen díky tomu, že v sobě zahrnuje jak autentizaci, tak autorizaci a nelze jej detailně konfigurovat, ale především díky tomu, že k řízení přístupu je nutné používat nastavení operačního systému, čemuž se snaží většina vývojářů vyhnout. Dle mého názoru je nejvhodnějším způsobem kombinace autentizace pomocí Forms a aplikačního kódu, který zajišťuje autorizaci na základě oprávnění uložených v XML souboru či relační databázi. Uživatel je autentizován, je mu založeno autentizační cookie a podle něj je pak řízen přístup v celé aplikaci. Je to ovšem věc názoru a někdo raději využije možnost URL-autorizace či impersonalizace. Každá z metod má své výhody i nevýhody, je však nutno zmínit důležitou poučku pro volbu autentizace a autorizace :

VŽDY NIKDY
Vždy používejte proces zosobnění, jestliže nechcete psát kód ASP.NET. Pokud použijete tento proces, budete muset nastavit pouze autentizaci pomocí serveru IIS a upravit seznamy řízení přístupu. Nikdy nepoužívejte proces zosobnění, chcete-li si vytvořit svůj vlastní systém autorizace.

Tabulka 2, Poučka pro autentizaci a autorizaci

1.7. Ochrana aplikace na úrovni aplikačního kódu

V případě, že se rozhodneme si vytvořit svůj vlastní systému autentizace či autorizace v plném měřítku, nastavíme režim autentizace na hodnotu Windows, případně nemusíme nastavovat nic, jelikož každý soubor web.config sdílí nastavení se souborem machine.config (jak je zmíněno v předešlé kapitole). Toto standardní nastavení v sobě zahrnuje právě autentizační režim Windows bez jakýchkoliv nároků na uživatelské jméno a heslo. Uživatel přistupuje pod účtem IUSR_COMPUTERNAME ze skupiny Guests. Jako takový má volný přístup v celé aplikaci, pokud mu někde nebude aplikačním kódem odepřen. Jelikož nám ale ASP.NET nabízí velice snadný způsob autentizace pomocí Forms, budeme na aplikační úrovni řešit pouze porovnávání uživatelských jmen a hesel a autorizaci do jednotlivých sekcí aplikace.

Následující kapitoly se zabývají různými druhy ochrany částí aplikace, které by mohly být ať záměrně či neúmyslně podvrženými údaji poškozeny. Je vždy nutno brát v úvahu, že jakmile přijímáme od uživatele nějaká data, musíme tato data považovat za potencionálně nebezpečná a než dovolíme naší aplikaci s nimi pracovat, je nutno je důkladně prověřit. Taktéž musíme počítat s tím, že jakákoliv data, která aplikace ukládá na klientský počítač, mohou být uživatelem záměrně změněna nebo odstraněna. Proto se dále budeme zabývat nejen způsoby ochrany částí aplikace, ale i ochranou dat, které aplikace využívá a která by mohla být potencionálně napadena. Oblasti, které patří mezi nejčastěji zneužívané patří session cookies, data předávaná SQL příkazům (tzv. SQL injection), script injection a cross site scripting. Nejprve si projdeme nejčastěji používané způsoby ochrany vstupů předávaných do aplikace a poté si ukážeme, jak se bránit provedení změn v session cookies. Namístě je také upozornit, že je velmi důležité zakázat výpis podrobných chybových hlášení, která by mohla případného útočníka přivést na stopu způsobu řešení ochrany aplikace. Výpis podrobných chybových hlášení vypneme v souboru web.config. Výpis by měl být implicitně zakázán, ale jelikož se jedná o velice důležité nastavení, je lepší jej takto znovu vynutit.

<customErrors mode=”Mód” defaultRedirect=”chybova_stranka.aspx” />

Volitelný atribut defaultRedirect odkazuje na stránku, která má být zobrazena při výskytu chyby. Povinný atribut Mód může nabývat hodnot:

  • On Detaily chyb nejsou zobrazovány vůbec. Pokud je specifikován atribut defaultRedirect, je použita vždy tato hodnota.
  • Off Každý může vidět detaily chyb vzniklých při zpracování stránky.
  • RemoteOnly Detaily mohou vidět jen lokální uživatelé. Ostatní jsou odkázáni na chybovou stránku. Toto nastavení je vhodné použít zvláště během dolaďování aplikace „za pochodu“, tedy pokud je již spuštěna a mohou k ní přistupovat venkovní uživatelé. Vývojář vidí chyby, ale případný uživatel nikoliv.

1.7.1. Script Injection

Podle mého názoru je nejnebezpečnější ta oblast, kdy aplikace během svého chodu spouští nějaké externí programy či dokonce využívá příkazového řádku. Nejvhodnějším zabezpečením je samozřejmě vyhnutí se takovým akcím v aplikaci. Pokud to jde, měla by si naše aplikace zabezpečovat veškeré činnosti sama. ASP.NET aplikace provozované na platformě .NET Framework od společnosti Microsoft mají výhodu, že mohou plně využívat všech možností jako operační systém. Aplikace ASP.NET nejsou jen skriptované stránky, jedná se o plně objektově orientovaný program. A .NET Framework nabízí nepřeberné množství objektů pro práci s nejrůznějšími typy dat od XML, přes Office dokumenty, databáze, atd. I když není aplikace či formát dat, s kterým chceme pracovat v .NET Framework přímo podporován, je z bezpečnostního hlediska mnohem lepší si objekty pro práci s nimi sám vytvářet, než spouštět externí programy a předávat jim parametry (například názvy souborů pro konverzi do jiných formátů). V takovém případě pak existuje riziko, že uživatelem záměrně či omylem podvržené informace mohou způsobit neočekávané chování aplikace a aplikace pak může být nabourána nebo může uživateli poskytovat informace, které bychom mu za normálních okolností v žádném případě sdělit nechtěli.

Script injection spočívá ve snaze uživatele přistupujícího k aplikaci, vkládat do zpracovávaných formulářů takový kód (obvykle javascript v kombinaci s HTML), který, pokud je následně zobrazen jiným uživatelem, na něj vyzradí nějaké informace či ho nevhodně obtěžuje. „Oním negativním efektem může být ledacos, obvykle se ale jedná o prosté obtěžování uživatele (otevíráním pop-up oken a podobně), získání autentizačních údajů (jsou-li uloženy v cookies, URL a podobně) či čirý vandalismus.“ Naším úkolem je tedy odstranit z textu předávaného uživatelem veškeré potencionálně nebezpečné konstrukce.

U starších internetových aplikací na platformě ASP byl tento úkol poněkud ztížen tím, že nedisponovaly implementovanými knihovnami, jako je tomu u ASP.NET a veškeré funkce pro kontrolu kódu nebo jeho převodu musely být celé napsány ručně. Oproti tomu ASP.NET nabízí několik možností, jak se script injection vyhnout. Samozřejmě je tu opět možnost si vše ošetřit sám, ale i u této varianty se dostane programátorovi mnohé pomoci. Namísto ošetřování obsahu textu metodou InStr() , je možné pohodlně použít regulárních výrazů a veškeré potencionálně nebezpečné výrazy blokovat nebo v nich měnit ty části, které by mohly způsobovat problémy. Zatímco v ASP bylo v podstatě jediným řešení testovat přítomnost určité skupiny znaků v řetězci zadaném uživatelem, v ASP.NET lze díky plné podpoře programovacích jazyků a s možností využití knihoven .NET Frameworku postupovat podstatně obratněji. V neposlední řadě je tedy potřeba zmínit objekt .NET Framework, s kterým je celá tato činnost doslova hračkou. Jedná se o objekt server a především o jeho metodu HtmlEncode(). ASP.NET od verze 1.1 obsahuje vestavěný obranný mechanismus proti script injection. Jde o systém tzv. validace požadavku (ValidateRequest), který spočívá v tom, že jakákoliv HTML značka zadaná do formuláře a předávaná aplikaci přes HTTP protokol metodou POST vyvolá chybu aplikace. Aplikace ji zkrátka nepřijme. Co kdybychom ale výslovně chtěli přijímat HTML značky od uživatele? Ačkoliv je tato validace standardně zapnuta, lze ji jako mnoho dalších voleb vypnout – buď nastavením v každém jednotlivém souboru aplikace nebo globálně v souboru (souborech) web.config. Co pak ale s možností, že uživatel zadá místo očekávaných HTML značek nějaký zákeřný javascript? Odpovědí je právě Server.HtmlEncode() - tato metoda převede jakýkoliv HTML označkovaný text na text prostý a všechny scripty a jiné vykonavatelné kódy se tak stanou nefunkčními.

Následuje ukázka nastavení vypnutého RequestValidation a části kódu aplikace pro ošetření vstupu z formuláře proti script injection.

Pro každý jednotlivý soubor:

<%@ Page Language="C#" validateRequest="false" %>

Nebo globálně ve web.config:

<configuration> <system.web> <pages validateRequest="false" /> </system.web> </configuration>

A ještě kód aplikace. Proměnná CistyText obsahuje již zkontrolovaný vstup a lze s jejím obsahem beze strachu pracovat dále.

<script runat=”server”> Public Static String CistyText; Public void button1_Click(Object Sender, EventArgs e) { CistyText = Server.HtmlEncode(TextBox1.Text); } </script> <form runat=”server”> <asp:TextBox id=”TextBox1” runat=”server” /> <asp:Botton id=”Button1” runat=”server” /> </form>

Zajímavostí je, že právě v ASP.NET 1.1 obsahoval automatický RequestValidation bezpečností díru. Pokud byl mezi znak < a HTML tag vložen znak NULL (ASCI 0), prohlížeč jej sice ignoroval a HTML tag vykonal, ale ASP.NET jej nepovažovalo za HTML tag a neošetřilo ho převodem na čistý text. Tato chyba byla sice již červnu roku 2003 opravena vydanou záplatou, ale můžeme se z toho poučit tím, že není radno vždy spoléhat na implementovanou podporu vývoje. Je vhodné si najít způsob, který bude nejen schopen odolat vnějšímu nepříteli, ale bude i trvale funkční bez skrytých nedostatků. Vždyť jen jediné opomenutí nás může stát mnoho. Příkladem toho může být tzv. cross site scripting a kradení obsahu session cookies .

1.7.2. Cross Site Scripting

Tato metoda útoku dává útočníkovi možnost odhalit údaje, které chceme schovat nejen před neoprávněným uživatelem, ale ani není vhodné, aby je znal uživatel oprávněný. Pokud jsou například v session cookies uchovávány údaje vztahující se k přihlášenému uživateli nebo údaje, které aplikace používá k přiřazení obsahu nákupního košíku k uživateli, neměl by je vidět ani on sám. Forma uchovávání ID uživatele či jiných informací by neměla být prozrazena. Způsoby, kterými lze získat identitu uloženou v session, nazýváme session-stealing.

Pokaždé když je v ASP.NET založeno session cookie, to znamená pokaždé, když aplikujeme kód session[nazev]=hodnota je v prohlížeči klienta založeno session cookie. Daná hodnota však není nikdy přímo viditelná. Princip, na kterém tato metoda funguje, je o něco složitější. Název i hodnota cookie jsou ukládány na serveru spolu s ID daného session. U klienta je pak uložena jen šifrovaná podoba ID, která ho provazuje s hodnotami uloženými na serveru. Celé session cookie se skládá vždy ze stejného identifikátoru asp.net_sessionid= a šifrované hodnoty ID. Může mít třeba následující podobu:

asp.net_sessionid=jhmbobkcbinehlpkjhopabbe

Nelze tedy přesně zjistit, jaká data si server u nás ukládá. Jediné, co lze zjistit, je výše uvedený řetězec. Ale i zjištění daného řetězce má za následek, že lze session cookie podvrhnout a zneužít. Podaří-li se nám kupříkladu zjistit session ID od nějakého uživatele, který je na určitém serveru aktuálně přihlášen, můžeme se za něj vydávat a server nepozná rozdíl. Z klientského prohlížeče hackera přijde session ID, které server aktuálně zná a přiřadí k němu u sebe uložené hodnoty – a nabourání je dokončené. A jak jej může hacker získat? Kupříkladu lze využít objekty JavaScriptu, které s cookies a dalšími proměnnými pracují. Jsou to třeba objekty document.cookie či document.referrer, který získá URL stránky, ze které návštěvník přišel. Jak je známo, v URL stringu bývají předávány různé informace pro aplikaci, i když ty opravdu důležité, jejichž vyzrazení chceme zabránit, by zde rozhodně být neměly. Někteří vývojáři například přidávají do URL stringu session ID, což je samozřejmě špatně. Jak jsem již zmínil, lze jej lehce získat pomocí objektu document.referrer. A jak tedy session ID nejlépe chránit? I zde existuje mnoho způsobů a různí vývojáři používají různé techniky. Osobně jsem zastáncem poměrně snadného způsobu publikovaného přímo společností Microsoft . Dále se pokusím tuto metodu objasnit.

1.7.3. Ochrana session ID

Celý postup je velmi jednoduchý a zakládá se na principu přidávání šifrovaných informací k session ID, které si pak server při každém požadavku ověřuje. Pokud se nad tímto způsobem zamyslíme, je zřejmé, že se jedná o symetrickou šifru s několika soukromými klíči . Na obrázku č.5 v příloze je grafické znázornění postupu při využití této metody. Přidaný modul SecureSessionModule nám zabezpečí přidávání a odebírání MAC identifikace poté, co je serverem vygenerováno session ID. To, že za session ID přidáme další informace nemá na funkčnost žádný vliv. Tyto informace jsou pak před zpracováním opět odebrány, aby mohl server požadavek vyřídit. Jak je uvedeno výše, ASP.NET vytváří session ID v podobě identifikátoru a šifrovaného session ID, které má vždy 24 znaků. Za poslední znak je pak přidán validační MAC. IP adresa je získána z HTTP hlavičky, stejně tak jako označení používaného prohlížeče. A validační kód? Ten je nutné si sestavit samostatně. Můžeme použít buď jednotný kód nebo každému uživateli generovat jiný. Je ovšem nutné, aby měl dostatečnou sílu, tedy byl náhodný, dostatečně dlouhý a těžko odhalitelný. I sám validační kód může být výsledkem zašifrování nějakého textu či jiných znaků. V ukázkovém příkladě od společnosti Microsoft je použit pevně stanovený 32 místný řetězec znaků. Aby nemusel být kód zadáván v aplikaci stále dokola, je možné jej přesunout do souboru web.config. Toto řešení, použité i v následné ukázce od Microsoftu, však s sebou přináší riziko, že otevření souboru web.config neoprávněným uživatelem povede k prozrazení kódu. Nejvhodnější by bylo ho pokaždé generovat znovu, i když to může mít vliv na rychlost zpracování požadavků. Následuje vysvětlení kódu SecureSessionModule pro zabezpečení session. Nejprve je ukázán obsah souboru web.config s nastavením validačního kódu a poté kód SecureSessionModule s popisem. Před každou metodou je stručný popis její činnosti a v kódu jsou pak popisy důležitých řádků. Popisy jsou vždy uvozené znaky „//” a vysázeny kurzívou.

<configuration> <appSettings> <add key="SessionValidationKey" value="DAD4D476F80E0148BCD134D7AA5C61D7" /> </appSettings> <system.web> <httpModules> <add name="SecureSession" type="SecureSessionModule, SecureSessionModule" /> </httpModules> </system.web> </configuration>

Do návěští

<appSettings></appSettings> je možné vkládat jakákoliv data, která pak lze v aplikaci volat jako proměnnou. Jedinou podmínkou je dodržení syntaxe: <add key=”nazev” value=”hodnota” />

using System; using System.Web; using System.Web.Security; using System.Configuration; using System.Security.Cryptography; using System.Runtime.Serialization; using System.Globalization; using System.Text;

Program využívá několik knihoven .NET Framework, za zmínku stojí především System.Web, System.Web.Security a System.Security.Cryptography. Knihovna System.Web pracuje s HTTP protokolem, pomocí System.Web.Security pak máme přístup k session cookies a v neposlední řadě knihovna System.Security.Cryptography nám zpřístupní hashovací algoritmy.

public class SecureSessionModule : IHttpModule { private static string _ValidationKey = null; // První metoda zajistí inicializaci validačního klíče a registraci // handlerů public void Init (HttpApplication app) { // Inicializuje se validační klíč, pokud ještě nebyl inicializován. // Volá se metoda GetValidationKey() if (_ValidationKey == null) _ValidationKey = GetValidationKey (); // Registruje handlery pro události Začátek HTTP požadavku a Konec // HTTP požadavku. app.BeginRequest += new EventHandler (OnBeginRequest); app.EndRequest += new EventHandler (OnEndRequest); } public void Dispose () {} // Tato metoda je provedena na začátku HTTP požadavku. Její spuštění je // svázáno s handlerem BeginRequest. void OnBeginRequest (Object sender, EventArgs e) { // Hledá se příchozí cookie se jménem "ASP.NET_SessionId". // K získání cookies se volá metoda GetCookie() HttpRequest request = ((HttpApplication) sender).Request; HttpCookie cookie = GetCookie (request, "ASP.NET_SessionId"); if (cookie != null) { // Pokud cookie neobsahují MAC, je vyvolána chyba. Jak již // bylo řečeno, délka session ID je 24 znaků. Pokud je tedy // délka session ID 24 a méně znaků, pak je evidentně session // cookie podvrženo a je vyvolána chyba. if (cookie.Value.Length <= 24) throw new InvalidSessionException ("Vstup zamítnut"); // Rozdělení session ID a MAC. string id = cookie.Value.Substring (0, 24); string mac1 = cookie.Value.Substring (24); // Vygenerování nového MAC ze session ID, IP adresy klienta, // použitého prohlížeče a validačního kódu. // Ke generování MAC se volá metoda GetSessionIDMac(). string mac2 = GetSessionIDMac (id, request.UserHostAddress, request.UserAgent, _ValidationKey); // Porovnání přijatého MAC a nově vygenerovaného. Pokud se // neshodují je vyvolána chyba. if (String.CompareOrdinal (mac1, mac2) != 0) throw new InvalidSessionException ("Vstup zamítnut"); // Odstranění MAC z cookie, aby jej ASP.NET nezachytilo. // Pak by ho mohl získat i klient. Nehledě na to, že cookie // v této podobě by server neznal a nedokázal by tak vyvolat // správné hodnoty. cookie.Value = id; } } // Tato metoda je provedena na konci HTTP požadavku. // Její spuštění je svázáno s handlerem EndRequest. void OnEndRequest (Object sender, EventArgs e) { // Hledá se odchozí cookie se jménem "ASP.NET_SessionID". // K získání cookie se volá metoda GetCookie(). HttpRequest request = ((HttpApplication) sender).Request; HttpCookie cookie = GetCookie ( ((HttpApplication) sender).Response, "ASP.NET_SessionId"); if (cookie != null) { // Ke cookie se přidá MAC vygenerovaný ze session ID, IP adresy // klienta, použitého prohlížeče a validačního kódu. // Ke generování MAC se volá metoda GetSessionIDMac(). cookie.Value += GetSessionIDMac (cookie.Value, request.UserHostAddress, request.UserAgent, _ValidationKey); } } // Metoda vrací validační klíč ze souboru web.config. // Pokud validační klíč chybí, vyvolá chybu. private string GetValidationKey () { string key = ConfigurationSettings.AppSettings ["SessionValidationKey"]; if (key == null || key == String.Empty) throw new InvalidSessionException ("Chybí validační klíč"); return key; } // Metoda načte všechna cookie a volá metodu FindCookie(), s parametry // kolekce cookies a jména hledaného cookie. Její výsledek pak vrátí. private HttpCookie GetCookie (HttpRequest request, string name) { HttpCookieCollection cookies = request.Cookies; return FindCookie (cookies, name); } // Metoda vrací cookie s definovaným jménem z kolekce cookies. // Pokud žádné nenajde, vrací null. private HttpCookie FindCookie (HttpCookieCollection cookies, string name) { int count = cookies.Count; for (int i=0; i<count; i++)=i++) {={ if=if (String.Compare=(String.Compare (cookies[i].Name,=(cookies[i].Name, name,=name, true,=true, CultureInfo.InvariantCulture)=CultureInfo.InvariantCulture) =0) return=return cookies[i];=cookies[i]; }=} return=return null;=null; }=} // Metoda vytváří MAC ze sesion ID, IP adresy klienta, názvu prohlížeče // klienta a validačního kódu. // K šifrování se používá algoritmus SHA . private string GetSessionIDMac (string id, string ip, string agent, string key) { StringBuilder builder = new StringBuilder (id, 512); builder.Append (ip.Substring (0, ip.IndexOf ('.', ip.IndexOf ('.') + 1))); builder.Append (agent); using (HMACSHA1 hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (key))) { return Convert.ToBase64String (hmac.ComputeHash (Encoding.UTF8.GetBytes (builder.ToString ()))); } } } // Metoda pro generování chyb. // Chyby jsou generovány v závislosti na události, která je vyvolala. [Serializable] public class InvalidSessionException : Exception { public InvalidSessionException () : base ("Session cookie je neplatné") {} public InvalidSessionException (string message) : base (message) {} public InvalidSessionException (string message, Exception inner) : base (message, inner) {} protected InvalidSessionException (SerializationInfo info, StreamingContext context) : base (info, context) {} }

1.7.4. SQL injection

SQL injection vzniká při podvržených údajích, které jsou předávány do SQL dotazů obsažených v aplikaci. Podvrženým vstupem pak útočník může provádět své vlastní SQL příkazy a ohrozit tak obsah databáze. Prvním krokem, který musí útočník provést je odhalení druhu SQL serveru, který je s aplikací používán. K tomu lze využít různých technik. Útočník může rozpoznat druh SQL serveru například podle použitého skriptovacího jazyka. Přípony souboru naší aplikace typu .asp nebo .aspx vedou ve většině případů k úsudku, že je použita ASP nebo ASP.NET technologie společnosti Microsoft, která pak ve většině případů spolupracuje s Microsoft SQL serverem. Přípony .jsp by mohly naznačovat použití Oracle a .php pak zase MySQL serveru. Tento nedostatek odstraníme již zmíněným mapováním .html přípon na prováděcí knihovny ASP.NET . To je ale jen drobnost a podstata zabezpečení proti SQL injection spočívá někde jinde. Ukážeme si několik druhů SQL injection a obrany proti nim. Vzhledem k tomu, že ASP.NET aplikace jsou využívány především s Microsoft SQL serverem, bude i obrana proti SQL injection vycházet z předpokladu použití tohoto databázového serveru.

Mějme kupříkladu jednoduchý SQL dotaz:

SELECT * FROM uzivatele

Tento dotaz nelze napadnout, jelikož nepřijímá od uživatele žádné vstupy. Ale co třeba následující dotaz?

SELECT * FROM uzivatele WHERE jmeno = ’”+ TextBoxUser.Text+”’

Tento SQL dotaz by nám měl vrátit všechny údaje o daném uživateli. Vstupem je jméno uživatele zadané do formuláře na stránce. Co když ale útočník vloží do formuláře následující kód?

’ OR 1=1 --

Celý dotaz vygenerovaný aplikací pak bude vypadat následovně.

SELECT * FROM uzivatele WHERE jmeno = ’’ OR 1=1 --’

Jelikož znaky -- jsou v MSSQL serveru interpretovány jako uvozující komentář, nebudou ve zpracování SQL dotazu brány v úvahu a SQL server tedy zpracuje požadavek:

SELECT * FROM uzivatele WHERE jmeno = ’’ OR 1=1

Jak je vidět, jedná se o dotaz, který vrátí veškeré záznamy v tabulce uživatelé, jelikož podmínka je nastavena na prázdné jméno nebo 1=1 a 1=1 bude platit u každého záznamu.

Otázkou je, jak se útočník dostane k názvům tabulek. I na to je snadná odpověď pomocí SQL příkazu UNION. Ten dovoluje spojit výsledky jednoho dotazu s jiným dotazem a tak pomocí vstupu

' UNION SELECT id, name FROM sysobjects WHERE xtype ='u' -–

získat id a názvy tabulek začínajících na U, což může být i tabulka users. U příkazu UNION stačí dodržet počet výsledných polí dotazu a napadení je na světě. V případě, že polí originálního dotazu je více, lze příkaz snadno doplnit o prázdné hodnoty nebo nuly. Například:

' UNION SELECT id, name, '', 0 FROM sysobjects WHERE xtype ='U' –

Kolikrát ani nemusí útočník vyvíjet tak složitou činnost. Je s podivem, jak jednoduše odhalitelné názvy dávají vývojáři tabulkám v SQL serveru. Tabulka obsahující hesla se v mnoha případech jmenuje passwords, tabulka s uživatelskými účty users a podobně. Z toho plyne další z nejjednodušších ochran. Nenazývat tabulky podle obsahu, ale dávat jim jiné, méně příznačné názvy. Pokud by hacker získal název tabulky s uživatelskými účty, může již lehce příkazem

' UNION SELECT jmeno,heslo FROM uzivatele –-

získat i uživatelská jména a hesla . Opět platí pravidlo, že případná další pole původního výsledného dotazu lze nahradit prázdnými znaky či nulami. V dotazovacím jazyce SQL je pak možné vymyslet obrovské množství různých variací na tuto metodu a docela snadno napadnout nechráněné aplikace. Jedním z mnoha dalších způsobů je použití ; jako oddělovače SQL příkazů a zadat tak více SQL dotazů najednou. Například

'; UPDATE produkty SET cena = 0.01 –-

provede původní dotaz s prázdným vstupem, ale zároveň také nastaví cenu všech produktů na 0.01. To je velice nepříjemná situace, jelikož těžko pak budeme někomu vysvětlovat, že ceny jsou jiné. A v případě, že by takto napadený internetový obchod měl i napojení na platební systém, všimneme si problému až ve chvíli, kdy budeme prodávat za mizivé sumy zboží, které má ve skutečnosti cenu úplně jinou.

A jak se tedy bránit? V uvedených ukázkách je využíváno předávání vstupu přímo do SQL dotazu. A to je právě kámen úrazu. Tato technika je velice nebezpečná a proto je naprosto nevhodné ji využívat. Místo předávání vstupů přímo do SQL dotazu je vhodnější využít parametrizovaných SQL procedur , které jsou v ASP.NET plně podporovány. Následuje ukázka kódu předávání parametrů do uložené SQL procedury s popisem.

// Metoda je volána při stisknutí tlačítka Login. private void cmdLogin_Click(object sender, System.EventArgs e) { // Připojovací řetězec k databázi je převzat ze souboru web.config. string strConn = ConfigurationSettings.AppSettings["connectionString"]; // Do SQL connection je přidán parametr prm, který bude obsahovat. // předávaný parametr. Nejprve uživatelksé jméno, poté heslo. using (SqlConnection Conn = new SqlConnection(strConn)) { SqlParameter prm; // Otevření spojení s databází. Conn.Open(); // Tato proměnná bude v případě úspěšné autentizace naplněna. string strAccessLevel; // Inicializace instance SqlCommand // Instance představuje SQL příkaz formou uložené procedury SqlCommand cmd = new SqlCommand("procVerifyUser", Conn); cmd.CommandType= CommandType.StoredProcedure; // Vložení obsahu formulářového pole obsahujícího uživatelské jméno // do parametru uložené procedury prm = new SqlParameter("@username",SqlDbType.VarChar,50); prm.Direction=ParameterDirection.Input; prm.Value = txtUser.Text; cmd.Parameters.Add(prm); // Vložení obsahu formulářového pole obsahujícího heslo // do parametru uložené procedury prm = new SqlParameter("@password",SqlDbType.VarChar,50); prm.Direction=ParameterDirection.Input; prm.Value = txtPassword.Text; cmd.Parameters.Add(prm); // Naplnění proměnné strAccessLevel výsledkem zpracování procedury strAccessLevel = (string) cmd.ExecuteScalar(); // Pokud je délka obsahu proměnné strAccessLevel větší než nula, je // povolen přístup. Uložená procedura tedy vrátila pozitivní // výsledek. V opačném případě by nevracela nic. To však závisí na // naprogramování této procedury. if (strAccessLevel.Length>0) { FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false); } else { lblMsg.Text = "Pokus o přístup selhal."; } Conn.Close(); } }

Jak si lze všimnout, v případě pozitivního výsledku uložené procedury je volán následující příkaz.

FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);

Ten nám zajistí přesměrování na zabezpečenou stránku a zároveň uchovává jméno přihlášeného uživatele. Parametr false opět způsobuje, že přihlášení je aktivní do uzavření prohlížeče. Tento způsob, ačkoliv je v ukázce aplikován na autentizaci, lze použít na předávání jakýchkoliv vstupů do aplikace. Jedinou podmínkou je vytvoření příslušné procedury v MSSQL serveru. Je to samozřejmě na vývoj o něco náročnější, ale v zásadě jen v délce kódu. Obtížnost programování se příliš neliší. Lze namítnout, že by šlo také ošetřovat vstupy a vkládat je přímo do SQL dotazu upravené o přidané zákeřné kódy. I to je samozřejmě možné, ale je zapotřebí se zamyslet nad tím, že ošetření všech možných kombinací SQL injection je výrazně složitější, než využití uložených procedur a jejich parametrů. Někdy však může být ošetření vstupů vhodné, jako v případě, kdy uživatel vkládá text obsahující apostrof (například ve jméně Smith´s), ale neměli bychom nabývat dojmu, že se tím lze SQL injection vyhnout.

V neposlední řadě bych rád zmínil způsob, jakým je aplikaci sdělováno umístění databáze a přihlašovací údaje. Běžně využívaný způsob je uložení těchto informací do souboru web.config. Tento způsob sice lze v zásadě považovat za bezpečný, ale pokud bychom ho chtěli ještě zdokonalit, je možné přístupové údaje šifrovat a až aplikace je převede do jejich pravé podoby. Následuje ukázka ze souboru web.config se shodným připojovacím řetězcem k databázi MSSQL. Nejprve v podobě čistého textu, poté šifrovaná algoritmem SHA.

<add key="cnxNWindGood" value="server=localhost;uid=NWindReader;pwd=utbbeesozg4d; database=northwind;" /> <add key="cnxNWindBest" value="AQAAANCMnd8BFdERjHoAwE/ Cl+sBAAAAcWMZ8XhPz0O8jHcS1539LAQAAAACAAAAAAADZgAAqAAAABAAAABdodw0YhWfcC6+ UjUUOiMwAAAAAASAAACgAAAAEAAAALPzjTRnAPt7/W8v38ikHL5IAAAAzctRyEcHxWkzxeqbq/ V9ogaSqS4UxvKC9zmrXUoJ9mwrNZ/ XZ9LgbfcDXIIAXm2DLRCGRHMtrZrp9yledz0n9kgP3b3s+ X8wFAAAANmLu0UfOJdTc4WjlQQgmZElY7Z8" />

Nesmíme také zapomenout na přístupová oprávnění, kterými bude moci uživatel disponovat. Nikdy bychom neměli uživateli dovolit širší rozsah, než je pro něj nezbytně nutný. Běžný uživatel nesmí mít přístupová oprávnění administrátora a je více než vhodné mu řídit i oprávnění k provádění SQL příkazů SELECT, INSERT, UPDATE a DELETE. Jelikož MSSQL server disponuje širokou paletou možností řízení přístupu k tabulkám, je dobré je využívat a uživatele opravňovat jen k úkonům, které jim přísluší. Pokud má mít uživatel možnost jen z databáze číst, neměl by jeho uživatelský účet obsahovat pravomoci provádět příkazy INSERT, UPDATE či DELETE. Na obrázku č.6 v příloze je vidět možnost nastavení uživatelských oprávnění v MSSQL serveru. První obrázek ukazuje možnost nastavení přístupu jen k některým databázím či pouze jediné databázi, druhý pak možnost řídit oprávnění k provádění jednotlivých SQL příkazů.

Vzhledem k tomu, že šifrování zde již bylo několikrát probíráno, nebudu se jím již v této kapitole zabývat. Nutné je však připomenout, že dobře zabezpečená aplikace by neměla ukládat data do databáze v podobě čistého textu. Alespoň důvěrné informace, jako uživatelská jména, hesla, čísla bankovních účtů či jiné osobní a citlivé údaje, by měly být v databázi uloženy v zašifrované podobě. Pokud by selhaly veškeré bezpečností metody nebo by došlo k odcizení celého serveru, nemohl by útočník zjistit více, než jejich šifrovaná znění.

1.7.5. Ošetření chyb a výjimek běhu aplikace

I když dodržíme veškerá doposud uvedená bezpečností opatření, může se stát, že aplikace dosáhne stavu, který není specifikovaný a pro aplikaci známý a v takovém případě pak knihovny ASP.NET Framework obstarávající běh aplikace vyhlašují chybu. Pokud je aplikace správně konfigurována , nezobrazují se chyby generované aplikací přímo do uživatelova prohlížeče. ASP.NET disponuje technikou, pomocí které lze chybám předcházet a v případě jejich výskytu řídit chování aplikace. K tomu nám slouží blok příkazů try, catch a finally podporovaný ve všech programovacích jazycích .NET frameworku.

Ještě před tím, než vysvětlíme jejich funkci a použití bylo by dobré zmínit, že není vhodné je využívat pro ladění aplikace. K tomu slouží mnohem účinnější pomůcka - trasování . Pokud povolíme na stránce trasování jednoduchým zápisem na začátku stránky <%@ Page Language="C#" Trace="true" %>, začnou se nám na konci výpisu stránky zobrazovat informace o veškerých datech, která jsou na stránce dostupná. Vypíše se nejen celá hlavička protokolu HTTP, ale i informace a hodnoty o cookies, proměnných a dalších dostupných datech. Nebudu se zde příliš touto metodou zabývat, jelikož spadá spíše do kategorie ladění aplikací, než do jejich zabezpečení, ale alespoň zmíním, že za použití objektu Trace, lze do výpisu dat vkládat jakékoliv použité proměnné a zjišťovat tak její hodnotu a zároveň sledovat výstup aplikace v prohlížeči. Na obrázku číslo 7 v příloze je ukázán výstup s použitím objektu Trace.Write(”Vlastní”,strSQL). Položka Vlastní obsahuje celý řetězec i s předaným parametrem z okénka formuláře. Samozřejmě by se vstupy do SQL dotazu neměly takto zadávat (viz kapitola SQL injection), ukázka slouží pouze pro demonstraci využití možnosti trasování stránek.

A nyní tedy konečně k samotnému zachytávání výjimek. Začneme praktickou ukázkou, kterou následně vysvětlíme.

OdbcConnection ConnMsSql = new OdbcConnection(); ConnMsSql.ConnectionString = CONN_STRING_MSSQL; try { ConnMsSql.Open(); } catch (Exception Exp) { lblMessage.Text = ”Nepodařilo se připojit k databázi”; } finally { ConnMsSql.Close(); }

Jedná se o příklad připojení k databázi MSSQL pomocí ODBC . Blok příkazů try a catch zajišťuje odchycení případných problémů vzniklých při připojování k databázi. Pokud proces připojení k databázi z jakéhokoliv důvodu selže, čili kód ConnMsSql.Open(); nebude proveden, provede se kód obsažený v bloku catch. Ten obsahuje pouze výpis chyby v uživatelsky přívětivé podobě – výpis vloží do pole na stránce. Pokud se připojení k databázi podaří, obsah bloku catch se provádět nebude. Obsah bloku finally je proveden vždy, nezávisle na tom, který z bloků try a catch bude proveden.

„Z toho vyplývá, že příkaz try se používá k vymezení a ochraně té části kódu, která by mohla způsobit nějaké chyby. Při vývoji tradičních aplikací je takový přístup nutný, neboť existují určité akce, které způsobí chybu prakticky vždy. Například klepnutí na tlačítko Storno jakéhokoliv dialogu způsobí chybu, kterou aplikace musí být schopna zachytit a zpracovat. Obecně platí, že příkaz try a s ním spojené další příkazy se označují jako strukturované zachytávání výjimek (structured exception handling).“

Bloky příkazů try a catch by se měly používat především tehdy, kdy se aplikace snaží o přístup mimo ASP.NET. Vstup do jiných systémů bývá ovlivněn řadou okolností, a selhání je tedy více pravděpodobnější. Taktéž je vhodné tyto bloky používat tehdy, když si nejsme jisti kvalitou kódu a očekáváme výskyt nějakých chybových událostí. Rozhodně by však neměly být využívány k ošetřování vstupů. Pro ošetření vstupů slouží mnoho jiných metod, která si však programátor musí alespoň z části připravit sám, aby byly opravdu účinné. Samozřejmě, že využití bloků try a catch je v mnoha případech pohodlnější, ale musíme brát v úvahu i jisté požadavky na výkon při takto zpracovávaném kódu a uzavírat celý obsah aplikace do bloku try je opravdu horší než začátečnické.

3. Závěr

V předchozích kapitolách jsem se snažil nastínit různé oblasti internetových aplikací, které jsou často vystavovány útokům nebo problémům. Nemusí se vždy jednat o útok záměrný. Je však nutné být vždy ve střehu a nepodceňovat sebemenší detail internetové aplikace a celého jejího okolí. Jak jsem již zmínil v úvodu, u zabezpečení internetových aplikací se nelze spolehnout jen na bezpečný program a dobře nastavený server. Zabezpečení je potřeba vnímat jako komplexní činnost, která v sobě ukrývá mnoho dílčích aspektů. I když jsem se zde zabýval hlavně serverovou a aplikační částí, rád bych na závěr zmínil i několik obecnějších rad.

• Nevyužívat hosting u třetích osob: Podle mého názoru jedna z nejčastěji se dopouštěných chyb. I když by se mohlo toto prohlášení zdát diskutabilní, mají k serveru, na kterém jsou aplikace provozovány, přístup nám neznámé osoby. Tyto osoby mohou číst naše data uložená v databázi, mohou manipulovat s kódem aplikace, zkrátka mají nad naší aplikací úplnou kontrolu. Tento stav je ještě umocněn tím, že hostingové společnosti nám ve většině případů neumožní detailní nastavování serveru. Pravou je, že pokud budeme mít s poskytovatelem uzavřenou dobrou smlouvu o poskytování služeb doplněnou o SLA , byla by tato varianta určitě ekonomicky výhodnější. V této práci se však zabývám bezpečností a z jejího pohledu je jistě výhodnější mít nad hardwarovými i softwarovými prostředky vlastní kontrolu, i když to může znamenat vynaložení vyšších nákladů. • Vyvarovat se serverhostingu: Serverhosting je umístění celého serveru k providerovi, který zajišťuje fyzickou ochranu serveru, elektrické napájení i konektivitu do sítě Internet. Tato varianta je už lepší. Zpravidla využijeme vlastního serveru, do jehož systému mají přístup jen námi pověření lidé. Nastavení je plně v naší moci, i když finanční náklady na hardware a software nejsou nezanedbatelné, zvláště při použití více strojů. Problém však nastává s důvěrou v poskytovatele. Pokud nalezneme 100% spolehlivého a důvěryhodného, máme vyhráno. Mohou se však vyskytnout problémy způsobené komplikovanou infrastrukturou poskytování internetových přípojek mnoha dalším klientů jako jsme my. • Vlastní linka: Pravděpodobně nejvhodnější řešení. Nejlépe v kombinaci s několika záložními internetovými připojeními a ještě lépe od různých poskytovatelů. Garance konektivity je téměř 100%. Samozřejmostí je vlastní hardware i software a kvalifikovaný, spolehlivý správce systému dostupný 24 hodin denně, 7 dní v týdnu. • Pozor na lidský faktor: Mnoho odborníků v oblasti IS/ICT upozorňuje na to, že zdaleka nejnebezpečnějším faktorem jsou lidé. Získání důvěrných informací od lidí bývá kolikrát jednodušší, než prolamovat výborně zabezpečené informační systémy. Selhání lidského faktoru může mít však také za následek, že se útočník dostane do systému stejně lehce jako jeho správce.

Pomineme-li však lidská selhání, stačí dodržet postupy, které byly v této studii zmíněny, uchovávat přístupové údaje na bezpečných místech, zajistit spolehlivé zálohování a internetová aplikace se stane skoro neprůstřelnou. V praxi pak jistě platí, že lépe zabezpečená aplikace přiláká méně útočníků než ta hůře zabezpečená. Proto bychom měli zabezpečení věnovat velkou pozornost, protože ani ta nejsilnější a nejvýkonnější aplikace nám nebude ku prospěchu, pokud stráví v provozu jen několik dní, či se zhroutí v době svého maximálního provozu. Vzhledem k rychlému pokroku celé oblasti informačních technologií a zvláště internetových aplikací je potřeba se zabezpečení věnovat nepřetržitě a stále jej zlepšovat. Pokrok ochránce znamená i pokrok útočníka a podle mého názoru je to nekonečný boj o to, kdo bude nakonec úspěšnější.

4. Použitá literatura

1. Henrickson H., Hoffman S., Microsoft IIS 6 Kompletní průvodce, 1. vydání Brno: Computer Press 2004, ISBN 80-251-0128-2

2. Payne Chris, Naučte se ASP.NET za 21 dní, 1. vydání Praha: Computer Press 2002, ISBN 80-7226-605-5

3. Lacko Luboslav, SQL Hotová řešení, 1.vydání Brno: Computer Press 2003, ISBN 80-7226-975-5

4. Wikipedie: Otevřená encyklopedie, 2005, http://cs.wikipedia.org/

5. ACUNETIC ltd., Whitepaper, November 2005, http://www.acunetix.cz/websitesecurity/clanky.htm

6. Výkladový slovník pojmů Microsoft, http://www.microsoft.cz/Glossary/default.asp

7. Terminologický slovník ČSSI, Česká společnost pro systémovou integraci, http://www.cssi.cz/all_terminologie.asp

8. ASPNET.CZ, http://www.aspnet.cz/Articles/50-filtrovani-html-jak-na-nebezpecne-elementy.aspx

9. Microsoft ASP.NET, http://www.asp.net/faq/RequestValidation.aspx

10. Interval.cz, Zoner Software s.r.o., ISSN 1212-8651, http://interval.cz/clanky/bezpecnost-predevsim-vyhnete-se-script-injection/

11. Edmond Woychowsky, Maintaining session state in ASP, TechRepublic’s Builder.com, CNET Networks, Inc. 2002, http://builder.com.com/5100-6373-1044890.html

12. Milan Negovan, ASP.NET Custom Error Page, ASP.NET Resources, http://www.aspnetresources.com/articles/CustomErrorPages.aspx

13. Invincible Poison, SQL injection attacks, The Code Project 2005, http://www.codeproject.com/aspnet/SqlInjection.asp

14. Microsoft Developer Network, SQL Injection, MSDN 2005, http://msdn2.microsoft.com/en-us/library/ms161953.aspx

15. Microsoft Developer Network Magazine, MSDNMAG 2004, http://msdn.microsoft.com/msdnmag/issues/04/09/SQLInjection/

16. SecuriTeam, SQL Injection Walkthrough, 2002, http://www.securiteam.com/securityreviews/5DP0N1P76E.html

17. Online Computer Dictionary for Computer and Internet Terms and Definitions, http://www.webopedia.com/

5. Slovník pojmů

.NET Framework

Soubor softwarových technologií k snadnějšímu propojování různých zdrojů informací. Aplikace stavěné na této platformě jsou při spouštění překládány do tzv. mezikódu (metajazyk MSIL) a ten je teprve běhovým prostředím .NET Frameworku (tzv. Common Language Runtime, CLR) zpracováván na binární kód. Programovací jazyk, ve kterém bude napsán prvotní kód může být libovolný z podporovaných jazyků: Visual Basic, C#, Visual C++, Visual J#.

Active Directory

Adresářová služba, která ukládá informace o objektech v síti a poskytuje uživatelům a správcům sítě přístup k těmto informacím. Služba Active Directory poskytuje síťovým uživatelům přístup k povoleným prostředkům na libovolném místě prostřednictvím jediného přihlášení. Správcům sítě poskytuje intuitivní hierarchické zobrazení sítě a centrální bod pro správu všech síťových objektů.

Active Server Pages (ASP)

Soubory na webovém serveru, které slouží k provozu interaktivních aplikací. Aplikace ASP jsou skriptovány ve Visual Basic Scriptu nebo v Java Scriptu. Obsahují omezený počet objektů pro ovládání serveru. Většinu objektů je pak nutné doprogramovat v některém vyšším programovacím jazyce (např. Visual Basic)

Application Service Provider (ASP)

Specializovaná firma, která na vlastní nebo pronajaté informační a komunikační technologii provozuje služby, které nabízí k použití externím zákazníkům. Zákazník je k aplikaci obvykle připojen přes Internet. Služby v sobě integrují software, hardware, síťové technologie a vhodné konzultační služby do jednoho balíku. K jejich využití je z technologického hlediska obvykle potřeba pouze připojení k Internetu a WWW prohlížeč na osobních počítačích uživatelů zákazníka. ASP poskytují své aplikace velkým i malým podnikům i spotřebitelům.

Attack Surface

Jedná se o rozsah funkcionality webového serveru, který je viditelný nebo přístupný anonymnímu uživateli.

Cookie

Zpráva předaná serverem internetovému prohlížeči. Prohlížeč drží tuto zprávu v textovém souboru a posílá ji zpět na server pokaždé, když si ze serveru vyžádá nějakou stránku. Hlavní účel cookie je identifikovat jednotlivé uživatele internetových stránek a aplikací a připravovat je pro ně podle jejich přání či potřeby. Taktéž jsou vhodné pro potřeby serveru, pokud je nutné nebo vhodné si u uživatele ukládat určité specifické údaje.

Domain Name System (DNS)

Hierarchická distribuovaná databáze obsahující mapování názvů domén DNS k různým typům dat, například adresám IP. Služba DNS umožňuje vyhledání počítačů a služeb podle srozumitelných názvů a také vyhledání jiných informací uložených v databázi.

Doménový řadič, Domain Controller (DC)

Server v síti Windows NT, na němž jsou uloženy všechny informace pro správu systému. DC autentizuje uživatelská jména a hesla při přihlašování do sítě, přičemž uživatelům stačí přihlásit se pouze do jediné domény, aby získali přístup ke všem síťovým prostředkům.

Hash algoritmus

Hash algoritmus nebo též hash funkce je transformace, která jako vstup přijímá řetězec znaků o libovolné délce a výsledkem je pak řetězec znaků s pevnou délkou, tzv. hash nebo také otisk.

Http Handler

V ASP.NET je to autonomní funkční modul pro zpracovaní požadavků, jež jsou cíleny na soubory se specifickou příponou či jménem. V praxi to znamená, že pokud je na nějakou událost registrován nějaký handler, vyřizuje tuto událost spolu s dalšími handlery, které jsou již na danou událost registrovány.

Kerberos v5

Mechanismus ověřování, který se používá k ověření identity uživatele nebo hostitele. Ověřování pomocí protokolu Kerberos V5 je výchozí službou ověřování v systému Windows 2000. Tento protokol používá k ověřování také protokol IPSec (Internet Protocol Security) a služba Řízení přístupu technologie QoS.

New Technology File System (NTFS)

Standardní souborový systém operačního systémů Microsoft Windows NT a jeho následovníků (Windows 2000, Windows XP, atd.) Souborový systém NTFS je následovníkem systému FAT, který byl používán v MS-DOS a prvních verzích Windows. Na rozdíl od něj má však řadu vylepšení. NTFS je oproti FAT výkonnější, spolehlivější a dovoluje lepší využití pevného disku.

Open Database Connectivity (ODBC)

Technologie pro přenos dat mezi aplikacemi. Zaměřena na strukturovaná data. Pomocí této technologie je umožněn každému druhu aplikace přístup ke každému druhu databáze. Jediné co aplikace potřebuje je ODB driver umožňující propojení. Tvůrci databází zpravidla poskytují spolu s databází různé ODBC drivery pro různé operační systémy.

Role serveru, Server Role

K jakému účelu nebo jakým účelům je server používán. Serveru mohou být přiřazeny různé rola, jak například souborový server, tiskový server, webový server, server DNS apod. Přiřazováním a odebíráním jednotlivých rolí můžeme zajistit, že server poskytuje jen námi zvolené služby.

Service Level Agreement (SLA)

Service Level Agreement, Dohoda o úrovni služeb. Jedná se o smlouvu s provozovatelem IS nebo dodavatelem outsourcingu, která vymezuje parametry provozu aplikačního software (ASW) a hodnoty těchto parametrů, které mají být provozovatelem IS splněny (úroveň služby, Service Level). Pokud provozovatel nesplní sjednanou úroveň služby, bývá penalizován, způsob penalizace však musí být přesně sjednán. SLA jsou sjednány obvykle ve formě strukturovaných dokumentů. Úroveň služby bývá sjednána pro jednotky užití ASW: pro aplikace IS a pro kategorie uživatelů jednotlivých aplikací. Úroveň služby je tak rozdílná pro různé potřeby užití ASW.

Secure Sockets Layer (SSL)

Navrhovaný otevřený standard pro zavedení bezpečných komunikačních kanálů, které zabraňují přístupu k důležitým informacím, jako jsou například čísla kreditních karet. Tento standard slouží především k zabezpečení elektronických finančních transakcí na webu, ačkoli je navržen i pro použití s jinými službami sítě Internet.

Session Cookie

Bývá také nazýváno transient cookie. Jedná se o cookie, které je vymazáno, jakmile uživatel vypne internetový prohlížeč. Session cookie je uloženo v dočasné paměti a není dále drženo, pokud je prohlížeč uzavřen. Session cookie neshromažďuje informace z uživatelova počítače. Obvykle drží informace v podobě session ID, které neidentifikuje osobní údaje uživatele.

SQL procedura

Procedura napsaná v dotazovacím jazyce SQL a uložená v příslušné databázi v SQL serveru spolu s ostatními objekty. Procedura může nahrazovat část aplikační logiky pro zpracování údajů. Příklad vytvoření uložené procedury v MSSQL serveru.

CREATE PROC VratKontakty @firma CHAR(20) AS BEGIN SELECT kontakt_jmeno FROM zakaznici WHERE firma = @firma END

Uniform Resource Locator (URL)

Je to řetězec znaků s definovanou strukturou a slouží k přesné specifikaci umístění zdrojů informací (ve smyslu dokument nebo služba) na Internetu. URL definuje doménovou adresu serveru, umístění zdroje na serveru a protokol, kterým je možné zdroj zpřístupnit. Jednotlivá pole v URL: protokol, doménové jméno, port, specifikace souboru, parametry. Příklad pro www stránku: http://cs.wikipedia.org:80/w/wiki.phtml?title=URL&action=edit

Web extensions

Rozšíření funkcionality webového serveru nad rámec jeho originálních možností. IIS 6.0 má v sobě implementovánu podporu ASP a ASP.NET. Přidáním mapování souborů na další, dodatečně dodané knihovny, lze IIS 6.0 rozšířit o podporu PHP či dalších technologií pro internetové aplikace.

Značkovací jazyk (Markup Language)

Jazyk, jehož zdrojový text obsahuje současně jak vlastní text, tak instrukce pro jeho zpracování. Ty se zpravidla vyskytují v podobě příkazů (commands) či značek (tags). Zdrojovým textem bývá obyčejný ASCII soubor, což umožňuje jeho snadnou editaci i nejjednoduššími textovými editory, jako je například Poznámkový blok v MS Windows nebo i v Unixu. Příkladem značkovacích jazyků může být HTML pro psaní webových stránek nebo XML umožňující popsat strukturu dokumentu z hlediska věcného obsahu jednotlivých částí.

6. Přílohy

Obrázek 1, Nastavení metod ověřování přístupu

Nastavení metod ověřování přístupu

Obrázek 2, Nastavení omezení přístupu k podle IP adres nebo domén

Nastavení omezení přístupu k podle IP adres nebo domén

Obrázek 3, Nastavení mapování souborů HTML na knihovnu aspnet_isapi.dll

Nastavení mapování  souborů HTML na knihovnu aspnet_isapi.dll

Obrázek 4, Průběh procesu impersonalizace (zosobnění)

Průběh procesu impersonalizace (zosobnění)

převzato z Chris Payne, Naučte se ASP.NET za 21 dní, 678s.

Obrázek 5, Schéma komunikace serveru s prohlížečem při ochraně session ID

Schéma komunikace serveru s prohlížečem při ochraně session ID

převzato z http://msdn.microsoft.com/msdnmag/issues/04/08/WickedCode/

Obrázek 6, Nastavení řízení přístupu v Microsoft SQL serveru 8.0

Nastavení řízení přístupu v Microsoft SQL serveru 8.0

Obrázek 7, Ukázka výstupu stránky při zapnutém trasováním a použití objektu Trace.Write()

Ukázka výstupu stránky při zapnutém trasováním a použití objektu Trace.Write()

© FISCHER SOFTWARE, s.r.o.