2009. június 9., kedd

Webalkalmazások biztonsági hibái - 9. Szerveroldali 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.

A biztonsági hiányosságok eddig tárgyalt területei között érintettük az inputvalidációs kontrollok témakörét: szó esett már a kliensoldaliakról, a szerveroldali kontrollok tárgyalásával még adósak vagyunk.

A szerveroldali kontrollok kiemelten fontos szerepet játszanak egy alkalmazás biztonságának szempontjából: ez az, ami "megvédi" az alkalmazás logikáját, az általa kezelt adatokat a rosszindulatú felhasználók által adott "trükkös" inputoktól. A sessionkezelés mellett ez a másik olyan terület, amit nagyon nehéz jól csinálni, viszont minden webfejlesztő beleütközik - emiatt számos példát láthatunk rosszul megvalósított validációs kontrollokra: minden olyan sikeres támadás, aminek a neve "injection"-re végződik, innét eredeztethető (SQL, XSS, Javascript, LDAP stb.)

Milyen hibák vezetnek ide?

A kerék újbóli feltalálása.
A legtöbb webprogramozó valamilyen módon megoldja az inputok validációját, azonban sok esetben saját validációs függvénycsaláddal történik a feladat megoldása: ezeket a legegyszerűbb kicselezni. Sokkal hasznosabb és hatékonyabb, ha a használt keretrendszer által biztosított validációs eszközöket használják - a keretrendszerek általában biztosítanak ilyen lehetőséget. Tessék élni velük!

Doboz típusú validáció.
Gyakori programozói hanyagság, ha a fejlesztő megírja Az Inputvalidáló Függvényt, és mindenfajta inputot ezen ereszt keresztül, függetlenül attól, hogy milyen típusú az input (szöveges, szám stb.), illetve mi fog történni az adott inputtal a továbbiakban. Ez a megközelítés csak akkor indokolható, ha (biztonság)tudatos programozói döntés eredménye, és megfelelő körültekintéssel történik az implementáció: például egy keresési mező tartalma egyrészt bekerül egy SQL query-be (SQL injection), másrészről visszaíródik a felhasználó képernyőjére (XSS) - ebben az esetben mind XSS, mind SQL injection szempontjából validálni kell(ene) a beérkező adatokat - például tipikus hiba, hogy az SQL metakaraktereket szűrik, viszont javascriptet könnyedén lehet injektálni.

Negatív szemléletű validáció.
Negatív szemléletűnek nevezünk (itt) minden olyan validációs módot, amely bizonyos nem kívánatos karakterek, minták szűrését végzi: ilyen például a <,>,\,",' stb. karakterek eplicit filterezése az SQL injection elkerülésekor.

Egy probléma van ezzel a megközelítéssel: nevezetesen az, hogy annyiféleképp lehet ártó módon injektálni az input mezőibe, hogy ezek ellen egyesével védekezni teljesen esélytelen: az XSS-injektálás lehetőségeiről kiváló XSS CHEAT SHEETet találhatni kattintás után.

Sokkal egyszerűbb és hatékonyabb megoldás az, ha pozitív módon állunk a problémához: ha számot várunk, akkor bizony illeszteni kell egy ^[0-9]*$ alakú regexpet a mezőre, és máris jóval nehezebb ártó kódot bevinni.

Egy másik példa: az böngészők is, és az MSSQL is mindenféle egzotikus karakterkódolásokat támogatnak, emiatt a kínai karakterkészletben szereplő, '-hoz hasonló karakter átjut a sima SQL metakaraktereket kereső validáción, viszont az adatbázisszerver előzékenyen kicseréli a valódi ' karakterre - ezt pedig nem nagyon lehet megfogni negatív validációval (a támadás nem túl régi, SQL smugglingnak keresztelték el.)

A validálóeszköz megrágás után továbbengedi az inputot.
Nem kevésbé veszélyes az sem, ha a validátor megpróbálja jól formálttá tenni az inputot: némi kísérletezéssel könnyen ki lehet ismerni a validátor logikáját, és kicselezni. Például tegyük fel, hogy a validátor XSS-támadás kiszűrésére a <> sztringet keresi, és szűri ki. Az alábbi két sztring például keresztüljut a PHP-s ellenőrzésen:

>< scri < script > pt > alert(document.cookie) < scr < /script > ipt>
% 00 < script > alert(document.cookie) < /script >
Az a legbiztosabb, hogy ha az alkalmazás hibaüzenetet jelenít meg, és semmiképp sem engedi tovább a folyamatot.

2 megjegyzés:

  1. Nagyon jók a cikkek és valóban sokat lehet belőlük tanulni. Én magam is elkezdtem írni egy php validátor fügvényt, de nem lett tökéletes sajnos. Aztán elkértem egy kollégától, amit ő használ, de az sem teljessen jó. Google-n is keresgéltem....
    Nem tudnának esetleg ajánlani valami jó megoldást??
    photon3d@gmail.com

    VálaszTörlés
  2. Az SQL smuggling nagyon tetszik, még nem hallottam róla :-) Jobb a prepared statement használata, a stored procedure-ben előállított, szövegként összefűzött SQL queryk meg öngyilkossággal egyenlőek, nem értem miért nincs valami épkézláb quote az adatbázisokban, ha már támogatnak ilyesmit... Akkor már jobb egy ORM a http szerveren, ha nincs más lehetőség.

    VálaszTörlés

Kommentek