Cross-site scripting
Napjaink egyik leggyakoribb támadási formája a weboldalakon. De mi is ez valójában?
Az elv elég egyszerű. Legyen a példa egy híroldal, ahova az emberek különféle híreket küldhetnek be, ami megjelenik a főoldalon. Ha a hírekben a HTML tag-eket nem szűrjük ki, vagy legalábbis nem korlátozzuk a használatukat, máris egy XSS támadás potenciális résztvevőjévé avanzsáltuk oldalunkat. Amennyiben engedélyezünk pl. iframe és/vagy script tag-eket, a rosszindulatú felhasználó szinte azt kezd az oldalunkkal, amit csak akar. Az iframe nyilván egyértetlmű, hogy mire használható, így nézzük inkább a script veszélyeit.
A script tag
Tegyük fel, hogy scripteket futtathatunk, természetesen az oldalt olvasó felhasználó tudta nélkul. A javascript egy nagyon csodálatos eszköz, gondoljuk csak bele, hogy milyen dolgokat tudnak művelni vele egy jó AJAX-os weblapon! És mindez azért lehetséges, mert a JS-bol a DOM (Document Object Model) teljes mértékben elérhető, átszabható. Mit is jelent ez? Azt, hogy ha JS-t futtathatunk, akkor úgy alakítjuk át az oldalt, ahogy nekünk tetszik. Ezáltal pl. jelszavakat tudunk lopni, esetleg más nevében hajthatunk végre műveleteket (pl. hírek törlése, módosítása), illetve akár böngésző hibákat kihasználva támadhatjuk az oldal látogatóit is.
Mielőtt egy konkrét példát hoznék fel, nézzük meg, hogy milyen típusai vannak egy XSS támadasnak:
DOM alapú XSS
Egy ilyen támadás kivitelezése nagyon egyszerű. Az alapja az, hogy pl. az oldal GET paraméterei között van olyan, ami közvetlenül bekerül a generált HTML kódba, így csak egy megfelelően összeállított URL-t kell elküldeni valamilyen IM klienssel vagy e-mailben a kiszemelt áldozatnak, aki rákattintva megkapja a manipulált weboldalt. Ebben a legnagyszerűbb dolog az, hogy a legtöbb böngésző ezt nem szűri ki. Pl. az Internet Explorer, ha egy másik zónából szeretnék scriptet futtatni, letiltja, de ebben az esetben ugyanabban a zónaban fog futni, mint amiben a weboldal. Ez természetesen azt jelenti, hogy a böngésző végrehajtja a parancsainkat.
Nem perzisztens XSS
Ez az előzőhöz hasonló, a külonbség csak annyi, hogy ebben az esetben az oldalon autentikált felhasználó értekes adataihoz is hozzá lehet férni. Ezeket szintén lehet hamis e-mailekkel végrehajtani, tehát ehhez is kell, hogy a felhasználó rákattintson az előkészített linkünkre. Ilyen esetekben pl. a sütiket is ki lehet csalni a böngészőtől, és pl. elküldeni magunknak. Ha az oldal session kezelése nincs bebiztosítva, akkor simán lehet akár session-t is lopni, és onnantól kezdve teljes mértékben azt csinálunk a felhasznaló nevében, amit akarunk.
Perzisztens XSS
Perzisztens XSS-ről akkor beszélünk - meglepő módon -, ha az injektált HTML tartalmat a szerver tárolja, és újra ki is rendereli egy oldalra. Ilyenek pl. a különféle üzenetküldők, hírezok stb., ahol lehet HTML formázást is használni. Jellemzően ez a legveszélyesebb mód, léven egy forgalmas oldalon felhasználók ezreinél-millióinál is megjelenhet a manipulált tartalom naponta. Ezzel lehet pl. akar tömegesen vírusokat, férgeket is terjeszteni az interneten.
Élő példa
És akkor most jöjjön az életből való példa, ami a legutolsó - tehát a perzisztens XSS - kategóriába fog esni.
A cél oldal a chat.hu. Az oldalon van üzenetküldési lehetőség. Az üzenet törzsében jól kiszűrték a HTML tag-eket, az címében viszont nem. Így ha valakinek küldtem egy megfelelo címmel ellátott üzenetet, amikor az megjelent az üzenet listában, végrehajtotta a JS-emet. Mivel nem célom rossz szándékkal támadni oldalakat, így csak egy kis PoC kódot csináltam hozzá, ami a gyanútlan felhasználók jelszavát probálta kicsalni. Ezt úgy probáltam elérni, hogy amikor megjelentek a levelek, feldobtam egy szép kis login ablakot. Ha ebben a user beírta a nevét és jelszavát, elküldtem magamnak az oldalon belüli üzenet küldő szolgáltatással. Még teszteles közben valahogy így nézett ez ki:

Mivel a cím hossza limitált, így a kódot nem helyben valósítottam meg, hanem a saját gépemen futó webszerverről include-oltam. Ugyanilyen hibát találtam még máshol is az oldalon. Ezeket már időközben kijavították mindegyik, ilyen engine-t használó websitejukon.
De hogy dobtam fel egy login képernyőt, ami ráadásul pontoan úgy néz ki, mint az eredeti?
A válasz: DOM. JS-ből a DOM elérhető, szerkeszthető. Szimplán raktam egy nagy -et az oldalra, kis áttetszősséggel, amire felpakoltam az eredeti login képernyő stílusával rendelkezo formot. Kb. fél órás munka volt, de csak azert, mert szerettem volna, ha teljesen megegyező kinézetet produkál a script.
Mit lehet ez ellen tenni?
A védekezés mind user, mint webes fejlesztői, mint böngésző fejlesztői oldalon roppant fontos. A felhasználó legjobban különféle böngészőpluginek (pl. NoScript) és a józan ész segítségével (nem kattint minden linkre rá) védekezhet. A weboldal fejlesztőinek pedig a beviteli mezőket minden esetben szűrni kell. A legjobb, ha egyáltalán nem engedélyezünk HTML formázást, vagy nagymértékben limitáljuk a felhasználható tag-eket. A legjobb, ha teljesen más módon formáztatjuk a felhasználókkal a szövegeket (pl. BBCode). A session ellopása ellen pedig legfeljebb annyit lehet tenni, hogy a session id-t csak akkor fogadjuk el, ha az ip-cím is egyezik, esetleg még vizsgálhatjuk a böngésző egyezését is.
Köszonet a Wikipedia-nak a sok kiegészítő informácioért, amit ebben a bejegyzesben is felhasználtam.