Výsledky výzkumu a další informace nejen
z oblasti přístupových telekomunikačních sítí.
Access server ISSN 1214-9675
Server vznikl za podpory Grantové agentury ČR.
21. ročník
Hlavní stránka | Seznam rubrik | Ke stažení | Odkazy  

Doporučujeme
Knihu o FTTx

Matlab server - on-line výpočty a simulace

E-learning - on-line kurzy

Kontakt
KTT FEL ČVUT
Napište nám

Redakční rada - pokyny pro autory a recenzenty

Copyright

Bezpečnost

* Zabezpečení webových aplikací III. - ostatní útoky a nastavení prostředí

Vydáno dne 15. 08. 2007 (12772 přečtení)

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:

safeweb_06

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.

safeweb_07

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



Autor:        J. Malý, J. Kacálek
Pracoviště: Vysoké učení technické v Brně

Informační e-mail Vytisknout článek
Zprávy
UPOZORNĚNÍ
Činnost serveru byla ukončena.


Tento web site byl vytvořen prostřednictvím phpRS - redakčního systému napsaného v PHP jazyce.
Na této stránce použité názvy programových produktů, firem apod. mohou být ochrannými známkami
nebo registrovanými ochrannými známkami příslušných vlastníků.