ugrás a tartalomhoz

Munkamenet kezelés biztonsági kérdései

Hodicska Gergely · 2004. Május. 25. (K), 22.00
Munkamenet kezelés biztonsági kérdései
Az előző cikkben megnéztük, miért van szükségünk egy webes alkalmazás során munkamenet kezelésre, s hogy hogyan használhatjuk ezt PHP esetén. Ebben a cikkben először körüljárjuk, hogy általában milyen támadási módszerek vannak egy felhasználó munkamenetének megszerzésére, majd ennek fényében megvizsgáljuk, hogy hogyan tehetjük biztonságosabbá a PHP saját munkamenet kezelő mechanizmusát. Végezetül szó lesz néhány kiegészítési lehetőségről, valamint pár hasznos tanácsról a PHP munkamenet kezelésével kapcsolatban.

A sorozatban megjelent

Miért szükséges védenünk munkameneteinket?


A munkamenet általában nem csak a felhasználók nyomon követésére szolgál, hanem azok azonosítására is. Ezzel kapcsolatban két fogalmat különböztetünk meg: authentikáció és authorizáció. Az authentikáció a felhasználó azonosítását jelenti a rendszer számára, ez zajlik le, amikor a felhasználó bejelentkezik rendszerünkbe. Ezt általában úgy jelezzük, hogy a munkamenetben elhelyezünk egy változót, aminek tartalma utal a felhasználó kilétére (például felhasználó azonosító). Az authorizáció az a folyamat, melynek során ellenőrizzük, hogy felhasználó számára egy funkció elérhető-e jogosultságai alapján. A jogosultságok kiolvasása általában a bejelentkezéskor történik, és ezek is a munkamenetben kerülnek tárolásra. Az authentikáció tehát egy egyszeri cselekmény, míg az authorizáció (szükség esetén) minden egyes oldalkéréskor végbe mehet.

Egy oldal lekérésekor a program megnézi, hogy a munkamenetben létezik-e a látogató bejelentkezettségét jelző változó, ha igen akkor a felhasználó személyazonosságát (és ezzel egyetemben a jogosultságait is) ez alapján állapítja meg. Így ha a csúnya, gonosz támadónak sikerül egy bejelentkezett felhasználó munkamenetét megszerezni, akkor ezzel együtt megszerzi annak személyazonosságát is, az ő nevében lesz képes használni a rendszert. Ehhez ennek a csúnya, gonosz (na jó, a továbbiakban nem hangsúlyozom ki, de ne feledjük :) ) támadónak „csak” annyit kell tennie, hogy valahogy megszerez egy éppen aktív munkamenethez tartozó sessionId-t.

Támadási módok

Alapvetően kétféle módszer van. Az egyik a session hijacking (munkamenet „eltérítés”). Ilyenkor a támadó egy már belépett felhasználó sessionId-jét próbálja meg megszerezni. A másik módszer a session fixation (munkament „rögzítés”). Ennek lényege, hogy a támadó még a felhasználó bejelentkezése előtt a megcélzott rendszeren létrehoz egy munkamenetet. Ezt követően megpróbálja elérni, hogy az áldozat már a bejelentkezésekor küldje el ennek a munkamenetnek a sessionId-ját, így elérve azt, hogy a bejelentkezését követően a rendszer ne hozzon létre számára új munkamenetet. Így a támadó eleve tudja a használt sessionId-t, bármikor képes átvenni az áldozat szerepét.

Session hijacking

Ezen módszer során háromféle lehetősége van a támadónak:

sessionId elfogása: ez történhet például a hálózati forgalom figyelésével. Titkosított kommunikáció használata kellő védelmet nyújt ellene, vagy ha erre nincs lehetőségünk, akkor megtehetjük, hogy figyeljük a felhasználó IP címét, böngészőjének általunk ismert paramétereit, melyek egy munkamenet alatt biztosan nem változnak (tekintsünk el például ADSL kapcsolat esetén történő napi kötelező IP váltástól), így ha ez mégis megtörténik, akkor az valamiféle támadásra utal: megszüntetjük a munkamenetet. Ez a megoldás korántsem nyújt akkora védelmet, mint a titkosított kapcsolat, illetve alkalmatlan olyan támadási kísérlet kiszűrésére, amikor a támadó IP címe, illetve az egyéb figyelt paraméterei megegyeznek az áldozatéival.

sessionId megjóslása: az ez ellen való védekezés alapja, hogy minőségi, kellően kiszámíthatatlan sessionId-t generáljunk. Például gyakran látom kódokban, hogy ha egy hosszú véletlenszerű karaktersorozatra van szüksége valakinek, akkor így állítja elő: md5(time()). Ennek hátránya, hogy egy jól felkészült támadó például egy md5 adatbázis segítségével hamar rájön, hogy a küldött sessionId számok md5-je, majd ezt követően az ütemezés alapján észreveheti, hogy az másodpercenként változik, és ezen információk birtokában már jó esélye van egy létező munkamenet sessionId-jének kitalálására. Ezért célszerű a sessionId generálását véletlen számok alapján végezni, illetve mindig jól jöhet valami egyéni „plusz” hozzáadása is. Alap beállítás szerint a PHP is az aktuális időpont és egy véletlen szám alapján képzett md5 értéket használ sessionId-ként, de lehetőségünk van meg kicsit „turbózni” a session.entropy_file és a session.entropy_length opciók használatával.

brute force: a támadó próbálgatással igyekszik kitalálni a sessionId-t. Az ilyen jellegű támadás ellen védelmet nyújt, ha a sessionId kellően hosszú, tekintetbe véve az egyszerre párhuzamosan létező munkamenetek számát. Például ha a sessionId 100 millió féle értéket vehet fel egyszerre, az elegendően soknak tűnhet ahhoz, hogy a támadó véletlenül ráhibázzon egy éppen bejelentkezett felhasználó munkamenet azonosítójára, de ha ebben a rendszerben előfordulhat egyszerre mondjuk 1 millió bejelentkezett felhasználó, akkor ez a szám már korántsem elegendően nagy ahhoz, hogy a támadónak ne érje meg próbálkozással munkamenethez jutni.

A fentiekből láthatjuk, hogy egy már létező munkamenet megszerzése nem könnyű feladat, ezért a második módszer eredményesebb lehet nem megfelelő munkamenet kezelés mellett.

Session fixation

A támadás lényege, hogy a támadó megpróbálja rávenni a felhasználó böngészőjét, hogy az már a bejelentkezéskor küldjön egy sessionId-t, így a rendszer nem fog számára újat kiosztani a bejelentkezés során.

A támadás három részre bontható:
  • session setup (beállítás): a támadónak szereznie kell egy érvényes sessionId-t

  • session fixation: a támadónak rá kell vennie az áldozat böngészőjét, hogy majd használja ezt a sessionId-t, amikor a felhasználó megpróbál bejelentkezni

  • session entrance (belépés): a támadó várakozik, míg az áldozat belép, majd ezután használhatja annak munkamenetét.
Session setup
A szerver oldali nyelvek (webszerverek) körében kétféle munkamenet kezelési mechanizmus létezik: „permissive” (engedékeny) (ide tartozik a PHP is) vagy „strict” (szigorú). Szigorú esetben a rendszer csak az általa korábban már ténylegesen kiosztott sessionId-kat fogadja el, ilyen rendszer esetén a támadónak létre kell hoznia egy úgynevezett trap sessiont (csapda munkamenetet). Engedékeny esetben tetszőleges sessionId elfogadásra kerül, ilyen rendszereknél a támadó egyszerűen választ egy sessionId-t.
Session fixation
Ha a sessionId átadása URL-en keresztül történik, akkor a támadónak rá kell venni az áldozatot, hogy egy általa manipulált linken keresztül lépjen be.

Ha az átadás rejtett űrlap elemen keresztül történik, akkor a támadónak rá kell venni az áldozatot, hogy egy általa készített űrlapon keresztül lépjen be. Mindkét esetben „látszik” a manipulálás ténye (persze előfordulhatnak böngésző bugok is ;) ), ezért a támadások célja többnyire a sütin keresztül várt sessionId-k. És mint előző cikkben említettem, ez (indokoltan) a sessionId kedvelt tárolási formája.

A nehézséget az okozza, hogy a támadónak a betörés céljául választott rendszer domainje nevében kell sütit elhelyeznie az áldozat gépén. Lássuk milyen lehetőségei vannak:

XSS: a cél rendszer XSS támadhatóságának kihasználása egyéb, az áldozat által látogatott, a célrendszerrel egy domainben lévő gép feltörése, majd a webszerver módosítása (amint az áldozat oda látogat küld neki egy sessionId sütit)

az áldozat DNS szerverének megtámadása: pl. az akcio.otp.hu-hoz rendelt IP cím a támadó gépére mutasson. Ezután küld egy levelet egy erre az oldalra mutató linkkel, amire ha az áldozat rákattint, akkor az elhelyezi a szükséges sütit.

hálózati forgalom figyelése, annak módosítása: a támadó a hálózati forgalmat figyeli, vagy abba beépül (hogy rajta keresztül menjenek az adatok), így manipulálni tudja a forgalmat, egy sütit tud eljuttatni a felhasználó gépére.
Session entrance
Ha a támadó sikeresnek bizonyult, akkor az áldozat belépését követően egészen annak kilépéséig képes lehet az adott rendszerben a megtámadott személy nevében ügyködni.

A munkamenet fixation elleni védekezés elemei:
  • Minden esetben, amikor a felhasználó belép a rendszerünkbe, generáljunk számára egy új munkamenet azonosítót.
  • A felhasználónak legyen lehetősége kilépni, mely mind az aktuálisan, mind az esetlegesen korábban általa használt munkamenetek megsemmisülésével jár. Ez ne csak a süti törlésével járjon, hanem szerver oldalon is szüntessük meg a munkamenetet.
  • Alkalmazzunk különböző időkorlátokat, melyek lejárta bizonyos megszorításokkal járjon. Például 10 perc inaktivitás esetén a következő oldallekéréskor kérjük be ismét a felhasználó jelszavát, 30 perc inaktivitás esetén az ezt követően pedig törlődjön a munkamenet, a felhasználónak újból be kelljen lépnie. Persze ezek a megszorítások legyenek összhangban az oldal tartalmának megfelelő biztonsági szinttel.

A keretrendszer részeként lesz még szó konkrét megvalósításról.

Biztonságos munkamenet kezelés

Láthattuk, hogy alapvetően milyen fenyegetettségekkel kell szembenéznünk a munkamenet kezelés során, illetve vázoltam, hogy milyen védekezési lehetőségeink vannak ellenük. Lássunk most egy lehetséges megvalósítást, mely igyekszik kellő védelmet nyújtani. Alapvetően a PHP saját munkamenet kezelését használjuk, egy kis kiegészítéssel :-).

Biztonságos munkamenet kezelésre csak bejelentkezett felhasználók esetén van szükség, hiszen különben érdektelen, hogy a munkamenetet ellophatják-e vagy sem. Ha bármi miatt erre ellenkező esetben is szükség lenne, minimális változtatások révén elérhetjük ezt.

A módszer lényege, hogy a bejelentkezett felhasználók munkameneteiről adatokat tárolunk el adatbázisunkban, és ezen adatok alapján ellenőrizzük, hogy egy kéréshez tartozó munkamenet érvényes-e, vagy sem. A munkamenet a programunk elején automatikusan elindításra kerül (session_start()), majd az ellenőrzés kimenetelének függvényében, érintetlenül hagyjuk, vagy töröljük. Az ellenőrzéshez használt adatbázis tábla szerkezete a következő:

CREATE TABLE "user_sessions" (
## azonosító
  "id" SERIAL, 
## munkamenet azonosító
  "session_id" VARCHAR(32) NOT NULL, 
## felhasználó azonosító 
  "u_id" INTEGER NOT NULL, 
## felhasználó IP címe 
  "ip_address" VARCHAR(23) NOT NULL, 
## felhasználó kliense által küldött user_agent
  "user_agent" VARCHAR(255), 
## munkamenet létrehozásának időpontja
  "created" TIMESTAMP WITH TIME ZONE NOT NULL, 
## legutolsó kérés időpontja 
  "modified" TIMESTAMP WITH TIME ZONE NOT NULL, 
  PRIMARY KEY("id"), 
  UNIQUE("session_id"), 
  UNIQUE("u_id") 
)
A munkamenet ellenőrzését és az ezzel kapcsolatos teendőket a következő szerkezetű osztály valósítja meg:

<?php
    define('SESSION_GLOBAL_TIMEOUT', 0);
    define('SESSION_REQUEST_TIMEOUT', 0);
    define('SESSION_INVALID_SESSIONID', -1);
    define('SESSION_NONEXISTENT_SESSION', -2);
    define('SESSION_GLOBAL_TIMEOUT_EXPIRED', -3);
    define('SESSION_REQUEST_TIMEOUT_EXPIRED', -4);

    class SessionManager {
        function SessionManager() {...}
        function _generateSessionId($userId, $startTime) {...}
        function _isWellFormedSessionId($sessionId, $userId, $startTime) {...}
        function destroySession() {...}
        function updateSession() {...}
        function validateSession() {...}
        function registerSession($userId) {...}
    }
?>
A felhasználó bejelentkezését követően meghívjuk a SessionManager objektum registerSession metódusát átadva neki a felhasználó azonosítóját. Ez a következőket teszi:
  • generál egy új munkamenet azonosítót, amelynek egy része úgy képződik, hogy belekódoljuk a létrehozás idejét és egyéb adatokat (IP, user_agent, stb.), amik alapján formai ellenőrzést tudunk majd végezni a munkamenet azonosítón. A másik része egy véletlen karaktersorozat. A két rész valamilyen általunk választott módszer alapján való összekeveréséből jön létre a tényleges munkamenet azonosító. Fontos, hogy ez az algoritmus két irányú legyen, hogy egy kapott azonosítót és részeire tudjunk bontani.
    töröl a munkamenet táblából minden korábbi olyan munkamenet bejegyzést, amiben a munkamenet azonosító megegyezik a most generálttal, illetve a felhasználó azonosító megegyezik az átadottal.
  • ezután a munkamenet táblába bekerül egy bejegyzés, ami tartalmazza a felhasználó azonosítóját, a munkamenet azonosítót és minden egyéb szükséges adatot (IP cím, user_agent, létrehozás időpontja, stb.).
  • ezután újraindítja a munkamenetet a generált munkamenet azonosítóval (ne felejtsük, hogy a munkamenet a programunk elején automatikusan elindításra került). Itt figyeljünk arra, hogy a $_SESSION tömb tartalma elveszik, ezért ha tárolunk olyan adatot benne, amire még szükségünk lehet (például melyik oldalról jött a felhasználó a bejelentkező oldalra), akkor azt mentsük el.
  • végül az újonnan létrejött $_SESSION tömbbe elhelyez egy változót, mely tárolja például a felhasználó azonosítót, vagy a user_sessions tábla megfelelő sorának azonosítóját, és amely jelzi, hogy az aktuális munkamenet egy bejelentkezett felhasználóhoz tartozik.

Amikor egy kérés érkezik az alkalmazásunkhoz, akkor megnézzük, hogy létezik-e a munkamenetünkben ez a változó. Ha igen akkor meghívjuk a SessionManager objektum validateSession metódusát, mely a következőket teszi:
  • először egy formai ellenőrzést végez a munkamenet azonosítóval kapcsolatban a belekódolt adatok és a kérés ezeknek megfelelő adatai alapján.
  • ha ez stimmel, akkor megnézi, hogy létezik-e a user_sessions táblában bejegyzés az adott munkamenet azonosítóval kapcsolatban.
  • ha igen, akkor megnézi, nem járt-e le a munkamenet. Én két időkorlátot definiáltam: a nagyobbik lejárta esetén nem tekintjük érvényesnek a munkamenetet (töröljük azt, és a felhasználónak újból be kell jelentkeznie a rendszerbe), míg a kisebbik lejárta esetén a felhasználónak lehetősége van folytatni munkamenetét jelszavának ismételt megadásával. A konkrét megvalósítás esetén célszerű úgy eljárnunk, hogy mindkét időkorlát esetén nulla érték megadásával az adott időkorlát figyelmen kívül maradjon.
  • ha minden ellenőrzés sikeres volt, akkor frissíti a user_sessions tábla bejegyzés modified mezőjét.

A függvény hiba esetén visszaadja annak kódját, ellenkező esetben true-val tér vissza. Jelenleg 4 féle hiba került definiálásra:
  • a munkamenet azonosító formailag nem megfelelő;
  • a munkamenet táblában nincs a munkamenet azonosítónak megfelelő bejegyzés;
  • nagyobbik időkorlát lejárt;
  • kisebbik időkorlát lejárt.

Az első 3 esetén meghívjuk a SessionManager objektum destroySession metódusát, mely törli az aktuális munkamenetet (esetlegesen meglévő user_sessions táblabeli bejegyzést), majd újraindítja a munkamenetet. Az utolsó hiba esetén a felhasználót a bejelentkezési oldalunkra irányítjuk, ahol jelszavának ismételt megadására szólítjuk fel.

