Zabezpečení webových aplikací je jednou z nejdůležitějších položek jejich vývoje. Tato část článku se zabývá ostatními typy útoků z principu nespadajících do kategorií zneužití klientských skriptovacích jazyků nebo zneužití databázového dotazu. Také řeší správné nastavení
prostředí PHP a ASP.NET, které je základním kamenem ke správné bezpečnosti celého systému.
Security of web applications III. - others type of attacks and environment setting
Abstract
Security of web applications is one of the most important aspects of their development. This part of paper deals with the others type of attacks, which do not belong to category of client script languages exploitation or database query exploitation. Here is also described proper setting of PHP and ASP.NET interface, which is basic element in proper security of whole system.
Úvod
Většina útoků, kterých se článek dotýká, opět
přímo souvisí s uživatelským vstupem. Jejich vážnost a rozsah možného poškození
jsou ovlivněny tím, v jaké části programu se vstupní údaj promítne. Ve většině
případů jde o podstrčení škodlivého kódu nebo serverového skriptu, které může
mít v nejhorších případech nedozírné následky. Pozornost je také třeba věnovat
nastavení serverového skriptovacího jazyka (PHP / ASP) a samotného serveru,
neboť vhodné nastavení direktiv a parametrů prostředí nám přímo zajistí ochranu před určitými typy
útoků.
Nebezpečné úpravy kódu
Problém se týká především skriptovacího jazyka PHP.
Ten je totiž z principu procedurálně skriptovací jazyk bez nutnosti kompilace,
což je na jedné straně zjednodušení práce pro vývojáře (za cenu nižšího výkonu
programů), na straně druhé tento fakt představuje nebezpečí z hlediska okamžité
změny kódu aplikace. U ASP.NET tento problém odpadá kvůli nutnosti kompilace
objektově orientovaného kódu.
Podstrčení proměnných
Jde o specifický útok pro jazyk PHP, který využívá
bezpečnostní díry (v počátcích vývoje PHP šlo spíše o hodnotnou vlastnost),
vzniklé při použití direktivy register_globals.
Tato direktiva automaticky převádí všechny hodnoty, získané z tzv.
superglobálních proměnných (GET a POST data,
SESSIONS, COOKIES) na globální proměnné pod patřičným
názvem. Ačkoliv se na jednu stranu zdá, že direktiva zjednoduší situaci přímým
zavedením proměnných, ve skutečnosti jde o snadnou cestu, jak do kódu zvenčí vložit vlastní
proměnné a jejich hodnoty. Vezměme si hypotetický příklad na obr.1:
Obr. 1 Útok s využitím podstrčení proměnné
Nejlepší obranou je, pokud máme tuto možnost, direktivu
register_globals úplně vypnout a postarat se o příchozí data ze
superglobálních proměnných pomocí polí $_GET, $_POST,
$_SESSION a $_COOKIE.
Pokud tuto možnost nemáme, je nutné tento problém ošetřit
pomocí důsledné inicializace proměnných na jejich výchozí hodnoty. To se týká i
polí, která bychom měli vždy inicializovat jako prázdná formou přiřazení $pole
= Array();.
Podstrčení cizího kódu
Extrémně nebezpečný útok spočívá v podstrčení škodlivého
kódu do webové aplikace. Tímto neduhem mohou být postiženy velmi špatně
zabezpečené aplikace, které dovolí uživateli měnit data, která jsou parametrem
funkcí exec() – sloužící k vykonání externího programu, a eval(), která vykoná
jakýkoliv vložený PHP kód. Následky takového útoku mohou být nedozírné, neboť
PHP skript má poměrně vysokou úroveň kontroly nad serverem, nehledě na možnost
získání zrojového kódu aplikace.
Typickým příkladem jsou redakčně / publikační systémy, které
přímo dovolují spouštět v uživatelem zadaném obsahu PHP příkazy formou značek
<?php a ?>. Toto řešení je pochopitelně
obrovský bezpečnostní problém a je nutné zajistit, aby k takovým možnostem měli
přístup pouze oprávnění lidé, kteří mohou obsah měnit (a naopak z tohoto řešení
těží).
Vždy je tedy nutné kontrolovat všemi dostupnými prostředky,
aby se k parametrům výše zmíněných funkcí nedostal uživatel bez patřičného
oprávnění. Riziková je i funkce preg_replace(), určená k záměně
řetězce za využití regulárních výrazů, pokud ji použijeme ve spojitosti s
modifikátorem regulárního výrazu /e, který vykoná přepsaný řetězec
jako PHP kód a následně ho uloží. Všechny tyto cesty je třeba zabezpečit, a
pokud je to možné, vůbec do nich uživatelský vstup nepromítat.
Vzdálené spuštění
Další metodou je vzdálené spouštění cizích skriptů. Souvisí
opět s PHP a spočívá v nedokonalém zabezpečení interních příkazů
include, include_once, require a
require_once. Problém nastane, pokud tyto funce čerpají vstup např. z
URL. Útočník může dostupný parametr, např. stranka4.php, nahradit
výrazem /etc/pass, která na UNIXovém serveru provede vložení souboru
s hesly (pokud proti tomu není server zabezpečen). Nebo se může pohybovat
ve stromové adresářové struktuře pomocí návratu na předchozí úroveň
../, příp. vložit kód z vlastní stránky.
Vhodným ošetřením je, pokud už musíme vkládaný soubor
specifikovat v URL, použít v PHP funkce basename(), která odstraní
veškerou cestu kromě názvu souboru. Daleko lepším řešením je však nepoužívat
vkládání pomocí uživatelského parametru, případně povolit jen vkládání souborů
z nějakého předdefinovaného seznamu (čímž se velice přibližujeme vkládání
souborů v kompilovaných jazycích, kde toto je součástí preprocesoru a není
možné parametr uživatelsky měnit). U jednodušších prezentací je vhodný způsob
založen na samostatném souboru pro každou sekci aplikace, přičemž společné
části se vloží pomocí include. Tyto části obsahují jen definice funkcí bez
jakéhokoliv kódu, který by se spustil po vložení (kromě např. inicializace
globálních proměnných).
Za vhodné zabezpečení nelze považovat direktivu
allow_url_include, jejímž vypnutím zabráníme vkládání souborů z cizích
URL; jednak může skript útočníka běžet na stejném stroji a jednak ošetření
nepamatuje na všechny možnosti vložení cizích dat (např. pomocí
php://input – standardní vstup PHP).
Další útoky
Úprava protokolových hlaviček
V originále se setkáme s označením response splitting [1].
Útok je založen na změně hlavičky HTTP (nebo SMTP v případě emailů), proti
kterému není aplikace zabezpečena. Tímto útokem lze přidávat do hlavičky
vlastní řádky, nebo – a to je zdaleka největší riziko – hlavičku prázdným
řádkem ukončit – čímž protokol přejde na zpracování samotných dat (která mu
tímto řešením podstrčíme ještě v rámci hlavičky). U HTTP hlavičky je
nejproblémovějším parametrem Location, který slouží k přesměrování
na jinou stránku.
Řešením v PHP je důsledně kontrolovat data, která do
hlavičky vstupují a nepovolit dělení řádků (znakem \n se jednotlivé parametry
hlavičky oddělují). Od PHP 4.4.2 a 5.1.2 není možné v rámci funkce header()
poslat více než jeden řádek.
U emailů problém spočívá v editaci hlavičky v příkazu
mail(), kde nevhodným zásahem můžeme opět hlavičku předčasně ukončit a
vložit do mailu podstrčená data. V žádném případě bychom neměli umožnit
uživateli přístup k hlavičce emailu. Ani v případě pole From:,
protože právě díky možnosti editace tohoto pole velmi usnadníme situaci těm
lidem, kteří chtějí využívat náš formulář k rozesílání spamu.
Zafixování session
Tento útok (session fixation) spočívá v přesvědčení
uživatele, aby pro přihlášení použil útočníkovu předgenerovanou session ID.
Jakmile se nic netušící uživatel zaloguje do systému a tento není proti útoku
chráněn, použije se jako session ID identifikátor poskytnutý útočníkem. Ten
pak může pod tímto ID přistoupit na stránku také a bude systémem chápán jako
napadený uživatel. Technicky se předání session ID provede např. pomocí URL
nebo POST dat z formuláře. Typické schéma útoku je na obr.7.
Obr. 2 Princip session fixation
Session fixation se dá ve skriptovací jazyce PHP předcházet
pomocí direktivy session.use_only_cookies, která nedovolí, aby se session ID
předávala jinak, než pomocí cookies. Další způsob spočívá v častém regenerování
SID pomocí funkce session_regenerate_id() (pozor, je třeba mít na serveru aktualizovanou
verzi PHP - nejlépe 4.3.2 a vyšší). Tuto funkci je vhodné volat alespoň
po zalogování do systému. Po ukončení práce je dobré session zničit pomocí
session_destroy(). Útok je podrobně popsán např. v [2].
VIEWSTATE a spojená rizika
VIEWSTATE je vlastnost specifická pro ASP.NET stránky [3]. Jedná
se o nástroj umožňující uchování stavu stránky a serverových objektů na ní
umístěných mezi jejím opakovaným zpracováním. Narozdíl od jiných metod uchování
stavu v ASP.NET aplikacích, které je možno použít v rozsahu platnosti uživatele
aplikace (Session) nebo celé aplikace (Application, Cache apod..) je tedy jeho
platnost omezena pouze po dobu tohoto opakovaného zpracování jedné stránky. VIEWSTATE je využívána zejména pro uchování hodnot vlastností ovládacích prvků umístěných na stránce, ale lze ji samozřejmě také použít v kódu stránky.
Problémem VIEWSTATE je, že standardně není šifrován. Proto není vyloučenou, že někdo může data ve VIEWSTATE pozměnit či přečíst. Z tohoto důvodu existují další dvě úrovně zabezpečení dat ve VIEWSTATE. Pokud jsou v těchto datech přenášeny citlivé informace je vhodné tyto úrovně do aplikace přidat, aby bylo minimalizováno nebezpečí odposlechu či změny dat ve VIEWSTATE. Jedná se o:
- Machine Authentication Check (MAC) - tamper-proofing
- šifrování
Tamper-proofing nechrání VIEWSTATE proti přečtení
obsahu nepovolanou osobou. Místo toho poskytuje možnost určit, zda-li někdo
nepozměnil data uložená ve VIEWSTATE. Při využití tamper-proofing je, ještě
předtím než jsou data ve VIEWSTATE poslány klientovy, vytvořen na serveru
jejich otisk pomocí některé z hashovaních funkcí (např. MD5 nebo SHA1). Když
pak klient odešle stránku zpět na server je opět vytvořen otisk dat ve
VIEWSTATE a ten je poté porovnán s prvním otiskem. Samotná aktivace
tamper-proofing je velmi jednoduchá a nastaví se v počátečním tagu stránky:
<%@ Page EnableViewStateMac="true"%>
Bohužel tamper-proofing umožní pouze detekci změn ve
VIEWSTATE, ale nezabrání případnému přečtení dat nepovolanou osobou. Pokud
tomuto chcete zabránit musíte natavit další úroveň zabezpečení. V tomto případě
musíte data ve VIEWSTATE zašifrovat. Jako šifrovací algoritmus se používá 3DES.
Nastavení tohoto šifrovaní pro VIEVSTATE musíte provést v souboru
machine.config pomocí kódu <machineKey validation=3Des />. Umístění tohoto
souboru je:
x:\<windows>\Microsoft.NET\Framework\<version>\config\machine.config
Nastavení serverových prostředí
Před samotným závěrem je vhodné uvést obecná bezpečnostní
doporučení, která v naprosté většině již vychází z toho, co bylo v článku
popsáno výše. Situace je pochopitelně odlišná v případě skriptovacího jazyka
PHP a prostředí ASP.NET
Jazyk PHP
Pokud používáme jazyk PHP, je nutné v první řadě správně
nastavit prostředí, na kterém pracuje. V naprosté většině případů jde o webový
server Apache. Je nutné pomocí konfigurace znemožnit např. prohlížení
zdrojových kódů PHP přímo z webu a takto zabezpečit všechny ostatní datové typy,
které by mohly způsobovat problémy. Také výpis adresáře pomocí HTTP požadavku
je dobré dovolovat jen lokálně a to pomocí souboru .htaccess s místním
nastavením.
Velmi důležité je mít správně nastavenou adresářovou
strukturu a manipulovat s oprávněními s extrémní opatrností. Správné řešení
tohoto problému je však nad rámec rozsahu tohoto článku, proto je vhodné např.
čerpat z [4].
Co se týče samotného skriptovacího jazyka, zde je především
nutné správně nakonfigurovat direktivy. Následující direktivy by měly být z
bezpečnostního hlediska vypnuty:
safe_mode – nastavuje bezpečný režim, je však nespolehlivá a do PHP 6 se s ní nepočítá.
display_errors – zobrazování chyb je nebezpečné, může útočníkovi značně pomoci. Pokud je to nutné, nastavovat lokálně pomocí error_reporting().
magic_quotes_sybase – mění zásadním způsobem ošetřování speciálních znaků v SQL dotazu.
register_globals – opět velmi nevhodné, otevírá možnost útoku pomocí vložených proměnných.
Naopak, následující direktivy je vhodné používat (nastavit):
open_basedir – zamezuje ze skriptu přístup mimo zadaný adresář
disable_functions – můžete specifikovat zakázání určitých funkcí (exec )
session.use_only_cookies – nebudou se brát v potaz session ID přicházející z GET nebo POST dat.
session.save_path a upload_tmp_dir – nastavují cestu k ukládání sessions a s dočasných dat. Vhodné nastavit na bezpečné místo.
Více informací k tématu lze načerpat např. v [5].
Prostředí ASP.NET
Stránky ASP.NET jsou úzce spjaty s IIS severem, proto také
bezpečnost ASP.NET stránek velmi souvisí se zabezpečeným tohoto serveru.
Možnosti zabezpečení IIS serveru jsou velmi rozsáhlé, proto zde nebudou
rozebírány. Pro podrobnější informace odkazujeme např. na [5], [6].
Pokud vyžadujete od uživatelů autentizaci je doporučeno
použít některý z autentizačních módů ASP.NET. Jedná se o módy None, Windows,
Passport a Form. Mód autentizace se natavuje v souboru web.config pomoci
následujcího kódu:
<authentication mode="Typ_modu">
// další volby v závislosti na zvoleném režimu autentizace
</authentication>
Mód None je základní mód, ve kterém nedochází k
žádné autentizaci, proto se jeho používání nedoporučuje. Nejflexibilnějí je mód
Form. Jde o režim, který si může vývojář upravit k obrazu svému.
Při ověřování identity uživatele se nemusíme omezovat pouze na uživatele
definované v doméně či na serveru, ale můžeme provádět ověřování vůči seznamu
uživatelů v souboru web.config.
Dále je doporučeno mít pro všechny stránky mít nastavenu
vlastnost ValidateRequest na hodnotu true. Dalším
obecný doporučením je, aby se při práci s databázemi používaly parametrizované
SQL dotazy a parametrizované uložené procedury. Zásadně se nedoporučuje skládat
SQL dotazy jako řetězce za použití vstupů od uživatelů.
Nastavení parametru mode tagu <customErrors>
v souboru web.config na hodnotu On bude mít
za následek, že se k uživateli nedostanou citlivá data v případě vyvolání
výjimky.
Doporučuje se také chránit autenzační cookie proti případným
změnám jejího obsahu uživateli. Toto se provádí v tagu <roleManager>:
- Nastavte atribut
cookieProtection na hodnotu All
- Nastavte atribut
cookieRequireSSL na hodnotu true
- Nastavte atribut
createPersistentCookie na hodnotu false
- Nastavte atribut
cookieSlidingExpiration na hodnotu true a atribut cookieTimeout v rozsahu 10-20 minut
Závěrem
Poslední část článku se věnovala ostatním typům útoků na
webovou aplikaci. Tyto útoky z velké části využívají skriptovacího charakteru
jazyka PHP; Je nutné, pracujeme-li v tomto prostředí, dobře promyslet důsledky
použití funkcí jako eval nebo exec. Obecně lze říci,
že opět platí pravidlo důsledné kontroly uživatelem zadaných dat. Problémy se
nevyhýbají ani daleko lépe zabezpečenému prostředí ASP.NET - viz např. část o
bezpečnosti VIEWSTATE. Pro dokonalé zabezpečení rovněž doporučujeme správně
nastavit chování serveru - v tomto případě ISS nebo Apache. V jednotlivých
kapitolách jsou odkazy k další literatuře, která se touto problematikou
zabývá.
Článkem popsaný výčet útoků pochopitelně není vyčerpávající.
Další spočívají např. přímo ve využití bezpečnostních děr v softwaru (prohlížeče) nebo v
operačních systémech. Dále může jít o útoky typu DoS (Denial of Service), příp.
horší varianta - DDoS, které představují nejnebezpečnější typy útoků, mnohdy bez rozumných možností obrany.
Tyto útoky mohou být namířeny i proti základním kamenům celého internetu - byl například zdokumentován pokus
o vyřazení páteřních DNS serverů [8]. Článek se také nezabýval zabezpečením pomocí protokolu
HTTPS, protože to je dosti rozsáhlé téma, které je vhodné řešit samostatně.
Nezbývá než doufat, že článek bude přínosný zejména
začínajícím programátorům, kteří se vývoji webových aplikací chtějí v budoucnu
věnovat. Jedině lepší informovaností tvůrců aplikací lze totiž docílit toho, že
podobné útoky se jednou stanou minulostí.
Poděkování
Autoři článku chtějí touto cestou poděkovat panu Jakubovi Vránovi za
velmi přínosné školení "Bezpečnost aplikací v PHP", ze kterého získali velké množství
informací zejména o praktické realizaci útoků z pohledu napadající strany. Mnoho užitečných rad
k dané problematice lze nalézt přímo na webových stránkách [5].
Literatura
[1] Securiteam.com: Introduction to HTTP Response Splitting, SecuriTeam™ 2005, online, dostupné z: http://www.securiteam.com/securityreviews/5WP0E2KFGK.html
[2] Kolšek, M.: Session Fixation Vulnerability in Web-based Applications, ACROS d.o.o. 2002
[3] Drlík, Z.: ViewState v ASP.NET aplikacích - implementace a použití, online, dostupné z: http://interval.cz/clanky/viewstate-v-asp-net-aplikacich-implementace-a-pouziti/
[4] Ristic, I.: Apache Security, O'Reilly 2005
Další zdroje
[5] Jakub Vrána - PHP triky (webová stránka), dostupné z: http://php.vrana.cz/
[6] Windows Server 2003 Security Guide (webová stránka), dostupné z: http://www.microsoft.com/technet/security/prodtech/windowsserver2003/w2003hg/sgch00.mspx
[7] Security Guidelines: ASP.NET 2.0 (webová stránka), dostupné z: http://msdn2.microsoft.com/en-us/library/ms998258.aspx
[8] SSAC Advisory SAC008 DNS Distributed Denial of Service (DDoS) Attacks, zpráva výboru ICANN pro stabilitu a bezpečnost, březen 2006