Hogyan védjem meg a portálomat?
 Sziasztok!
Készítettem egy portált J2EE-ben, és az lenne a kérdésem, hogy milyen lépéseket kell tennem, hogy 'teljesen' biztosnágos legyen?
Én fejlesztő vagyok, a Tűzfalakkal, mások foglalkoznak, tehát első sorban a fejlesztéssel kapcsolatban szeretnék tanácsot kérni.
(Oracle adatbázist használunk linux alatt GlassFish az application server...)
ami a kockázatosabb rész lehet:
* Fájl feltöltés (képek és pdf lehet | csak a kiterjesztést vizsgálom)
* különb.. |

Én nem látom megjejölve fent, hogy miről szól a téma, a cím alapján meg bármi lehet, nem csak java...  |
Hali!
...mert ugye java-ról beszélgetünk továbbra is, nem php-ról.
Hát... amennyire a szerény képességeimmel meg tudom ítélni, aistvan hozzászólásában (2010.03.19 20:54) - amire reagáltam - található forrás nekem PHP-nek tűnik. De javíts ki, ha tévednék. 
 |
Összeroppantam érveid súlya alatt.  |
általában meg mondjuk ValidationUtils.isNumeric() vagy már a framework eleve tipusosat vár pl Integer/int esetén, és typeMismatch-ot dob ha olyan az input. mert ugye java-ról beszélgetünk továbbra is, nem php-ról.  |
nem sting, nincs igazad 
vagyis csak félig, de alapvetően nem annyira  |
Azóta már ezt én is előástam, csak akkor még a ctype_digit függvényről nem tudtam Erre csináltam egy is_positive_int() függvényt is, így egyszerűbb használni.  |
Hali!
Ötlet:
$id = $_REQUEST['id']; if (ctype_digit($id) && $id > 0) { // mehet } else { // nem mehet }
 |
Ahogy már mondták, ez ágyúval verébre - ráadásul ha már regexpet használsz (mert mondjuk egy komolyabb kifejezésellenőrzés részeként kell, mint csak egy sima integer-vizsgálat), akkor '[0-9]' helyett lehet használni '\d'-t, a '[0-9][0-9]*' helyett meg '\d+'-t. (Ez utóbbi ugyan nem ekvivalens a te vizsgálatoddal, mert bevezető nullákat is megenged, de azok úgysem zavarnak be sehol.)  |
Ugyanerre jó az is_int() függvény is, de az negatív számra is igaz eredményt ad, azért nem tetszett.  |
lehetne (int)$_REQUEST["id"];
Ilyenkor ugye 0-t kapsz ha nem szám volt.  |
Ugye előfordul, hogy egy adatbázis id-t kell get vagy post paraméterként átvinni. Ez alapvetően csak pozitív egész érték lehet, ezért én erre a következő ellenőrzést szoktam használni:
$id=$_REQUEST['id']; if (preg_match('/^[1-9][0-9]*$/',$id)) { // mehet } else { // hibauzenet }
Vélemény? |
Védekezni úgy lehet, hogy például vannak olyan pdf könyvtárak, amellyel meg lehet nézni, hogy a pdf tartalmaz-e javascript-et.
Ez nem védekezési módszer, mert amíg a sebezhetőségre nem derül fény, addig ugye nem tudsz scannelni az exploit kód után sem. Utána pedig azért nincs már sok értelme, mert rövid időn belül foltozásra kerül a rés, és mivel itt egy auto-update szoftverről van szó, ezért az installált bázis >95%-a immunissá válik a támadással szemben. Ráadásul a te módszereddel az esetleg teljesen legitim, egyáltalán nem rosszindulatú PDF-eket is kiszűrnéd, ami megintcsak rontja az oldal használhatóságát - elég sok ilyen "biztonsági ellenőrzést" beépítve teljesen használhatatlanná téve azt.
Ráadásul mint mondtam, a PDF-eken kívül akármilyen más kliens-oldali szoftverben lehet sebezhetőség, amely ugyanolyan veszélyes vagy még veszélyesebb is lehet. Ezeknek a hibáknak kezelése ill. a hibák kihasználása elleni védelem egyszerűen nem lehet egy általános célú weboldal feladata, és mint a példa mutatja, nincs is sok értelme energiát feccelni ebbe. Mert egy rést lezársz, és még mindig marad tízmillió, és mert sokszor legitim tevékenységek is lehetetlenné válnak ezáltal.
Esetleg idegen domainre lehet helyezni a pdf kiszolgálását.
Ez a konkrét XSS sebezhetőség ellen véd, de pl. azok a tízszer veszélyesebbek ellen nem, amelyek mondjuk puffertúlcsordulás kiváltásával tetszőleges kód futtatását teszik lehetővé. Szóval összességében szinte semmi haszna nincs (a külön domainre rakásnak), cserébe viszont jól megbonyolítja a dolgokat.
A Content-Disposition: attachment pedig addig ér valamit, ameddig a felhasználó nem dönt másképpen, és nem böngészőben nyitja meg.
A fenti fejlécnek pont az az értelme és a hatása, hogy csak a mentést teszi lehetővé, azaz hogy a böngésző le is tiltsa (vagy meg se jelenítse) a megnyitás gombot ha ilyen választ kap. (Erre még rá is lehet erősíteni egy "application/octet-stream" MIME típussal, ami elméletileg szintén a megnyitási opció eltűnését vonja maga után, legalábbis az ajánlást pontosan követő böngészőkben, mert pl. az IE szeret ilyenkor is automatikus típusdetekciót alkalmazni a magic byte-ok alapján, ami hatástalanná teszi az egészet.)
De mint mondtam, mindez megint nem túl sokat ér a biztonsági réseket, hibákat kihasználó exploitok ellen, hiszen semmi sem akadályozza meg a felhasználót, hogy lementés után nyissa meg az állományt, ami százszor csúnyább dolgokat művelhet, mint a sütik ellopása.  |
Védekezni úgy lehet, hogy például vannak olyan pdf könyvtárak, amellyel meg lehet nézni, hogy a pdf tartalmaz-e javascript-et. Esetleg idegen domainre lehet helyezni a pdf kiszolgálását.
A Content-Disposition: attachment pedig addig ér valamit, ameddig a felhasználó nem dönt másképpen, és nem böngészőben nyitja meg.
Egyébként nekem mindegy, itt csak eszmét cserélünk, például én sem védekeztem még soha a pdf ellen.  |
Ezért sztem mindenféle idegen aktív tartalom befogadása rizikó. Tehát védekezni kell ellene.
Igen, de vedd észre, hogy itt nem egy perzisztens fícsörről, hanem egy hibáról van szó, ami ráadásul elvileg már javításra került, tehát máris nem állja meg a helyét az állításod (mely szerint ez jelenleg is problémát jelentene). Ráadásul ez önmagában sovány alap a PDF-feltöltés letiltására, hiszen hasonló - ill. még veszélyesebb - sebezhetőségek voltak már képekkel is, így ennyi erővel még azt is le lehetne tiltani - visszakatapultálva magunk a két évtizeddel ezelőtti internet korába.
A konkrét esetben ráadásul pl. a böngészőablakban történő megnyitás letiltásával és a letöltés kikényszerítésével (Content-Disposition: attachment) kihúzható a dolog méregfoga anélkül, hogy magát a feltöltést, megosztást korlátozni kellene.
Ezért sztem mindenféle idegen aktív tartalom befogadása rizikó. Tehát védekezni kell ellene.
Hogyan? Az egyetlen tuti védekezés az itt említett dolgok ellen csakis a feltöltés, megosztás teljes tiltása lehet. Ha azonban az oldal célja pont ez, akkor ez nem opció (ha meg nem ez az oldal célja, akkor nem is jelenthet fenyegetést hiszen nincs is ez a lehetőség).
Nem. A védekezés a szóban forgó esetekben a felhasználó ill. az általa készített szoftverek készítőinek a dolga. Egy adott exploitot kihasználó rosszindulatú állomány weboldalon keresztüli megosztása és letöltése pedig abszolút nem nagyobb és nem más fenyegetés, mint ugyanez a fájl elküldése és fogadása emailben, amitől szintén semmi nem tartja vissza a támadót, a megnyitástól pedig az áldozatot, saját józan eszén, óvatosságát, és harmadik felektől származó védelmi technológiákat leszámítva.
Egyszerűen tudomásul kell venni, hogy teljes, tökéletes biztonsági nincs (a valós életben sem). Aki nem tud ezzel együttélni az ne nyissa meg a böngészőt!  |
Például ez nem is olyan régi cikk: link. Acrobat reader 9-ig bezárólag leírja, hogy hogyan éri el a hívó html dom-ját, természetesen a cookie-ját is stb. a böngészőben. Már is kész egy jó kis session lopás.
Ezért sztem mindenféle idegen aktív tartalom befogadása rizikó. Tehát védekezni kell ellene.  |
Hát, azért ez nem így működik. Volt valami ilyen sebezhetőség több évvel ezelőtt, de az is azért működött, mert magában az Adobe Reader pluginben volt egy biztonsági rés - és az sem magában a PDF-ben elhelyezett JavaScript kód futtatását tette lehetővé a befogadó oldal kontextusában. Ezt azonban már rég foltozták.  |
Mivel pdf-et is engedsz feltölteni, azt tudnod kell, hogy a pdf-ben javascript kódokat is el lehet helyezni, és azzal a portálodon tetszőlegesen futtatható idegen javascript kód, ha a pdf-et megtekintik, és a pdf reader-ben a javascript futtatása nincsen letiltva.  |
Pl. azt, hogy URL-ben tárolod a session-azonosítót süti helyett. Süti esetében ugyanis az említett hiba nem okozott volna problémát, mert a süti magától is lejárt volna, ráadásul onnan nem olyan egyszerű kivadászni a session-azonosítót, mint az URL-ből, amit ráadásul pl. a böngésző előzményeiből úgy lehet előhívni, hogy nem is kell különösebben bányászni utána (tehát még az egybites júzer is képes rá).
Ezen kívül a sessionben (session tömbben vagy a sessionhöz kapcsolódó perzisztens containerben) magában nem szabad semmilyen olyan adatot tárolni, ami változhat a session során (az oldalletöltések között), beleértve a felhasználó jogait (vagy egyáltalán hozzáférési jogosultságát a rendszerhez) sem, hanem ezeket minden egyes oldalletöltéskor újból be kell tölteni az adatbázisból. Itt annyi engedhető meg maximum, hogy teljesítményokokból pl. ugyan tárolható ez az információ informatív jelleggel, és mondjuk a menü felépítésénél felhasználható, de a konkrét műveletek elvégzése előtt - különös tekintettel a POST oldallekérésekre, amik általában magát a végrehajtást takarják - mindig rá kell ellenőrizni ezekre az adatokra az élő, kurrens adatbázis alapján (ti. hogy rendelkezik -e a felhasználó a megfelelő jogokkal). Egyéb esetben könnyen előfordulhat, hogy a felhasználó elméletileg elveszti a jogait (pl. mert lejár az előfizetése, hozzáférése), de a session mesterséges nyitvatartásával - ha annak életére pl. nincs felső korlát meghatározva - akár még hónapok múlva is hozzáférhet a rendszerhez, olyan jogokkal, amik már rég megvonásra kerültek tőle.
Ezen kívül a sesssion információkat mindig szerveroldalon kell tárolni, nem szabad pl. a <form> részeként, rejtett mezőben ide-oda futtatni sem, hiszen az rendkívül könnyen manipulálhatóvá teszi azt. (Szokás még olyan megoldást alkalmazni, hogy valami egyedi salttal kódolva ill. checksummolva mégis a form adatok részeként tartják nyilván és küldözgetik a session információkat, de ez is elméletileg sebezhető - szemben a szerveroldali tárolással, ami by design manipulálhatatlan -, és egyébként is belassíthatja a kommunikációt ha sok adatot kell ide-oda küldözgetni így minden egyes oldalletöltéskor az oldal ill. visszafelé a form-adatok részeként.)  |
Én egyszer belefutottam abba, hogy kijelentkezéskor nem invalidáltam megfelelően a sessiont, így ha késöbb visszaírta az url-t akkor le lehetett halászni az adatokat.
Milyen hibákat lehet még elkövetni tervezéskor?
|
Kezded kapiskálni  |
hűűha háát szerintem te zseniális vagy... Nagyün ügyes... De tényleg...
Olyannyira, hogy neked sztem nincs is szükséged rá, hogy ezt a fórumot használd!  |
Háát igen ezt én is igy tanultam az iskolában..
Csak sajnos a való életben általában úgy van, hogy bejön a megrendelés, aminek tegnapra kész kell lennie, majd ha van idő akkor foglalkozok a részletekkel is...
(Na jó, azért most egy kicsit túloztam, vannak olyan technikáink, amiket mindig alkalmazunk biztonság téren...
(sql injectionnal pl nem lehet matatni...)
Ebben a kérdésben igazábol össze szerettem volna gyűjteni, hogy milyen kockázati tényezők lehetnek egy portálnál.
)  |
@google:
java/j2ee develop secure web application
Nem tudom mi ebben a nehéz, csak én tudom használni a googlet???  |
"Készítettem egy portált J2EE-ben"
Bocsi, hogy nem lesz túl hasznos a hozzászólásom, de ez a mondat egyből megütötte a szemem, mivel rossz a sorrend.
Előbb megtervezem a különböző igények, paraméterek figyelembevételével (ilyen a biztonság is), majd a tervek alapján elkészítem. Az előbb elkészítem, aztán majd beletervezem a biztonságot elég reménytelennek tűnik nekem.  |
beszorult az ujjad? :D  |
jspaartaaaaaaaaaaaaaaaaaaaaaaaa  |
Én alapvetően nem aggódnék, azért használnak Java-t a biztonságot igénylő helyeken (banki környezetben például szinte csak Java fordul elő), mivel kifejezetten erőlködni kell ahhoz, hogy nagyobb biztonsági lyukak keletkezzenek rajta.
Hát én meg elég paranoid módon állok a biztonsághoz, lehet én teszem rosszul?  |
Én alapvetően nem aggódnék, azért használnak Java-t a biztonságot igénylő helyeken (banki környezetben például szinte csak Java fordul elő), mivel kifejezetten erőlködni kell ahhoz, hogy nagyobb biztonsági lyukak keletkezzenek rajta.
Szerintem abszolút nem ezért használnak, hanem mert
- többplatformos (ti. a Java alkalmazásszerver sok operációs rendszeren futtatható, Windows-tól nagygépig),
- jól illeszthető a tipikus vállalati rendszerekhez (ti. mert megvannak a magasszintű adatbáziskonnektorok, könnyű webszolgáltatások írása és hívása, stb.),
- konzisztens és átfogó alap- (vagy legalábbis standard-)könyvtárkészlettel rendelkezik, amik mind elősegítik az elkészült programok későbbi karbantartását (szemben a C++, PHP, Perl, stb. kódokkal, amelyekhez ahány fejlesztő, annyiféle könyvtárat használ ugyanarra a feladatra, ami nagy ill. hosszú távú fejlesztéseknél hátrány, hiszen az eredeti fejlesztők defektálása esetén nehéz ugyanazzal a skillkészlettel rendelkező másik munkaerőt találni, vagy akár csapatan belül másnak átadni a kód továbbfejlesztésének feladatát).
Biztonsági szempontból amúgy Java-ban és éppen olyan nehéz, vagy könnyű biztonsági rést nyitni, mint pl. PHP-ben, vagy akármilyen másik virtuális gépben futó és/vagy interpretált nyelvben. Ezekben ugyan a puffertúlcsordulásból adódó biztonsági rések keletkezése szinte kizárt (a nyelv szerkezetéből és a futtatás módjából adódóan), ugyanakkor SQL injekcióval, XSS-sel, stb. szemben a Java éppen úgy sebezhető, mint a PHP, C, Delphi, Perl és szinte akármilyen másik nyelv.
A másik oldalon a PHP alapvetően semmivel sem rosszabb biztonsági szempontból, mint akármelyik másik nyelv (sőt, C/C++/Delphi-nél tuti jobb), csak éppen azon programozók nagy részének, akik ezen a platformon fejlesztenek, fingjuk sincs a biztonságról, és ezért nyitnak ill. hagynak praktikusan tervezési biztonsági réseket az alkalmazáson (lásd az előző példát ahol az SQL lekérdezést sztringkonkatenációval állítják elő a normális, paraméteres megoldás helyett). De ez nem a platform, vagy a nyelv hibája, hanem a programozóé (ill. aki annak csúfolja magát).  |
amiket olvastam a neten, azok alapján úgy nézki, hogy az MS-es adatbázisok, a Firebird, és a MYSQL van kitéve inkább ennek a veszélynek...
Az hogy a fejlesztő így
sql="insert into tábla (...) values (" + mező1 + ", " + mező2 + ")"
akarja összerakni az sql utasítást nem adatbázis függő,
ezt ha nagyon akarom Oracle alatt is megtehetem...  |
php strip_tags()
Hm... úgy vettem észre Java-ról van szó.
Namost a Java (JDBC esetén PreparedStatement esetén, de főleg a JPA használatával) by design védett olyasmi ellen, amiről egész eddig beszéltetek PHP tudással átérezve a helyzetet.
Ha nincs szükség valamilyen HTML editorra (CKEditor, stb) a felületen, akkor az XSS is elég könnyen lerendezhető.
Én alapvetően nem aggódnék, azért használnak Java-t a biztonságot igénylő helyeken (banki környezetben például szinte csak Java fordul elő), mivel kifejezetten erőlködni kell ahhoz, hogy nagyobb biztonsági lyukak keletkezzenek rajta.
--
http://www.javaforum.hu  |
|