Mit nyertünk?

Az általunk generált sessionId, ha jól csináltuk, akkor nehezebben megjósolható, mint a PHP által generáltak, ráadásul formai megszorításokat is tartalmaz, így ellenállóbb egy brute_force támadás ellen, hiszen a támadónak formailag megfelelő azonosítókat kéne generálnia ahhoz, hogy eleve sikerrel járjon. Szükség esetén számon tarthatjuk azokat az IP címeket, ahonnan formailag nem megfelelő sessionId-t tartalmazó kérések érkeznek, és ha ezek száma meghalad egy értéket, akkor tetszőleges megszorításokat eszközölhetünk ellenük.

Módszerünk alkalmazásával a PHP munkamenet kezelésének említett permissive jellegét strict-é változtattuk, hiszen csak az általunk nyilvántartott munkamenetek használhatóak.

A belépést követő, a munkamenet általunk generált azonosítóval történő újraindítása kizárja a session fixation támadás lehetőségét, míg erre a PHP saját munkamenet kezelése esetén lenne mód.

Bár a PHP is nyújt lehetőséget (session.gc-maxlifetime) a munkamenet maximális hosszának meghatározására, az általunk használt időkorlátok bevezetése rugalmasabb kezelést tesz lehetővé. (Ezen kívül, ha a fenti linkre kattintunk, olvashatunk róla, hogy a PHP 4.2.3-as verziója előtt bizonyos fájlrendszerek esetén ez a beállítás nem működött megfelelően.)

Még egy előnye ennek a módszernek, hogy teljesen független a munkamenet adatainak tárolási formájától. Így ha esetlegesen saját kezelőt használnánk, mert például szeretnénk ezen adatokat adatbázisban tárolni, akkor ezt nyugodtan megtehetjük.

Pár plusz lehetőség

A felhasználó kezelés gyakran párosul jogosultság kezeléssel is, az egyes felhasználóknak eltérő jogosultságaik vannak. Amikor a felhasználó bejelentkezik a rendszerbe, jogosultságai felolvasásra kerülnek az adatbázisból, és általában a munkamenetben kerülnek tárolásra. Ezt követően a jogosultságait nem frissítjük minden egyes oldallekéréskor egy felesleges adatbázis műveletet végrehajtva. Ennek a módszernek azonban egy hátulütője lehet, miszerint ha egy felhasználónak a bejelentkezését követően megváltoznak a jogosultságai (az adminisztrátor éppen ezen idő alatt változtatja őket), akkor a frissítés nélkülözése miatt a munkamenetében és az adatbázisban tárolt jogai nem lesznek konzisztensek, a felhasználó esetleg továbbra is elérhet olyan funkciókat, melyekhez szükséges jogosultságokat már megvonták tőle.

A probléma megoldására valahogy jeleznünk kell a változás tényét. Mivel a munkamenet ellenőrzése miatt a user_sessions táblánk egy sorát úgyis lekérdezzük, célszerű lehet ezt itt jelezni. Elhelyezünk egy plusz mezőt, melyet true értékre állítva jelezhetjük, hogy szükséges a jogosultságok újraolvasása. A SessionManager osztályunkat pedig bővítjük a mező értékének lekérdezését és állítását lehetővé tevő metódusokkal. Ezután már csak annyi a teendőnk, hogy amikor megváltoztatjuk a felhasználó jogosultságait, akkor frissítjük a user_sessions táblát.

Még egy kényelmi funkciót érdemes lehet rendszerünkbe beépíteni. Tegyük fel, hogy a felhasználó kitölt egy hosszú űrlapot, majd az elküldés előtt valami tennivalója akad, és mire visszatér munkájához lejár a tétlenséget definiáló kisebbik időkorlát. Mikor az űrlap elküldésekor ezt érzékeljük és a bejelentkezési oldalra irányítjuk, ezek az adatok elvesznek, a felhasználó jelszavának kitöltése után kénytelen újból megadni őket. Ezen kellemetlen szituációk elkerülésére megtehetjük, hogy az időkorlát lejárta esetén a kérés során küldött adatokat lementjük munkamenetünkbe, és ha a felhasználó sikeresen megerősítette azonosságát, visszatöltjük azokat, és az eredeti kérésnek megfelelően folytatódik a program futása.

Néhány jótanács

Következzen néhány jótanács a PHP munkamenet kezelésével kapcsolatban, melyek egy részére a kézikönyvben is találunk utalást, de van ami személyes tapasztalaton alapul.

Figyeljünk arra, hogy ha a sessionId nem sütiben tárolódik, és egy Location HTTP fejléccel szeretnénk a felhasználót átirányítani egy másik oldalra, akkor nekünk kell biztosítani a sessionId elhelyezését az URL-ben.

Tartsuk szem előtt, hogy a $_SESSION tömb tartalmának előállítása fájl műveleteken alapul, ezért érdemes minél kevesebb adatot tárolnunk benne, nagy adatmennyiség használata esetén lassulást tapasztalhatunk. Ha szükséges érdemes lehet egy ramdisken tárolni ezeket a fájlokat, vagy saját kezelőt használnunk.

Ha objektumokat szeretnénk tárolni munkamenetünkben, akkor ezen osztályok definícióinak betöltése a session_start() parancs előtt meg kell történjen. Ilyen esetben például nem használható a session.auto_start lehetőség sem.

Figyeljünk arra, hogy a $_SESSION tömb egy super global tömb, ezért függvényen belül nem szükséges a global kulcsszó használata, ellenkező esetben bár értékadásaink látszólag érvényre jutnak, nem kerülnek tárolásra.

És még egy dolog, ami már az előző cikkben szintén említésre került, saját munkamenet kezelő használata esetén a programunk befejezésekor hívjuk meg a session_write_close() függvényt, ezzel biztosan elkerüljük, hogy a munkamenet adatok még azelőtt mentésre kerülnek, mire a következő oldal kiszolgálása során a programunk újból használni szeretné azokat, ami az adatok inkonzisztens állapotba való kerülését eredményezheti.

Hát ennyi volt mára, legközelebb, ha minden jól megy, a webes környezetben létező biztonsági fenyegetettségeket vizsgáljuk meg, illetve azt, hogy hogyan is védekezhetünk ellenük.
 
1

PHP biztonsági kérdések

Dualon · 2004. Május. 30. (V), 00.06
Kedves FelhoBacsi!

Nagy örömmel olvasom a cikksorozatot, egyre növekvő kíváncsisággal várom következő részeit. Ahogy mondani szokás: "így tovább"! ,o)

Dúalon
Rejtett Uradalom - http://uradalom.fantasya.hu
2

Miért nem hash?

Anonymous · 2004. Jún. 14. (H), 08.00
Egész jó cikk, de lenne egy észrevételem az alábbihoz:

"generál egy új munkamenet azonosítót, amelynek egy része úgy képződik, hogy belekódoljuk a létrehozás idejét és egyéb adatokat (IP, user_agent, stb.), amik alapján formai ellenőrzést tudunk majd végezni a munkamenet azonosítón. A másik része egy véletlen karaktersorozat. A két rész valamilyen általunk választott módszer alapján való összekeveréséből jön létre a tényleges munkamenet azonosító. Fontos, hogy ez az algoritmus két irányú legyen, hogy egy kapott azonosítót és részeire tudjunk bontani.
töröl a munkamenet táblából minden korábbi olyan munkamenet bejegyzést, amiben a munkamenet azonosító megegyezik a most generálttal, illetve a felhasználó azonosító megegyezik az átadottal."

Két irányú legyen? A http kéréssel beérkező adatokat (ip, user_agent, stb) kellene összevetni a sessionId mellé (az sql táblában) eltárolt értékekkel, és cselekedni, ha nem egyeznek.
Szerintem pont azért kellene valamilyen egyirányú függvényt használni (hash), hogy az ip-t, user_agentet ne lehessen visszafejteni illetve megváltoztatni a sessionId-ben. Ha elkapja a sessionId-t vki, akkor csak kicseréli benne az IP címet, és a saját proxyja mögül tud tevékenykedni a user nevében.

/sunz
3

Re: Miért nem hash?

Hodicska Gergely · 2004. Jún. 23. (Sze), 22.04
Szia!

Két irányú legyen? A http kéréssel beérkező adatokat (ip, user_agent, stb) kellene összevetni a sessionId mellé (az sql táblában) eltárolt értékekkel, és cselekedni, ha nem egyeznek.

Az a mondat a ket resz (kulonbozo adatok alapjan generalt, veletlen szam) osszekeveresenek algoritmusara vonatkozott. Ez ket iranyu kell legyen, hogy a visszakpott sessionId-t szet tudd bontani.
A "generalas" nalam is mondjuk md5-tel megy. Igaz ezt nem hangsulyoztam ki, ezert koszonom hozzaszolasod.

Felho
4

[i]Az a mondat a ket resz (ku

Anonymous · 2004. Jún. 30. (Sze), 09.46
Az a mondat a ket resz (kulonbozo adatok alapjan generalt, veletlen szam) osszekeveresenek algoritmusara vonatkozott. Ez ket iranyu kell legyen, hogy a visszakpott sessionId-t szet tudd bontani.
A "generalas" nalam is mondjuk md5-tel megy. Igaz ezt nem hangsulyoztam ki, ezert koszonom hozzaszolasod.


Nem értem, hogy miért kell a sessionId-t később szétbontani. Én úgy csinálnám ezt, hogy loginkor generálok md5-tel egy random sessionId-t (az, hogy ebbe ki mit rak bele mint inputként, az más kérdés, csak az a lényeg, hogy eléggé véletlenszerű és egyirányú függvény legyen).
Ha ez megvan, akkor eltárolom az IP-t, user-agent-et, időpontot és egyéb infokat az sql táblába a session azonosítóval együtt.
Ezután ha a user lekér egy újabb oldalt, a php-m megkapja a sessionId-t, a böngészőtől a fejléceknél a user-agent-et, IP címet, valamint tudja a lehívás időpontját is. Az ellenőrzés meg úgy megy, hogy az sql táblából kikeresi a loginkor eltárolt sessionId mellett levő adatokat (user-agent, ip, idő, stb), és összehasonlítja az aktuális laplehíváskor kapottakkal.
Szóval arra akarok kilyukadni, hogy ha a sessionId-ban visszakódolható módon benne van valamilyen információ, akkor azt egy támadó esetleg képes lehet megváltoztatni. A Te írásodból viszont ez számomra nem tűnik ki, pedig fontos kritérium. Ha csak számomra nem világos, akkor elnézést kérek.

(Ha már mindenképpen a sessionId-ban kell lennie ezeknek az adatoknak (mondjuk sebességproblémák miatt), akkor mondjuk egy AES-sel titkosítanám az egészet, gyakori kulcsváltások mellett.)

/sunz
15

Miért kellene kétirányú?

inf3rno · 2008. Nov. 2. (V), 13.32
Nem értem miért kéne kétirányúra megcsinálni? Eltárolod adatbázisban az összes jellemzőjét a munkamenetnek, az alapján hasonlítasz össze.
16

Szerited emlékszik?

Poetro · 2008. Nov. 2. (V), 21.32
Szerinted emlékszik rá 4 év távlatából?
Előbb talán olvasd el, mikori témákra válaszolsz, mert ez nem az első eset, hogy egy 3-4 éves témát boncolgatsz, ami persze nem baj, csak nem sok értelme van.
17

Sztem igen

inf3rno · 2008. Nov. 4. (K), 22.21
Hát azért ha ő írta a cikket csak emlékszik :-)
5

sessionok és authentikáció

Anonymous · 2005. Feb. 3. (Cs), 14.45
Épp tegnap eszkábáltam össze egy smarty oldalat pear Auth és a pear HTTP_Session kiegészítéssel.

Nagyon jók :)

Sessionoket sose tároljatok fájlokban, mert local user támadásokkal szemben védtelenek, ha nincs phpsuexec a rendszeren. De ha van is a /tmp könyvtárat bárki kilistázza és megszerzi az azonosítót.
Szóval sessionoket csak adatbázisba! A PHP feket könyvben is van erre példa, de a pear HTTP_Session pont erre való.
A pear Auth meg aztán mindent lement a userről: ip, böngésző, meg minden.
6

PHP példa kód

Anonymous · 2006. Jan. 18. (Sze), 11.51
Kedves Felho Bácsi

Nagyon tettszett a cikk és sok újat tudtam meg belőlle! Most sajnos nem túl sok időm van, de szeretném ezt a session kezelést alkalmazni egy projektemben és ha kérhetnék egy példa kódot, akkor azt az igényeimnek csak át kellene alakítani és nem kellene az egészet megvalósítanom és gyorsabban haladnék. Nagyo nagyon megköszönném.

Tobias
7

re: PHP példa kód

Anonymous · 2006. Jún. 24. (Szo), 23.58
No igen... A példa kód nagyon jó lenne, sok hozzám hasonló kezdő számára is. Azonban nem hiszem, hogy a cikk írója ilyesmivel foglalatoskodna, hogy minden olvasó ilyen irányú kérését kielégítse, amit mondjuk meg is tudok érteni. A cikk nem azért készült, hogy helyettünk megírják utána a kódot is, hanem hogy segítsen elindulni. Azonban ha tudna ajánlani valami oldalt, ami részletesebben feszegeti a témát, azt megköszönném én is, és szerintem még nagyon sokan mások is.

--K--
9

példakód

Hodicska Gergely · 2006. Jún. 26. (H), 22.52
A rendszer, aminek része a sessionkezelés, elég összetett, de megpróbálom kivadászni belőle a csak ide tartozó részeket.


Felhő
11

örülnék ;)

KergeKacsa · 2006. Júl. 15. (Szo), 18.52
Egy ilyesminek szerintem még a tapasztaltabbak is örülnének. (Például én. ;))
14

hm? :)

KergeKacsa · 2006. Dec. 20. (Sze), 23.47
Szia!

Lehet róla szó, hogy kivadászd a dolgokat? :)
8

session ID

Homecsiga · 2006. Jún. 25. (V), 01.25
Tisztelt Gergely!

Engem az érdekelne, hogy jól fogtam e fel azt a dolgot, hogy ameddig a user nem logolt be, addig gyakorlatilag teljesen lényegtelen a session ID. Nem kell nekem generálni, nem kell semmit ellenőrizni vele kapcsolatban? Például ha van egy oldalam, amin azt mondom, hogy beállítok egy session változót amikor a user ráklikkelt egy linkre, hogy amikor beolvassa a következő oldalt megvizsgáljam ennek értékét, és ennek függvényében irassam ki pl a regisztrációs formot?
10

nagyjából igen

Hodicska Gergely · 2006. Jún. 26. (H), 23.04
ameddig a user nem logolt be, addig gyakorlatilag teljesen lényegtelen a session ID

Amíg nem tartozik felelősség a munkamenethez, addig az azonosító is lényegtelen.

Például ha van egy oldalam, amin azt mondom, hogy beállítok egy session változót amikor a user ráklikkelt egy linkre, hogy amikor beolvassa a következő oldalt megvizsgáljam ennek értékét, és ennek függvényében irassam ki pl a regisztrációs formot?

Nem igazán látom, hogy ezzel mit is szeretnél elérni.


Felhő
12

Lenne pár kérdésem ...

Anonymous · 2006. Nov. 14. (K), 11.18
generál egy új munkamenet azonosítót, amelynek egy része úgy képződik, hogy belekódoljuk a létrehozás idejét és egyéb adatokat (IP, user_agent, stb.), amik alapján formai ellenőrzést tudunk majd végezni a munkamenet azonosítón. A másik része egy véletlen karaktersorozat. A két rész valamilyen általunk választott módszer alapján való összekeveréséből jön létre a tényleges munkamenet azonosító. Fontos, hogy ez az algoritmus két irányú legyen, hogy egy kapott azonosítót és részeire tudjunk bontani.

Itt mit jelent ez a kétirányú dolog (mert nagyon nem értem)?

ezután újraindítja a munkamenetet a generált munkamenet azonosítóval

Itt pontosan hogyan történik az újraindítás és a session id beállítása?

először egy formai ellenőrzést végez a munkamenet azonosítóval kapcsolatban a belekódolt adatok és a kérés ezeknek megfelelő adatai alapján.

Hogyen történik az ellenőrés? (Ezen kérdésem abból következik, hogy nem értem a kétirányú dolgot ...)
13

Kétirányú ...

Anonymous · 2006. Nov. 20. (H), 10.39
A session újraindítást már megoldottam, de ezt a kétirányú dolgot még mindig nem értem ...
19

Session ID generálás és validálás

Max Logan · 2009. Júl. 27. (H), 11.35
...
18

Példa a munkamenetkezelésre

mikieger · 2009. Júl. 21. (K), 23.43
Sziasztok, van valakinek példája a munkamenet-kezelésre Hodicska Gergőtől, vagy hasonló?
Előre is köszi a válaszokat...