WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   PHP->Sessions->Object->Säkerhet? (https://www.wn.se/forum/showthread.php?t=13186)

FredrikMH 2006-03-28 12:04

Jag funderar lite över säkerheten i mitt system (som ännu ej är i bruk).

Det är så att jag använder session_register() på ett objekt av klassen User. Där användarnamn, lösenord osv finns lagrat. Detta för att jag vill på ett enktelt sätt komma åt all användarinformation på alla kommande sidor. Nu undrar jag om jag behöver kolla Objektet som kommer tillbaka så det inte har ändrats av användaren. Exemeplvis innuti objektet finns information lagrad om användaren är en vanlig användare, moderator eller en administratör.

Finns det möjlighet för användaren att modifiera detta och på så sätt skapa säkerhetshål i mitt script? I så fall behöver jag kontrollera all kritisk data överst i varje fil.

DeSoto 2006-03-28 12:26

Det är generellt sett inte bra att lagra objekt i sessionsvariabler, eftersom objektet först serialiseras (heter det så?) och sparas i en fil på servern, och sen avserialiseras (unserialize) nästa gång användaren skickar en request till servern. Detta tar onödigt lång tid. Det är bättre att lagra värdena i din databas, och skapa ett nytt objekt för varje request. Du ska försöka lagra så lite som möjligt i sessionsvariabler.

Eftersom sessionsvariabel-filen lagras på servern finns det inget sätt för en användare att ändra på den (såvida han inte har tillgång till servern). Risken som finns är dock att en användare får reda på ett sessions-id från en administratör, och lurar servern med det sessions-id:et att han är administratören.

kullervo 2006-03-28 13:00

Citat:

Originally posted by DeSoto@Mar 28 2006, 11:26
Det är bättre att lagra värdena i din databas, och skapa ett nytt objekt för varje request.
Du tycker alltså att det är skillnad på att lagra hela objektet i sessionen och att plocka ut datat och lagra det separat i sessionen? Samma sak i min mening. Jag föreslår att lagra hela objektet eftersom det är det resultatet han vill åt. Om det nu är långsammare att lagra hela sessionen så kan det inte vara många microsekunder.

Använder folk PHP's inbyggda session-hanterare till seriösa sajter? Det var länge sen jag ens tänkte på att det faktiskt finns en inbyggd i PHP. Den var kass för 4 år sedan (då jag senast hade med den att göra). Koda en egen istället. Det blir enklare i längden, ger mycket bättre prestanda, är mycket säkrare (om man har koll på bitarna) och är inte skadlig för hårddiskarna.

zoran 2006-03-28 14:00

Citat:

Originally posted by DeSoto@Mar 28 2006, 12:26
Det är generellt sett inte bra att lagra objekt i sessionsvariabler, eftersom objektet först serialiseras (heter det så?) och sparas i en fil på servern, och sen avserialiseras (unserialize) nästa gång användaren skickar en request till servern. Detta tar onödigt lång tid. Det är bättre att lagra värdena i din databas, och skapa ett nytt objekt för varje request. Du ska försöka lagra så lite som möjligt i sessionsvariabler.

Eftersom sessionsvariabel-filen lagras på servern finns det inget sätt för en användare att ändra på den (såvida han inte har tillgång till servern). Risken som finns är dock att en användare får reda på ett sessions-id från en administratör, och lurar servern med det sessions-id:et att han är administratören.

Och du har mätt prestandaskillnaden på serialisering->avserialisering av ett objekt kontra mysql-query och retur av data och kan presentera det för oss?

zoran 2006-03-28 14:06

Citat:

Originally posted by FredrikMH@Mar 28 2006, 12:04
Jag funderar lite över säkerheten i mitt system (som ännu ej är i bruk).

Det är så att jag använder session_register() på ett objekt av klassen User. Där användarnamn, lösenord osv finns lagrat. Detta för att jag vill på ett enktelt sätt komma åt all användarinformation på alla kommande sidor. Nu undrar jag om jag behöver kolla Objektet som kommer tillbaka så det inte har ändrats av användaren. Exemeplvis innuti objektet finns information lagrad om användaren är en vanlig användare, moderator eller en administratör.

Finns det möjlighet för användaren att modifiera detta och på så sätt skapa säkerhetshål i mitt script? I så fall behöver jag kontrollera all kritisk data överst i varje fil.

Du bör, som i alla andra fall, aldrig lagra ett lösenord i klartext. Ifall du har ett krypterat lösenord så tappar det sitt säkerhetsvärde. Med andra ord, spelar ingen roll om någon "får tag i det".

Du kan fortfarande autenticera mot det.

Jag brukar göra så här i en funktion för autenticering:

Ta användarnamnet som användaren skickar in,
Skapa en factory med användarobjekt (jag har få användare),
Hämta objektet med användarnamnet användaren skickade in,
Kryptera lösenordet användaren skickade in med lösenordet i användarobjektet jag fick som salt,
Om resultaten är samma som lösenordet i användarobjektet returnera objektet, annars null.

Sen i applikationen, om sessionen har ett userobjekt som inte är null, är användaren inloggad, annars inte.

FredrikMH 2006-03-28 14:12

Lösenord lagrar jag inte i klartext utan med md5().

zoran 2006-03-29 02:43

Citat:

Originally posted by FredrikMH@Mar 28 2006, 14:12
Lösenord lagrar jag inte i klartext utan med md5().
Dåså, vad har du att riskera ifall någon stjäl det?

Per 2006-03-29 08:42

md5:ar man utan salt krävs det endast att hitta en dublett för att logga in (jmf att använda salt då exakt lösenord måste hittas). Se vad zoran skrev, även om det kanske är smart att använda något mer än bara användarnamn som salt. För övrigt föredrar jag nog sha1.

zoran 2006-03-29 08:59

Citat:

Originally posted by Per@Mar 29 2006, 08:42
md5:ar man utan salt krävs det endast att hitta en dublett för att logga in (jmf att använda salt då exakt lösenord måste hittas). Se vad zoran skrev, även om det kanske är smart att använda något mer än bara användarnamn som salt. För övrigt föredrar jag nog sha1.
Nja, du missupfattade nog mig lite. Jag använder inte användarnamn som salt. När lösenordet skapas, (eller lagras första gången), används 2 random-bokstäver som salt. Däremot när jag ska verifiera lösenordet, måste jag kryptera det lösenordet som jag ska verifiera. För att krypteringen ska ge samma resultat, måste jag använda det krypterade lösenordet som salt (eller rättare sagt de två första bokstäverna).

freakalis 2006-03-30 15:52

Citat:

Originally posted by kullervo@Mar 28 2006, 13:00

Använder folk PHP's inbyggda session-hanterare till seriösa sajter? Det var länge sen jag ens tänkte på att det faktiskt finns en inbyggd i PHP. Den var kass för 4 år sedan (då jag senast hade med den att göra). Koda en egen istället. Det blir enklare i längden, ger mycket bättre prestanda, är mycket säkrare (om man har koll på bitarna) och är inte skadlig för hårddiskarna.

Jag är lite nyfiken hur skriver man sin egna sessionshanterare?

jahaa 2006-03-30 16:30

Citat:

Ursprungligen postat av freakalis
Citat:

Ursprungligen postat av kullervo
Använder folk PHPs inbyggda session-hanterare till seriösa sajter? Det var länge sen jag ens tänkte på att det faktiskt finns en inbyggd i PHP. Den var kass för 4 år sedan (då jag senast hade med den att göra). Koda en egen istället. Det blir enklare i längden, ger mycket bättre prestanda, är mycket säkrare (om man har koll på bitarna) och är inte skadlig för hårddiskarna.

Jag är lite nyfiken hur skriver man sin egna sessionshanterare?

Kika på http://se2.php.net/manual/sv/functio...ve-handler.php

kullervo 2006-03-30 19:48

Citat:

Originally posted by freakalis@Mar 30 2006, 14:52
Jag är lite nyfiken hur skriver man sin egna sessionshanterare?
Läs på php.net hur sessions fungerar.

dotvoid 2006-04-04 22:05

Citat:

Originally posted by kullervo@Mar 28 2006, 13:00
Använder folk PHP's inbyggda session-hanterare till seriösa sajter? Det var länge sen jag ens tänkte på att det faktiskt finns en inbyggd i PHP. Den var kass för 4 år sedan (då jag senast hade med den att göra). Koda en egen istället. Det blir enklare i längden, ger mycket bättre prestanda
Det nog rätt få seriösa utvecklare som inte använder PHP:s inbyggda sessionshanterare. Att själv sätta en cookie via http-headern Set-cookie är i o f s inte några större problem men onödigt. Däremot är det många som skriver egna krokar för lagring eller rensning av sessionsdata.

För bättre prestanda blir det nog ganska sällan med en userland-implementation i PHP än att använda PHP:s inbyggda funktioner som är skrivna i C. Det är bättre att koncentrera sig på sin applikation eller webbplats än att hålla på och bygga grejer som redan finns inbyggt i språket. Dock är det nog viktigt att man ändå "har koll på sina bitar".

Att lagra sessionsdata på fil, i en databas eller i RAM-minnet är en smaksak och beror på den miljö applikationen/webbplatsen körs i. På till exempel en delad unix-server skulle jag nog vara försiktig med att lagra sessionsdata i /tmp som ju ofta är standard.

Enda gången jag ser någon anledning till att inte använda PHP:s inbyggda sessionshantering (med eller utan egna krokar) är om man använder någon produkt eller extension för en single-sign-on-lösning.

kullervo 2006-04-05 00:36

Citat:

Ursprungligen postat av dotvoid
För bättre prestanda blir det nog ganska sällan med en userland-implementation i PHP än att använda PHP:s inbyggda funktioner som är skrivna i C.

Om man använder sig av sessions så bygger förmodligen sajten på en SQL-databas. Att bryta ut en del av datat (sessionerna) och lägga det separat någon annan stanns är ju bara krångligt och långsamt. Det är som att dela upp alla tabellerna i två databaser för en och samma sajt.

Citat:

Ursprungligen postat av dotvoid
Att lagra sessionsdata på fil, i en databas eller i RAM-minnet är en smaksak och beror på den miljö applikationen/webbplatsen körs i. På till exempel en delad unix-server skulle jag nog vara försiktig med att lagra sessionsdata i /tmp som ju ofta är standard.

Och vad är då vitsen med att använda PHP's inbyggda sessionhanterare när det är massa jobb att komma runt dess vanliga problem (såsom det där att det läggs fysiskt på disk och dessutom i /tmp)?

En mycket svag punkt för PHP är att den inte finns en standard för hur allt är konfigurerat. Låt oss säga att du har satt upp en LAMP-server konfigurerat så att du klarar mycket trafik med PHP's inbyggda sessionhanterare (dvs. lagrar datan på säkert ställe samt inte på disk). Vad händer då när du plötsligt ska byta server/webbhotell? Då sitter du kanske plötsligt på en mer standard-installation som både är osäker och långsam då den ska ändra datat i 200 sessions per sekund (stackars diskar). Hade det inte varit enklare då att haft en egen sessionhanterare integrerad i sajten? Jopp, det hade det nog.

Och åter igen, det är så mycket enklare att ha all data på samma ställe. Försök plocka ut användarnamnet på alla som är online just nu på en sajt som använder en separat sessionhanterare. Då ska du först ha ut alla användar-ID:n från alla sessioner (hur gör man ens det med PHP's inbyggda?) och sen ska du formulera det till en två mil lång SQL-fråga som läser ut användarnamnet från databasen. Suck och stön vad krångligt och segt.

dotvoid 2006-04-05 01:25

Citat:

Ursprungligen postat av kullervo
En mycket svag punkt för PHP är att den inte finns en standard för hur allt är konfigurerat ... Hade det inte varit enklare då att haft en egen sessionhanterare integrerad i sajten? Jopp, det hade det nog.

Verkligen inte. Just för att man har så olika behov är flexibilitet viktig. Så mycket jobb är det ju knappast att ändra till exempel /tmp då det ju finns en specifik metod för att ändra det runtime. Om du hanterar 200 sessioner per sekund tror jag inte det är snabbare med en databas än med en filbaserad lösning. Databasen måste också skriva och läsa data till och från disk. Dessutom måste den hantera index osv.
Citat:

Ursprungligen postat av kullervo
Och åter igen, det är så mycket enklare att ha all data på samma ställe. Försök plocka ut användarnamnet på alla som är online just nu på en sajt som använder en separat sessionhanterare. Då ska du först ha ut alla användar-ID:n från alla sessioner (hur gör man ens det med PHPs inbyggda?) och sen ska du formulera det till en två mil lång SQL-fråga som läser ut användarnamnet från databasen. Suck och stön vad krångligt och segt.

Jag vet inte om det är så krångligt. Man använder sig av PHP:s inbyggda sessionshantering men definierar en egen metod för att spara sessioner genom PHP:s session_set_save_handler(). I din egendefinierade metod för att spara sessionen är det lätt att plocka ut exempelvis ett användarid och koppla sessionsdata till detta och spara både sessionsdata och användarreferenser i en databas på det vis man vill.

Finns ingen anledning att skapa en egen sessionshantering när det finns så bra möjligheter att integrera PHP:s sessionshantering med sin egen kod.

Jag misstänker att vi är helt överens egentligen. Är det så att det du kallar för "egen sessionshanterare" egentligen bara är dina userland-funktioner du registrerar via session_set_save_handler()? I så fall missförstod jag nog din första post.

När jag läser "egen sessionshantering" så läser jag det som att man ersätter session_start() och $_SESSION med egen cookie-hantering och egna metoder för att registrera och läsa sessionsvariabler. Det var länge sen man behövde det. Däremot har många olika behov av lagringslösning för sessioner och det är en helt annan sak.

kullervo 2006-04-05 11:50

Citat:

Originally posted by dotvoid@Apr 5 2006, 00:25
Om du hanterar 200 sessioner per sekund tror jag inte det är snabbare med en databas än med en filbaserad lösning. Databasen måste också skriva och läsa data till och från disk. Dessutom måste den hantera index osv.

Jag misstänker att vi är helt överens egentligen. Är det så att det du kallar för "egen sessionshanterare" egentligen bara är dina userland-funktioner du registrerar via session_set_save_handler()? I så fall missförstod jag nog din första post.

Jag sa ju redan från början att det är helt onödigt att lägga sessions på disk. Självklart låter man inte sessions-tabellen i SQL-databasen heller ligga på disk. Och inte vill man att den ska logga ändringarna på disk heller. I MySQL finns ju HEAP-tabeller.

Nu har du inte tänkt till riktigt. Index är ju till för att snabba upp. Om du använder vettiga index går det snabbare. Om du missbrukar index så går det långsammare. Du kan ju inte utgå från att man använder korkade index bara för att man slänger upp sessions i en SQL-databas.

Nej, jag menar inte att en egen sessionhanterare använder PHP's färdiga sessionsfunktioner. Den sessionhanteraren jag gjort och som jag använder på ett flertal sajter är bara 12kiB stor. De timmarna det tagit att göra den och slipa på den är den värd många gånger om.

dotvoid 2006-04-05 20:56

Som jag sa tidigare, vilka behov man har skiljer sig åt väldigt. Har man en distribuerad miljö med flera lastbalanserade servrar är det ganska meningslöst att hålla sessionsdata i minnet på en enskild server. Då har man andra behov än om man har en enda server. Då måste man ha en fristående server för sessioner - oavsett metod för datalager. Ofta används t ex LDAP-databaser som lagringsmetod för single-sign-on-system då det normalt ger väldigt snabb åtkomst till data.

Om du pratar om HEAP (eller MEMORY) i MySQL finns också en del nackdelar eller risker om du hanterar många sessioner. Låt säga att du behöver lagra sessioner i minnet för att orka med prestandamässigt - då har du troligen många sessioner du hanterar och hög trafik (eller en dåligt dimensionerad maskin). Om du skulle få osedvanligt hög last helt plötsligt riskerar du att slå i taket och då konverterar MySQL automatiskt minnestabellerna till diskbaserade tabeller. Orkar maskinen med det då om du inte dimensionerat för detta? Och om du dimensionerat för detta - varför inte köra med diskbaserade tabeller redan från början?

Vill du ha hög tillgänglighet och använder replikering mellan två eller fler databaser finns också problem med minnesbaserade tabeller som måste hanteras. Skulle master-databasen gå ner rensas de minnesbaserade tabellerna helt från data. Detta hanteras inte alls av child-servrarna som då behåller gammal data.

Oavsett vilken modell man väljer, distribuerad eller ej, ser jag fortfarande ingen vits med att inte använda $_SESSION och php:s inbyggda sessionsmekanismer eftersom man ju normalt sett bygger egna lagringsmetoder och registrerar dem. Jag har svårt att tro att du nånsin kan få bättre prestanda med 12k php-kod än om du använder dig av den kompilerade c-koden i php-interpretatorn - oavsett om du lagrar det lokalt i minnet eller använder dig av mer raffinerade modeller.

Däremot inte sagt att din kod inte fungerar. Det gör den säkert. Alla, eller många, skrev sin egna sessionshantering innan den inbyggda implementerades i php - även jag. Så du gör som du vill - bra va :)


Alla tider är GMT +2. Klockan är nu 05:44.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson