PHP biztonság, hibakezelés
2009-10-05T20:04:26+02:00
2010-07-30T00:01:34+02:00
2022-07-25T01:07:31+02:00
  • Nézz utána a kivétel (angolul Exception) dobásnak.
    Mutasd a teljes hozzászólást!
  • Ez nálam úgy működik, hogy kapcsolódásnál, lekérdezésnél ha sikertelen a művelet, akkor megpróbálom még 3-szor, ha ezek után sem megy, akkor hibaoldalra irányítom a user-t.


    Szerintem teljesen felesleges 3x próbálgatni, weblapokról van szó, nem olyan rendszerekről, ahol életbevágó, hogy végrehajtsák a kérést.

    Hibakezelésről annyit, hogy semmit ne tegyél ki, ha nem muszáj. Ha elszállt az adatbázis, akkor max annyit tegyél ki, hogy "Sajnáljuk, technikai gondjaink akadtak.", ha kíváncsi vagy, hogy mi volt a gond, akkor loggold a hibát és onnan olvasd vissza.

    Nézegess ilyesmiket, hogy set_error_handler, ErrorException, set_exception_handler....
    Mutasd a teljes hozzászólást!
  • 10 sikertelen próba után tiltom 10 percre az adott ip-ről jövő próbálkozásokat.


    Szerintem ez kevés, ha több gépből álló botnettel brute forcolják a jelszót, akkor semmit sem ér. Jobb, ha a támadott fióknál is jegyzed a sikertelen próbálkozások számát, és azt tiltod le bizonyos időre, vagy captchat kérsz a hozzá való belépéshez...
    Mutasd a teljes hozzászólást!
  • Igen az, csrf-nek hívják, a lényeg, hogy ha valaki be van jelentkezve az oldaladra, akkor cookie-ban tárolódik a session id-je. Ha ilyenkor rámegy a támadó oldalra, akkor a támadó oldal postolhat az ő session id-jével, mert azt a cookie-ból kéri le a szerver. Szóval gyakorlatilag bármilyen postot el lehet küldeni a felhasználó nevében, ha be van jelentkezve.
    Elég sok böngésző támogatja a referer headert, ha megnézed, és más domainről jött a post, akkor ilyenről van szó. Kivédhető referer nézéssel, vagy ha loginkor letárolsz egy egyedi azonosítót, amit minden űrlapban visszakérsz. (hidden input)

    Ha a referer más domain, és a login oldaladra megy (és mondjuk stimmel a jelszó meg a felh név), akkor érdemes automatikusan jelszót változtatni. Ilyenkor az van, hogy eladták a felhasználónak, hogy a te oldaladra biztonságosan bejelentkezhet tőlük is, vagy egyszerűen észre sem vette, hogy más oldalon jár stb...
    Mutasd a teljes hozzászólást!
  • Az a lényege, hogy nehezebb visszafejteni, hogy mi volt az eredeti szó, ha nem ismered pontosan a kódolási módszert.
    pl:
    $salt=(string)rand(1000,9999); $pass=md5($salt.md5('alma'));
    Az adatbázisba lemented a $pass és $salt változókat, amikor bekéred a jelszót, akkor kikéred a felhasználó salt-ját, és ugyanezzel az algoritmussal bekódolod a megadott jelszót. Ha az eredmény egyezik az adatbázisban tárolttal, akkor a jelszót adta meg, egyébként meg mást.
    Arra jó, hogy szivárványtáblával ne lehessen szimplán visszafejteni a jelszókat.
    Nem muszáj minden felhasználóhoz külön saltot tárolni, sőt talán jobb, ha egy állandó salt van az adatbázistól függetlenül tárolva, mert úgy az adatbázis lopásakor a salt-hoz nem jut hozzá a támadó, és kevesebb az esélye, hogy vissza tudja fejteni a jelszót.

    Ennek az egésznek az a lényege, hogy ha sikerül megszerezni az adatbázisodat (sql injektálással pl), akkor a jelszavakat ne lehessen visszafejteni, és belépni velük az accountokba.
    Mutasd a teljes hozzászólást!
  • szia

    Szerintem csak gondold végig a http protokoll-t. Firefox-hoz van egy nagyon jó kiegészítő: live http header. elindítod, beírsz egy címet, hátradőlsz és látod, hogy mi is történik. Sok mindent meg fogsz tudni a header-ökről és magáról a protokollról, és akkor át fogod látni, hogy ez a természetes viselkedése a formoknak.

    Sőt, azon csodálkozom, hogy csak néha enged be. Mindig be kéne engednie, hacsak nincs a háttérben valami átirányítós, session-ös dolog.
    Mutasd a teljes hozzászólást!
  • Szerintem ez nem számít annak. Miért lenne ez biztonsági rés? Pont azért van a form-nál az action megadására lehetőség, hogy bárhová submitolhasd a formot. Ahová submitolod, az meg vagy elfogadja, vagy nem, de ezesetben miért ne fogadná el? Mihez jutsz így hozzá, amihez egyébként nem?
    Mutasd a teljes hozzászólást!
  • Találtam egy számomra új dolgot.
    Kicsit hosszú lesz, de csak így tudom elmondani.

    Ha belenézek a weben egy oldal forrásába, akkor többnyire a belépés résznél látok egy formot, a formban pedig inputokat: felhasználónév, jelszó és belépés gomb.
    pl:

    <form action="belepes.php" method="post"> Felhasználónév: <br> <input type="textbox" name="felhasznalonev" value="" maxlength="20"> <br> Jelszó: <br> <input type="password" name="jelszo" value="" maxlength="20"> <br><br> <input type="submit" name="belepes" value="Belépés"> </form>

    Ha csinálok a gépemen pl. egy index.html-t, majd a fenti forrást bemásolom azzal a különbséggel, hogy
    action="http://ahonnanletolottem/belepes.php"
    és erről saját magam által kreált index.html-fájlról próbálok belépni az adott oldalra, akkor időnként ez sikerül is.

    Szerintetek ez biztonsági résnek számít?
    Ha igen, miért?
    Mutasd a teljes hozzászólást!
  • köszi
    Mutasd a teljes hozzászólást!
  • Mert vannak adatbázisok, ahol a sűrűn használt jelszavak megvannak.

    pl md5("alma") az szinte minden ilyen adatbázisban megvan szerintem.
    Tehát ha valaki hozzájut a hashhez akkor megnézni, és hoppá, ez a jelszó az "alma".
    De ha hozzáadsz egy kis sót, akkor sokkal kisebb az esélye, pl:
    md5("Valami só"+"alma"+"egykissó") Máris sokkal jobb.
    Mutasd a teljes hozzászólást!
  • ez a "sózás" dolog attól lesz biztonságos, hogy ha valaki hozzájut egy md5 hash-hez, akkor a sózottat nem tudja elvileg visszafejteni? vagy mástól? elmagyarázná valaki? amiket láttam leírásokat, mindenütt csak az van, hogy a jelszóhoz adjunk még hozzá plusz karaktereket, de hogy ez pontosan miért jó, azt sehol nem írják.
    Mutasd a teljes hozzászólást!
  • Egyébként ha jól kódolsz, nem írathatják ki a jelszó mezőt a képernyőre


    Erről tudnál valami bővebbet mondani? Esetleg egy példát arra, amikor rosszul van kódolva, és kiírathatják a jelszómezőt?
    Mutasd a teljes hozzászólást!
  • A "PHP feketekönyv" c. csodában olvastam erről, de ott nem volt teljes a kifejtés.
    Mutasd a teljes hozzászólást!
  • Itt:
    PHP: set_error_handler - Manual

    Mondjuk nem teljesen értem :)
    Mutasd a teljes hozzászólást!
  • Véleményem szerint egy adat típusát, megfelelő értéktartományba tartozását nem @ és hibakezeléssel kell megvalósítani.

    ---

    Php verzió függő is.

    ---
    indulásnak
    Mutasd a teljes hozzászólást!
  • Sziasztok!
    Engem a php hibakezelése érdekel, dolgozatba kellene róla írni. Pl. ha negatív számból próbálok gyököt vonni, akkor ne a NAN üzenettel térjen vissza, hanem a die, exit, ill @ operátorral kellene ezt megoldani, vagy másik példát kellene kitalálnom ami most nem jut eszembe, ahol a hibakezelés működne. Pl. téglalap kerület számítása de csak akkor, ha $a és $b nem negatív. Szintén a @ operátorral, ill. die/exit-tel kellene megoldani. Van vmi ötletetek? Köszi!
    Mutasd a teljes hozzászólást!
  • tárolás:
    Bőven elég a sózott md5. Ezzel megtettél mindent amit lehet.
    Feltételezve, hogy kiiktattad az SQL Injection-t és biztonsági szempontból jól van beállítva az SQL kiszolgáló akkor csak a rendszergazda elől kell védened a user jelszavát. A rendszergazda viszont jó eséllyel hozzáfér a PHP kódhoz is. Innentől meg akármennyire bonyolítod le tudja utánozni, hisz ismeri az eljárásodat.

    brute force:
    ne foglalkozz az IP-vel meg egyebekkel. A usert tiltsd le adott időre.
    Mutasd a teljes hozzászólást!
  • "Egyébként a dupla md5 is jó megoldás lehet."


    Én is ebben a hitben éltem, amíg el nem olvastam ezt!
    Mutasd a teljes hozzászólást!
  • Felvetődött bennem még valami a 10 perc próbálkozás után 10 perc tiltás ip alapján dolognál. Az egyetemen nálunk az egész koli egy ip címen csücsül ha jól tudom. Most ha valaki 10-szer rossz jelszót ír be, akkor levágja az egész koli ip-jét 10 percre, és senki nem tud bejelentkezni. Szóval az ip alapján tiltás nem biztos, hogy jó ötlet. Gondolkoztam még azon is, hogy session-ben feljegyzem a tiltást, de akkor nyit egy új böngészőt, és folytatja tovább a próbálgatásokat.

    matt383:
    Ez szerintem ágyúval verébre, valamint ha belegondolsz, egy munkacsoporton belül lehet ugyanolyan böngészője és azonos ip-e két embernek, pl. munkahelyen vagy iskolai hálózaton. A random id generálás és a tétlen userek kiléptetése a session törlésével szerintem elég.


    Iskolában, illetve munkahelyen úgy is el tudom lopni valaki session id-jét, hogy megkérem kicsit engedjen a gépéhez mert az enyém nem jó, és kiolvasom a cookie-ból. Szerintem ezeken a helyeken a legvalószínűtlenebb, hogy valaki el akarná lopni a sessionodet. A tétlen userek kiléptetése szerintem nem igazán véd ez ellen, ha már beléptem a nevében, akkor elintézem, hogy ne legyen tétlen. A random SID-t pedig ugyanúgy el lehet lopni, viszont ha figyelem a böngészőt és az ip-t akkor azért elég rendesen leszűkítem azok körét akik esetleg fel tudják használni.
    Mutasd a teljes hozzászólást!
  • Konkrétan úgy működik, hogy a jelszó hashének 2 betűje után véletlenszerűen beszúrok egy betűt. Így ha megvan a hash, sem lehet belőle megkapni a jelszót (kivéve, ha valami egyszerű szótári alak a jelszó, mert akkor feltűnő lesz...).

    Tehát nem
    md5($_POST["password"] . chr(mt_rand(97,122)))

    hanem
    $password = md5($_POST["password"]); //a megfelelő ellenőrzések után természetesen //$password felszeletelése ciklussal egy tömbbe //tömbbe az új betű beillesztése //visszaalakítás változóvá

    Ellenőrzésnél meg kivágom a hashból a betűt, és azt hasonlítom össze.
    Ha visszakap egy hashet, teszemazt 9d0dd4d83f8e717c554dd0efc8e431f8 lesz a hash, a hg2Gf5Rr karaktersorozatra mint jelszó. Az adatbázisban mondjuk 91d0dd4d83f8e717c554dd0efc8e431f8 lesz eltárolva. Hogy fejti vissza az eredeti karaktersort? Már a sima md5 hash dekódolás sem egyszerű, de ha egy nem érvényes hashból kell érvényeset csinálni úgy, hogy nem lehet próbálkozni sem?
    Egyébként a dupla md5 is jó megoldás lehet.
    $pass = md5(md5($_GET["pass"]));

    De ez már aktívan OFF.
    Mutasd a teljes hozzászólást!
  • hozzákódoltam mindegyik jelszó md5-jéhez egy véletlenszerű karaktert és így mentettem le az adatbázisba


    ha jól értem: md5($_POST["password"] . chr(mt_rand(97,122)))

    ezzel hogy loginoltatod be a usert?
    Mutasd a teljes hozzászólást!
  • mysql_close() pl ha valamiért nem megy

    Én nem láttam még olyat, hogy ez ne sikerült volna, de ha nem sikerül se látom értelmét ezt közölni a felhasználóval.

    Én spec nem is használom, úgyis lezárja a kapcsolatot (sajnos) az oldal legenerálása után a php. Azért sajnos, mert php5.3 -ig nem volt perzisztens csatlakozásra képes a mysqli kliens library, ami azért sokat tud dobni a hatékonyságon.
    Mutasd a teljes hozzászólást!
  • a +20 karakter csak az adatbázisnak tesz rosszat

    md5($salt1 . $password . $salt2);

    Így csinálom, így nincs +20 karakter.


    Csak sebezhetőbbé tesz, ha kiírod a hibát a felhasználónak, valamint megtudja a könyvtárstruktúrát, amit esetleg el akartál titkolni, stb. Tehát több szempontból is rossz ötlet kiírni a hibát. Nálam MySQL error esetén egyből az "Adatbázis hiba" lapra van átirányítva a felhasználó.


    Én sem a hibát akartam kiírni, hanem jelezni, hogy hiba van. Ha hiba van én is egy egyszerű adatbázis hoba oldalra irányítom a user-t, de a kérdésem az volt, hogy mysql_close() pl ha valamiért nem megy, érdemes-e leállítani a script futását, és hiba oldalra dobni a felhasználót?
    Mutasd a teljes hozzászólást!
  • cross site scripting és sql injection
    Bőven elég, amit írtál.

    session lopás
    Ez szerintem ágyúval verébre, valamint ha belegondolsz, egy munkacsoporton belül lehet ugyanolyan böngészője és azonos ip-e két embernek, pl. munkahelyen vagy iskolai hálózaton. A random id generálás és a tétlen userek kiléptetése a session törlésével szerintem elég.

    próbálgatásos jelszó törés
    Erre jó amit írtál, bár a +20 karakter csak az adatbázisnak tesz rosszat, semmit nem segít. Én legutóbb úgy csináltam, hogy hozzákódoltam mindegyik jelszó md5-jéhez egy véletlenszerű karaktert és így mentettem le az adatbázisba. Így ha meg is szerzik a hashet valami módon, a rendszer ismerete nélkül képtelenek lesznek dekódolni. Egyébként ha jól kódolsz, nem írathatják ki a jelszó mezőt a képernyőre



    Ezen kívül minden bejövő adatot ellenőrzök, ha számot várok, akkor leellenőrzöm, hogy szám-e, ha szöveget, akkor minimális, maximális hosszúságot, email esetén, hogy megfelelő formában lett-e megadva, illetve minden szövegből kiszedem a html tageket, és escape-elek.

    Körülbelül én is, az e-mail ellenőrzéshez hozzátennék annyit, hogy érdemes megpingelni a domaint, úgy biztosabb az ellenőrzés.


    A másik dolog ami még érdekelne, az az adatbázissal kapcsolatos utasítások hibakezelése. Ez nálam úgy működik, hogy kapcsolódásnál, lekérdezésnél ha sikertelen a művelet, akkor megpróbálom még 3-szor, ha ezek után sem megy, akkor hibaoldalra irányítom a user-t. Szerintetek mysql_close, mysql_num rows függvényeknél van értelme figyelni a hibát és jelezni a felhasználónak?

    Csak sebezhetőbbé tesz, ha kiírod a hibát a felhasználónak, valamint megtudja a könyvtárstruktúrát, amit esetleg el akartál titkolni, stb. Tehát több szempontból is rossz ötlet kiírni a hibát. Nálam MySQL error esetén egyből az "Adatbázis hiba" lapra van átirányítva a felhasználó.


    Néhány hónapja kezdtem el egy új rendszert, ami egy játék, melyben valós pénz is gazdát cserél majd, úgyhogy a már meglévő dolgok (regisztráció, belső levelezés, néhány része a játékmodulnak) szuper-biztonságosak.

    Az új rendszer csatarendbe állítása előtt érdemes egy biztonsági tesztet csináltatni, akár ingyen is megoldható, ha kihívásként állítod, pl. a "Weblap véleményezés" topicban megkéred a népet, hogy törjék fel.


    Eddigi tapasztalataim alapján ezt tudtam elmondani.
    Mutasd a teljes hozzászólást!
  • Sziasztok!

    Mostanában sokat olvasgattam PHP biztonság témaköréről, és nagyon érdekelnének más emberek tapasztalatai. Milyen támadási módszerek vannak, illetve hogyan lehet ezeket kivédeni? Az összeolvasgatott dolgok alapján kipróbálásképpen írogatok egy beléptető scriptet, eddig a következő támadási módok kerültek kivédésre:

    cross site scripting: itt a bemeneteknél szűröm strip_tags() függvénnyel a html tag-eket

    sql injection: mysql_real_escape() függvény a megfelelő helyeken

    session lopás: az adott session-ban a létrehozáskor eltárolom a felhasználó ip-jét, böngésző típusát, ezeket utána ellenőrzöm, hogy egyeznek-e a session-ben eltárolt értékek a user ip-jével illetve böngésző típusával. Ezen kívül a belépés után új session id-t generáltatok

    próbálgatásos jelszó törés: az adatbázisban számon tartom a belépési próbálkozások számát, illetve az utolsó próbálkozás idejét. 10 sikertelen próba után tiltom 10 percre az adott ip-ről jövő próbálkozásokat. Ezen kívül, ha valaki md5 adatbázis segítségével próbálkozna, "sózom" a jelszavakat md5-be való kódolás előtt az elején illetve a végén egy 10 karakterből álló karaktersorozattal

    Ezen kívül minden bejövő adatot ellenőrzök, ha számot várok, akkor leellenőrzöm, hogy szám-e, ha szöveget, akkor minimális, maximális hosszúságot, email esetén, hogy megfelelő formában lett-e megadva, illetve minden szövegből kiszedem a html tageket, és escape-elek.


    A másik dolog ami még érdekelne, az az adatbázissal kapcsolatos utasítások hibakezelése. Ez nálam úgy működik, hogy kapcsolódásnál, lekérdezésnél ha sikertelen a művelet, akkor megpróbálom még 3-szor, ha ezek után sem megy, akkor hibaoldalra irányítom a user-t. Szerintetek mysql_close, mysql_num rows függvényeknél van értelme figyelni a hibát és jelezni a felhasználónak?

    Előre is köszönök minden építő jellegű hozzászólást!
    Mutasd a teljes hozzászólást!
abcd