Spletni napadi

Objavljeno: 30.5.2007 13:29 | Avtor: Marko Hölbl | Kategorija: Preizkusi | Revija: Maj 2007

Spletne strani postajajo vedno bolj dinamične. To omogoča uporabniku prilagojeno in prijaznejšo rabo. Vendar se s kompleksnostjo spletnih strani povečuje tudi verjetnost napadov, zlorab in pogostost razpok v sistemu varnosti.

Med najpomembnejše napade spletnih strani (t. i. spletne napade) sodijo cross-site scripting (XSS), ki izkoriščajo dinamične komponente spletnih strani, manj razširjen napad izvajanja na daljavo (angl. remote code execution), napadi na zbirke podatkov ob pomoči vrivanja SQL (angl. SQL injection) in napadi na piškotke (angl. cookies). V članku bomo predstavili poglavitne značilnosti napadov in ukrepe za njihovo preprečevanje.

Napadi cross-site scripting (XSS)

Pri napadih cross-site scripting (XSS) poskuša napadalec spletno aplikacijo spremeniti tako, da bo ob obisku strani izvedena zlonamerna programska koda - spletni brskalnik obdela vstavljeno zlonamerno programsko kodo kot del spletne strani. Ob pomoči napada XSS lahko napadalec spreminja in poneveri podatke spletne strani in s tem obiskovalca prepriča, da je na znani spletni strani. Ko uporabnik vpiše svoje podatke (npr. uporabniško ime in geslo), napadalec prestreže podatke in se tako dokoplje do različnih podatkov - od osebnih podatkov do podatkov o kreditnih karticah. Uporabnik velikokrat sploh ne opazi, da gre za napad, saj napadalci uporabljajo različne zvijače in tehnike ter tako preslepijo uporabnika.

