2009. március 18., szerda

Webalkalmazások biztonsági hibái - 4. Kliensoldali input kontrollok

Betörési tesztjeink során gyakran találkozunk azzal a jelenséggel, hogy a weboldalak fejlesztői ugyanazokat a hibákat követik el újra és újra. Ezen klasszikus hibákat egy több részből álló sorozatban szeretnénk bemutatni.

Minden webalkalmazás fogad valamilyen formában klienstől (felhasználótól) származó inputokat. A felhasználói inputokkal kapcsolatos első számú aranyszabály az, hogy a webalkalmazásnak soha nem szabad bennük vakon megbíznia bennük: a felhasználótól érkező, nem várt formátumú inputok könnyen hibát okozhatnak az alkalmazásban (hibaüzenetet generálva ezzel), esetleg lehetőséget adhatnak klasszikus injection támadásra (SQL, script, LDAP, XML,...) Nyilvánvaló, hogy az alkalmazásnak szerveroldalon kell eldöntenie egy kérésről, hogy érvényes, vagy ártó szándékú inputokat tartalmaz-e, de gyakori megoldásként kliensoldali kontrollokat is alkalmaznak a fejlesztők az inputok szűrésére.

Sok biztonsági tesztelő a kliendoldali kontrollokat egyértelműen "felfedezésként" azonosítja a jelentésben, ugyanis a legtöbb módszert több-kevesebb energia belefektetésével ki lehet kerülni. Jelen sorok írója szerint azonban megvan a kliensoldali ellenőrzéseknek is a maguk létjogosultsága, azonban nem biztonsági kontrollként, hanem a felhasználói élményt javító "fícsör"-ként. Lássuk, milyen tipikus kliensoldali kontrollokkal találkozunk a tesztelési munka során!

A felhasználó számára (egyszerű eszközökkel) módosíthatatlan adatok.
A leggyakoribb és legegyszerűbb megoldásban a kliensnek küldött oldallal adatokat küld az alkalmazás, és arra épít, hogy a kiküldött adatokat változatlan formában kapja vissza. Session azonosító, felhasználói név, egyéb hitelesítési adatok - minddel találkoztunk már. Tipikusan az alábbi megoldási módokat akalmazzák széles körben:
  • Hidden html form mezők. A html lehetőséget biztosít arra, hogy hidden mezőket tegyünk a formokra, amik a felhasználó számára láthatatlanok, viszont a form elküldésekor a webalkalmazás megkapja.
  • Http cookie-ban tárolt információk. A cookie-k egyszerű lehetőséget kínálnak arra, hogy az alapból állapotmentes http protokollba állapotokat csempésszünk. Működésük egyszerű: a http válasz headerjében a set-cookie paranccsal lehet írni őket, a kliens pedig minden, az adott domainbe küldött http kérésbe beleteszi a domainben érvényes cookie-k adatait. Két fajtájuk van: permanens (a böngésző bezárása után is érvényes marad) és átmeneti (a böngésző bezárása után törlődik).
  • Flash cookie-k. A http-s cookie sok problémával küzd: implementációtól függ, hogy mekkora lehet a maximális méretük, emiatt komplex adatok tárolására nem igazán alkalmas. Emiatt a flash technológiában újfajta "cookie"-kat vezettek be: ezek nem a böngésző http cookie-jai között tárolódnak, hanem egy külön mappában (%APPDATA%\Macromedia\Flash Player Windowsban, ~/.macromedia linuxban és /Preferences/Macromedia/Flash Player Mac OSX-ben). Forensic munkáink tapasztalatai szerint a felhasználók és a felhasználói azonosíthatatlanságot védő egyszerű eszközök nem törlik a flash-es cookie-kat.
  • URL paraméterek. A legegyszerűbb mód az a megoldás, amikor a linkek és feldolgozó php-k az URL-ben kapják meg az adatokat, GET paraméterként.
  • A referer mező. A böngészők nagy része egy form elküldésekor a küldő oldal címét beleteszi a referer mezőbe. Nem túl gyakori megoldás, de találkoztunk már azzal, hogy ebben a mezőben küldik el a sessionazonosítót GET paraméterként.
Javascriptes input validáció. Gyakori, hogy az oldal valamilyen javascript segítségével ellenőrzi, hogy a felhasználó megfelelő hosszúságú, típusú stb. inputot ad az egyes beviteli mezőkhöz. Ez a megoldás azzal jár, hogy a teljes validációs logika elérhető a kliensoldalon a forrás megtekintésével, ezáltal módosítható, hiszen a böngésző futtatja.

Obfuszkált inputok. Sok esetben alkalmaznak obfuszkálást a felhasználónak küldött, majd változatlanul (illetve legitim módon megváltoztatva) visszavárt inputokkal való machinálás megnehezítésére. A sessionazonosító gyengeségeit tárgyaló részben több esetet is mutattunk, amelyben a sessionazonosító valamilyen obfuszkált információt is tartalmaz az adott sessionről. Az ott tárgyalt problémás megoldások tetszőleges felhasználó oldali input egyfajta validációs techikáiként is felfoghatóak: gyakori megoldásként valamilyen értelmes, az alkalmazás logikáját befolyásoló adatot base64-gyel kódolva teszik ki a klienshez.

Hibrid biztonsági kontrollok helytelen használata. Az ASP-ben bemutatott ViewState technológia megfelelő használat esetén egyfajta hibrid kontrollként is felfogható a felhasználói interakció kezelése során. A ViewState-et használó oldalak egyetlen, rendszerint hidden paraméterként átadott változóban tárolják a felhasználó/oldal a megvalósított logika szerinti teljes állapotát (tehát ide tartozik minden azonosítási adat és minden olyan adat, ami fontos a megvalósított logika szempontjából). A ViewState mező base64-encodinggal kerül továbbításra, emiatt önmagában nem tekinthető biztonsági kontrollnak: azonban az ASP lehetőséget ad arra is, hogy "aláírják" egy kulcsolt hashfüggvénnyel ezt az értéket, amit az EnableViewStateMac="true" sorral kapcsolhatunk be az oldal forrásában - ez az opció már védelmet nyújt a felhasználó oldalán történő megváltoztatás ellen (legalábbis jelzi, hogy nem érvényes a hash).

Mi a gond a fenti megoldásokkal, ha biztonsági kontrollként alkalmazzák őket? Az, ami a legtöbb kliensoldali kontrollal: triviálisan kikerülhetők, ugyanis ezen kontrollok csak addig a pontig működnek, amíg a felhasználó meg nem nyomja a "submit" gombot. Számos olyan eszköz elérhető (pl. owasp webscarab, burp suite, paros proxy), amelyek a localhoston http proxyként működnek, ezáltal lehetőséget adnak a http-kérés tetszőleges részének módosítására, emiatt a felhasználó felől érkező (akár kliensoldali kontrollokon is túljutott) adatokat alapvető biztonsági hiba "jól formáltnak" feltételezni.

Nincsenek megjegyzések:

Megjegyzés küldése

Kommentek