Razlikujemo dve vrsti napadov XSS glede na tehniko integriranja zlonamerne programske kode v prikazano spletno stran:

  • odsevni napad XSS (angl. reflecting XSS attack),
  • trajni napad XSS (angl. persistent XSS attack).
  • Pri prvem mora napadalec prepričati žrtev, da klikne določen naslov URL. V parametrih naslova se skriva zlonamerna koda, ki izkoristi razpoko v strežniški aplikaciji. Skoraj vsi napadi, ki jih lahko najdemo na spletni strani hekerske skupine "Electrical Ordered Freedom" Phishmarkt (glej seznam naslovov na koncu članka), so te vrste.

    Shema odsevnega napada XSS

    Druga vrsta napada XSS je trajni napad XSS, ki podobno kakor prva vrsta napadov izvede zlonamerno kodo v strežniku ob pomoči naslova URL, ki ga klikne uporabnik. Razlika je v tem, da ta vrsta napada izvede še vmesno povpraševanje v zbirki podatkov strežnika. Strežnik tako posreduje zlonamerno programsko kodo tudi uporabnikov, ki niso kliknili spremenjene povezave. Primer so vnosi v forum, ki imajo integrirano programsko kodo JavaScript; uporabnik, ki klikne spremenjeno povezavo, je kar sam napadalec, saj želi zlonamerno kodo posredovati v strežnik. Ko je zlonamerna koda enkrat v zbirki podatkov strežnika, ni več treba, da bi potencialne žrtve kliknile spremenjeno povezavo.

    Shema trajnega napada XSS

    Pri obeh vrstah napadov je aplikacija, ki ima razpoko v varnosti/hrošča, v strežniku. Drugače pa so tudi napadi, ki se v celoti izvajajo v uporabnikovem računalniku - to vrsto napada imenujemo lokalni napad XSS (angl. local XSS attack). Tak napad je tipičen predvsem za spletne aplikacije Web 2.0 (npr. Ajax), kjer se veliko programske kode (JavaScript in Java) izvaja v uporabnikovem spletnem brskalniku.

    Shema lokalnega napada XSS

    Pri lokalnem napadu XSS strežnik spletnemu brskalniku posreduje le skripto z razpoko/hroščem, ne pa tudi zlonamerne programske kode. Posebno vlogo igra DOM (angl. Document Object Model), ob pomoči katerega brskalnik zgradi strukturo spletne strani. Zato napad imenujemo tudi "DOM-based XSS". Ob pomoči drevesa DOM aplikacija izvede dinamične spremembe prikazane spletne strani - na primer za potrebe interaktivnosti. Razpokana spletna skriptna koda ob pomoči DOM vstavi zlonamerno programsko kodo neposredno z naslova URL na prikazano spletno stran, in to brez novega zahtevka spletnemu strežniku. V internetu je mogoče najti veliko primerov napadov vrste XSS, nekaj demonstracij napadov XSS je mogoče najti na spletnih naslovih, podanih na koncu članka.

    Napad z izvajanjem programske kode na daljavo (Remote Code Execution)

    Medtem ko napadi XSS brskalniku "podtaknejo" zlonamerno programsko kodo, pa napadi z izvajanjem programske kode na daljavo izkoriščajo razpoke in druge ranljivosti ter omogočajo uporabniku izvajanje programske kode na daljavo (angl. remote). Primer takega napada je napad na spletni forum phpBB. Naslednji ukaz iz korenskega imenika phpBB vključi datoteko common.php in jo izvede:

    include_once ($phpbb_root_path . 'common.php');

    Razvijalci vtičnikov (plug-in) so privzeli, da globalna spremenljivka $phpbb_root_path vsebuje pot do namestitve phpBB. Ker lahko vtičnike poženemo prek naslova URL s poljubnimi parametri, lahko napadalec preusmeri pot do korenskega imenik phpBB (na primer z izvedbo ukaza /plugin.php&phpbb_root_path=zlobnez.si). V tem primeru se izvede datoteka zlobnez.si/common.php in to omogoča napadalcu izvesti poljubno programsko kodo, ki je v njegovem spletnem strežniku. Podobna težava nastopi pri uporabi ukaza require().
    Tako preprosto izvajanje zlonamerne programske kode je sicer možno samo v "nevarnih" konfiguracijah PHP, vendar veliko ponudnikov spletnih gostiteljstev (angl. shared-hosts) uporablja prav tako konfiguracijo, predvsem zaradi združljivosti.

    Redkeje naletimo na obliko napada z izvajanjem programske kode na daljavo, pri kateri izvajamo programsko kodo neposredno ob pomoči naslovov URL ali podatkov s spletnih obrazcev (angl. Forms) - podobno kot pri napadih XSS. Za tak napad je lahko kriva nepazljiva uporaba PHP funkcije eval(), ki interpretira poljuben niz znakov kot programsko kodo PHP.

    Prikaz primera napada XSS (s spletne stran Phishmarkt)

    Napad ob pomoči vrivanja SQL (SQL injection)

    Skoraj vse sodobne spletne aplikacije za prikaz spletne strani uporabljajo zbirko podatkov SQL. Vrivanje in izvajanje spremenjenih ukazov SQL imenujemo vrivanje SQL (angl. SQL injection). Preprost primer takega vrivanja lahko demonstiramo z ukazom SQL

    SELECT * FROM users WHERE name='$username' AND password = '$password'.

    Če povpraševanje ne vrne rezultata, v zbirki ni vnesenega uporabnika s takim uporabniškim imenom in geslom. Demonstrirajmo vrivanje SQL ob pomoči naslednjega stavka SQL:


    SELECT * FROM users WHERE name='admin' AND password = 't' OR 't' = 't'.

    Originalnemu stavku smo vrinili "OR 't' = 't'". Ker je ta vedno veljaven (t = t vedno velja), nas aplikacija prijavi kot uporabnika admin, če le-ta seveda obstaja. Napadalec lahko z ugibanjem ugotavlja polja oz. atribute in imena tabel v zbirki podatkov SQL.

    Možna je tudi druga rešitev:

    SELECT * FROM users WHERE name='admin' -- AND password = 'karkoli'.


    Vrinili smo "--" in ker v jeziku SQL velja, da se vse, kar je za nizom -- ignorira, je tudi tako mogoče pridobiti dostop samo ob pomoči pravilno ugotovljenega uporabniškega imena.

    S podpičjem lahko uporabnik ukazu doda celoten ukaz SQL in tako izvede poljubne operacije:

    SELECT * FROM users WHERE name='admin'; INSERT INTO users....

    K sreči so taki napadi le redko mogoči, saj večina strani že uporablja filtriranje ali druge zaščitne ukrepe. Primer slednjega je dodajanje varnostnega izračuna (hash) ob vnašanju novega uporabnika v zbirko podatkov.

    Naj omenimo še starejši napad ob pomoči jezika SQL, tj. napad s pobegom poti (angl. Path Traversal). Večina sodobnih operacijskih sistemov uporablja oznako ".." kot kazalo na starševski imenik. Uporabnik ima lahko ob pomoči vrivanja SQL in in izraza "../../../" dostop do višjih imenikov (kar s strani razvijalca gotovo ni bilo predvideno). Dokoplje se lahko celo do datoteke /etc/passwd ali do konfiguracijske datoteke config.php ...

    Napadi na piškotke

    Piškotki so majhne besedilne datoteke v uporabnikovem računalniku in lahko hranijo podatke, ki jih vanje zapisuje brskalnik oz. prek njega spletne strani. Uporabljajo se za identifikacijo uporabnikov ali spremljanje brskalnih navad uporabnikov. Oglejmo si primer vsebine piškotka, ki ga uporablja podjetje Informit.com:


    Domain: .doubleclick.net

    Name: id

    Content: 800000a5610cc5a

    Path: /

    Expires: Friday, November 06, 2009 9:23:14 AM

    Prvi del piškotka označuje domeno, torej lastnika piškotka. Naslednji dve polji označujeta ime ("Name") in vrednost ("Content") piškotka - uporabljata se za identificiranje piškotka. Zadnji pomemben del je polje o veljavnosti piškotka ("Expires") - "rok zapadlosti".

    Piškotke "legalno" zlorabljajo različna marketinška podjetja, kar pomeni resno grožnjo zasebnosti uporabnikov. Piškotki so shranjeni kot besedilo, berljivo vsakomur. Ko uporabljamo piškotke (oz. hranjenja le-teh v brskalniku ne prepovemo), se moramo tega zavedati. Piškotki se prav tako prenašajo po nezaščitenih povezavah (razen kadar je uporabljeno šifriranje, npr. SSL) in to omogoča prestrezanje ali "prisluškovanje". Resno grožnjo predstavlja tudi to, da je mogoče piškotke "ukrasti" z napadi XSS. Ker pogosto vsebujejo informacije o seji uporabnika, lahko napadalec to izkoristi, in "ugrabi" sejo (session hijack), npr. po tem, ko smo se z geslom ali celo certifikatom prijavili v spletno trgovino ali banko.... Kraja piškotkov je mogoča že s preprostim vstavljanjem ukaza "document.cookie" v naslov URL ali ukaz POST.

    Navedimo primer spletne strani restaurant.com, ki s pomočjo piškotkov vodi evidenco kupcev. Spremljajo jih ob pomoči polja ShopperEmail. Napadalec lahko "ugrabi" seje oz. se izda za drugega uporabnika z modifikacijo piškotka, in to s spremembo vrednosti omenjenega polja. Celoten postopek je podrobno opisan na spletni strani www.informit.com/guides/content.asp?g=security&seqNum=232&rl=1.

    Primer prikazuje, kako preprosto je zlorabiti piškotke, če ni skrbnik spletne strani pazljiv in se ne zaveda tveganja, ki ga prinašajo piškotki.

    Vtičnik AnEC za Firefox, ki omogoča delo s piškotki

    Protiukrepi proti napadom

    Pri razvoju spletnih aplikacij, ki zahtevajo vnos uporabnika, je treba biti pazljiv in "sumničav" do vseh zunanjih vnosov. Če spletna aplikacija ne uporablja posebnih podatkovnih tokov ali vnosov prek zaprtih omrežij, razvijalci pogosto uporabljajo spremenljivke URL vrstice za prenos oz. vnos parametrov. Brskalnik URL parametre prenaša ob pomoči ukaza HTTP GET, zaradi česar jih imenujemo tudi spremenljivke GET. Večina skriptnih programskih jezikov uporablja parametre ali kot globalne spremenljivke (angl. global variables) ali kot urejeno polje (angl. array) - prva možnost je bolj tvegana, druga manj. Pozornost je treba posvetiti globalnim spremenljivkam, saj so pogosto tarča manipulacij. Manj znano je to, da so tudi vse spremenljivke POST, torej vidna in nevidna polja vnosnih polj, lahko nevarne. Brskalnik jih posreduje spletni aplikaciji ob pomoči ukaza HTTP POST, tako da lahko tudi v tem primeru pride do zlorab. Zelo priljubljeni piškotki, ki jih uporabljamo za shranjevanje uporabnikov nastavitev, so lahko šibka točka in pogosta tarča napadalcev. Razvijalci morajo biti previdni tudi pri lokalnih datotekah, kot so različni strežniški dnevniki (angl. server logs).

    Zaradi vseh omenjenih nevarnosti je treba preverjati veljavnost vhodnih podatkov. Če je mogoče, omejiti zalogo vrednosti vnosnih parametrov (pri številih ali znakovnih nizih). Navedimo primer: omejitev vnosa rojstnega datuma od leta 1950 do aktualnega datuma. Če vnašamo imena, jih omejimo na velike in male črke. Taki in podobni ukrepi lahko preprečijo marsikateri napad.

    Treba je filtrirati posebne zanke, ob pomoči katerih se velikokrat izvedejo napadi. Določene funkcije za obdelavo znakovnih nizov je mogoče pretentati z znaki "Null-Bytes" in "Newline". Kot kritične je treba obravnavati vse večpomenske znake (posebni znaki, ključne besede itd.). Pri aplikacijah, ki za prikaz gradijo kodo HTML, je treba biti pozoren na ostre oklepaje (>, <), ki se uporabljajo pri značkah HTML (angl. HTML tags) in pri različnih skriptnih jezikih, in znake, kot sta odstotek (%) in znak &.

    Primeren način, da se izognemo omenjenim napadom je filtriranje z belim seznamom (angl. white list) - na seznam uvrstimo vse dovoljene znake. Drug pristop je črni seznam (angl. black list), na katerem so vsi prepovedani znaki.

    Če ni mogoče omejiti domene vnesenih podatkov na pregledno množico, je priporočljivo uporabljati tehniko "Escaping". S tem onemogočimo funkcionalnost vsem posebnim in nadzornim znakom (jih interpretiramo kot alfanumerične znake). Seveda pa je treba paziti, da ne onemogočimo funkcionalnosti spletne aplikacije.

    Večina skriptnih jezikov ima posebne funkcije za delo z nizi in vhodnimi podatkovnimi tokovi. PHP, na primer, vsebuje množico funkcij:

  • htmlentities() - zamenja vse posebne znake v datoteki HTML s kodnimi znaki HTML; na primer ""< z "&lt",
  • addslashes() - doda poševnico pred vse narekovaje,
  • mysql_escape_string() - filtrira znakovne nize glede na specifike ukazov MySQL.
  • Za vse, ki delate s PHP, je priporočljivo prebrati razdelek "Security" v navodilih PHP (angl. users manual).

    Pogosto so težave pri modularno zasnovanih aplikacijah. Možno je namreč pognati modul spletne aplikacije, čeprav je bilo predvideno, da ga lahko kliče samo osrednji del programa - primer zgoraj omenjenih vtičnikov phpBB. Pomembno je, da module varujemo pred neposrednimi klici, saj lahko preprečimo marsikateri napad. V PHP je mogoče vnaprej nastaviti defined ('_GLOBAL_VALUE') or die ('Error - direct access to the module!');

    In tako preprečiti neposreden dostop do modulov. Tak skript je mogoče klicati le prek drugih skriptov, in sicer ob pomoči ukaza define ('_GLOBAL_VALUE', null);

    Za preprečevanje vrivanj SQL je priporočljivo, da uporabljamo t. i. pripravljena povpraševanja (angl. Prepared Statements). Pojem označuje vnaprej pripravljene izraze SQL in njihove krajevne vsebnike (angl. placeholders). Krajevni vsebniki omogočajo ločevanje podatkov in izraza SQL. Navedimo primer krajevnega vsebnika:

    $query = $sql->prepare("select * from users where name = ?");

    $query->execute($user_name);

    Večina zbirk podatkov podpira krajevne vsebnike. Z uporabo omenjene tehnike tudi omogočimo ločeno posredovanje vrednosti krajevnih vsebnikov in SQL ukazov API in tako preprečimo SQL vrivanja. PHP podpira krajevne vsebnike od različice 5 naprej, in sicer z razširitvijo (angl. extension) mysqli.

    Veliko napadov je mogoče preprečiti že s pravilno konfiguracijo in pazljivostjo pri nameščanju skriptnega okolja. S pravilno nastavljenimi parametri lahko onemogočimo nevarne funkcije ali preprečimo zlorabo operacij in opcij. Smotrno je razvijati spletne aplikacije v omejenem okolju, v katerem upoštevamo načelo najmanjših pravic: "Čim manj pravic imajo spletne aplikacije, tem manj škode lahko povzročijo."

    V primeru skriptnega jezika PHP lahko v konfigurcijski datoteki php.ini nastavimo naslednje pomembne parametre:

  • register_globals = off - preprečimo, da HTTP zahtevki in piškotki prepišejo globalne spremenljivke. Nastavitev omogoči prenašanje spremenljivk s pomočjo polj, kot je $_REQUEST. S tem onemogočimo, da napadalec zlorabi neinicializirane spremenljivke ali prednastavljene globalne spremenljivke.
  • allow_url_fopen = off - Omogočimo samo uporabo lokalnih strežniških datotek. Tako onemogočimo napadalcu nalaganje skript z drugih lokacij (strežnikov).
  • safe_mode = on - Ta možnost omeji dostop do datotek in imenikov, ki so v lasti uporabnika, ki poganja skript PHP. Varni način (angl. Safe-mode) tudi onemogoči "nevarne" funkcije, kot so shell_exec().
  • open_basedir = /pot_do_www_imenika - Omeji dostop do datotek; dovoljen je dostop do podimenikov, hkrati pa ni mogoč dostop iz imenika (na primer do datotek, kot je /etc/passwd).
  • display_errors = off - Oteži pripravo napada, saj onemogoči prikaz napak. Za določene napade je pomembno, da napadalec pozna pot do spletne aplikacije. Podatke o poti je ponavadi mogoče dobiti iz različnih sporočil o napakah. Ta izbira pa prepreči prikaz takih sporočil, ki jih lahko načrtno "provocirajo" napadalci.
  • To so le nekatere izmed nastavitev, ki otežijo napade ob uporabi PHP. Več bralec najde ob pomoči povezav na koncu članka. Seveda pa pazljivost pri nastavitvah ni odveč, saj lahko onemogočimo delovanje spletnih aplikacij ali strani.

    Največjo težavo za varno uporabo PHP predstavljajo t. i. gostitelji (angl. shared-host). Zaradi zagotavljanja združljivosti in zadovoljevanja različnih zahtev uporabnikov skrbniki gostiteljskih strežnikov pogosto uporabljajo "nevarne" nastavitve PHP. Pomemben dejavnik za varnost spletnih aplikacij je tudi pravilna konfiguracija in vzdrževanje strežnikov in omrežja, v katerem je strežnik. Če se napadalec dokoplje do prijavne datoteke podatkovnega strežnika (angl. Login file), so varne nastavitve brezpredmetne. Prav tako je priporočljivo omejiti dostop do strežnikov - tudi v tem primeru velja, da se mora držati načela najmanjših pravic.

    Za preprečevanje zlorab piškotkov je najučinkoviteje, če jih preprosto onemogočimo. Seveda to marsikdaj ni mogoče, zato je morda dobro, da določene domene dodamo na t. i. črni seznam in tako označimo piškotke, ki jih ne želimo prejeti (jih blokiramo). To lahko storimo, na primer, v brskalniku Firefox prek nastavitev.

    Blokiranje določenih piškotkov v brskalniku Firefox

    Za konec

    Spletni napadi še zdaleč niso rekli zadnje besede. Ko najdemo način, kako preprečiti trenutno aktualne, se že pojavijo novi. Zaradi časovnega in finančnega pritiska razvijalci velikokrat spregledajo kakšno pomembno stvar ali načrtno zanemarijo varnostne vidike izdelka. Tako se pojavljajo nove in nove razpoke in špranje, ki jih napadalci s pridom uporabljajo. Varnostna merila je tako treba določiti že v fazi načrtovanja in jih vključiti v ceno izdelka. Le tako je mogoče dvigniti kakovost izdelka, kar zadeva varnost. Pri delu z osebnimi podatki je priporočljivo izdelati varnostni načrt in varnostno politiko ter tako določiti morebitna tveganja. Za konec še naslednja misel: "Varnost ni stanje, temveč proces, ki se venomer razvija."

    Koristne povezave:

  • Spletna stran Phishmarkt s primeri napadov, baseportal.com/baseportal/phishmarkt/de
  • Informacije o (ne)varnostni piškotkov, www.informit.com/guides/content.asp?g=security&seqNum=232&rl=1
  • PHP manual, www.php.net/manual/en
  • PHP Safe-mode maual, si.php.net/features.safe-mode
  • The Cross Site Scripting (XSS) FAQ, www.cgisecurity.com/articles/xss-faq.shtml
  • Detection of SQL Injection and Cross-site Scripting Attacks, www.securityfocus.com/infocus/1768
  • SQL injection na Wikipedii, en.wikipedia.org/wiki/SQL_injection
  • Steve Friedl's Unixwiz.net Tech Tips, SQL Injection Attacks by Example, www.unixwiz.net/techtips/sql-injection.html
  • Christiane rütten, Tobias Glemser, Gesundes Misstrauen: Sicherheit von Webanvendungen, c't 26/2006
  • Spletne stran vtičnika AnEC za Firefox, addneditcookies.mozdev.org
  • Podjetje Informit, www.informit.com
  • ph

    Komentirajo lahko le prijavljeni uporabniki