session timeout
Maak je de sessie timeout-duur te lang, bijv. 2 uur, dan vergroot je (theoretisch gezien) de kans dat een sessie wordt gekaapt.
Dus wat is wijsheid? Wat is een goede session timeout-duur?
Quote:
Maak je de sessie timeout-duur te lang, bijv. 2 uur, dan vergroot je (theoretisch gezien) de kans dat een sessie wordt gekaapt.
Toch alleen als je beveiliging ontoereikend is.
Zoals ik al eerder heb aangegeven, in plaats van het krampachtig proberen je sessies in leven te houden kun je beter inzetten op een strategie waarbij het niet uitmaakt dat deze (veelvuldig) verlopen en weer (veelvuldig) naadloos vervolg worden (onder water geherstart worden) zonder dat dit je applicatie/workflow/whatever breekt.
Gewijzigd op 11/06/2016 18:09:49 door Bas IJzelendoorn
Ik snap niet helemaal wat je bedoelt. Eenmaal verlopen is verlopen, dus dan kun je niet onderwater herstarten. Er zal op dat moment een nieuwe sessie worden gestart en alle sessie-data is dus foetsie. Wat ik bedoel te zeggen is ... soms wil je niet dat een sessie (te) snel verloopt. Stel iemand heeft spullen in z'n winkelmand gegooid en gaat even een blokje om lopen. Komt een half uur later terug. Klikt op z'n winkelmandje om af te rekenen, maar in de tussentijd is de sessie verlopen. Mogelijk gevolg, klant raakt gefrustreerd en sluit de browser af. Koop gaat niet door. Tegelijkertijd ... de back-end van een website wil je weer niet té lang hebben open staan. De vraag is dus of er een soort "balans" is. Ik lees ook websites waar ze pas na 24 uur een timeout doen. Zo'n sessie blijft dus een hele dag lang geldig. Als tegengeluid hoor je hier dan weer dat je moet oppassen voor session hijacking. Hoewel je daar het een en andere tegen kunt doen, is het wel een reëel risico. Hoe reëel? Geen idee ... daarom ben ik dus benieuwd naar ervaringen / best practices.
@Ward
>> Je opent de laatste tijd voortdurend vragen over het configureren van een VPS
Waar in de richtlijnen van dit forum staat dat dit niet mag? Iedereen is vrij om vragen te stellen en iedereen is vrij om die te beantwoorden (of niet). Volgens mij is dit forum bedoeld om elkaar te ondersteunen en helpen. Het inrichten van een server beslaat veel meer facetten dan enkele php.ini instellingen waar ik graag even over wil sparren.
Ik vind jouw reactie in deze een beetje vreemd en ook onverwachts. Liever had ik dan nog gehad dat je me een persoonlijk berichtje had gestuurd. Maar goed, als jij dit topic graag wil dichtgooien ... go ahead.
Daarbij snap ik waar Thomas op doelt, je kunt je sessies combineren met andere methoden, bijvoorbeeld een cookie met een token oid, op welke basis je sessies kunt opbouwen/hervatten mbv gegevens die je al hebt. Ik heb zelf eerder gespeeld met een database session handler die in plaats van data verwijderen de data als inactief meldde, en na X periode uiteindelijk de zaak schoonveegde. Als je hier een token aanhangt kun je blijven hervatten zo vaak als je wilt.
In een back-end zou je bijv. kunnen kiezen dat een sessie 20 min. openstaat ... maar achter de schermen kun je ervoor zorgen dat de daadwerkelijk timeout langer duurt, bijv. een uur. Als de gebruiker 20 minuten lang niks doet, kun je bij de eerstvolgende request vragen om het wachtwoord. Als dat klopt, dan kun je de sessie weer vrijgeven, en als het niet klopt dan kun je de sessie-data vernietigen. Gevolg is dan wel dat als een gebruiker inlogt en een uur lang niks doet, het sessie-bestand op de achtergrond een uur lang "actief" is en pas na dat uur als inactief wordt bestempeld. Vergroot dit het risico op session-hijacking?
De manier die je schetst kan een uitkomst bieden, bij verloop van de sessie om een wachtwoord vragen. Dit vereist tegelijk wel dat je in een cookie bijhoudt om welke gebruiker het gaat. Als je een session cookie gebruikt (timeout 0) is dit geen enkel punt, bij het sluiten van de browser gaat dit cookie verloren.
Op het punt van hijacking: session hijacking kan voorkomen wanneer je onveilig met de data omgaat. Net als dat je niet wilt dat URLs van het backend bekend worden. Hier zijn uiteraard oplossingen voor, zoals een tussenliggende pagina op een neutrale locatie, die mbv bijvoorbeeld een Refresh header de uiteindelijke URL opvraagt, dan is de Referer header tenminste leeg. Verder is het zaak om gewoon te voorkomen dat men toegang krijgt tot de session id, en een eenvoudige oplossing is session.use_only_cookies aan te zetten, waardoor er geen session id's in urls gestopt worden. Uiteraard kun je per sessie de parameters instellen met o.a. session_set_cookie_params
Ja inderdaad ... de sessie blijft nog even aanwezig totdat de GC in actie komt. Ook weer zo'n leuke. Die kun je heel "strak" afstellen, zodat ie bij ieder request wordt getriggerd, maar dat is dan weer niet lekker voor de performance ... althans dat stelt men. De default session.gc_divisor in mijn php.ini stond maar liefst op 1000 en session.gc_probability op 0! Waarschijnlijk probeert mijn hostingboer op deze manier om zo min mogelijk processorkracht te verbruiken. Maar die GC komt dan dus nooit in actie :-s
>> Dit vereist tegelijk wel dat je in een cookie bijhoudt
Dat gaat toch als het goed is automatisch als je een sessie-start. In de sessie zelf moet ik dan een "last_active_time" of iets dergelijks opnemen, die ik dan vergelijk met de huidige tijd.
>> Hier zijn uiteraard oplossingen voor, zoals een tussenliggende pagina op een neutrale locatie ...
Ik volg niet helemaal wat je hiermee bedoelt. Wat voor pagina bedoel je, en waarom moet de referer leeg zijn? Wie kan daar iets mee?
>> Verder is het zaak om gewoon te voorkomen dat men toegang krijgt tot de session id, en een eenvoudige oplossing is session.use_only_cookies aan te zetten ...
Dat klopt. Dat heb ik gedaan, maar dan nog kan men toch een cookie spoofen met telkens een andere session-id? Wel een hoop werk en weinig kans van slagen .. maar de mogelijkheid is er wel lijkt me.
De mogelijkheid is er wel, maar dat zal volgens hetzelfde stramien (en dus hetzelfde tempo) gaan als het raden van een wachtwoord. Hoe lang gaat het duren om de juiste string te raden uit 63^27 mogelijkheden?
>> De default session.gc_divisor in mijn php.ini stond maar liefst op 1000 en session.gc_probability op 0! Waarschijnlijk probeert mijn hostingboer op deze manier om zo min mogelijk processorkracht te verbruiken. Maar die GC komt dan dus nooit in actie :-s
Ik weet dat op Debian standaard de gc_probability op 0 staat, en met cronjob verouderde session bestanden worden weggegooid. Mogelijk speelt bij jou iets soortgelijks.
>> Dat gaat toch als het goed is automatisch als je een sessie-start. In de sessie zelf moet ik dan een "last_active_time" of iets dergelijks opnemen, die ik dan vergelijk met de huidige tijd.
Als je sessie vernietigd wordt door een timeout lijkt het me niet dat je nog bij de gegevens in de sessie kan, dus je zult dit apart moeten opslaan van je sessie.
>> Ik volg niet helemaal wat je hiermee bedoelt. Wat voor pagina bedoel je, en waarom moet de referer leeg zijn? Wie kan daar iets mee?
Het zou niet de eerste keer zijn dat ik zie dat een aanval getriggerd wordt door een ongelukkige link naar een externe partij, die bij het ontdekken van de URLs naar een backoffice vol aan de slag ging. Hoe beter je je backend verborgen kunt houden, hoe veiliger het blijft. Dit is uiteraard iets dat naast de beveiliging speelt, maar als niemand weet waar hij moet zijn om je backend te benaderen loopt het risico ook enorm terug.
Eens, maar als je een sessie pas na 24 uur een time-out geeft, dan heeft men dus wel een dag de tijd om te 'raden'.
>> Ik weet dat op Debian standaard de gc_probability op 0 staat, en met cronjob verouderde session bestanden worden weggegooid. Mogelijk speelt bij jou iets soortgelijks.
Oké, dat wist ik niet. Ik lees het hier nu inderdaad. Oplossing is inderdaad gewoon om de waarde te wijzigen.
>> Als je sessie vernietigd wordt door een timeout lijkt het me niet dat je nog bij de gegevens in de sessie kan, dus je zult dit apart moeten opslaan van je sessie.
Haha, ja da's inderdaad een goede ... dat gebeurt op het moment dat de sessie dus écht z'n limiet heeft bereikt. Bijv. de sessie timeout vindt na een uur plaats, maar na 20 min. inactiviteit maak je deze onbereikbaar voor de gebruiker (bijv. omdat die in de back-end aan het werk is). Voordat hij verder kan moet hij dan eerst z'n wachtwoord invoeren. Echter, doet hij een uur helemaal niks, dan is de sessie compleet verlopen en zal er een nieuwe sessie worden aangemaakt. Anders gezegd 'achter de schermen' bestaat de sessie een uur, maar na 20 min. inactiviteit moet een gebruiker eerst een wachtwoord invoeren om verder te kunnen. Gaat dat mis, dan kun je de sessie verwijderen/leegmaken.
En hier raken we dus de kern van mijn vraag ... wat is een goede duur voor de sessie timeout? Na hoeveel minuten COMPLETE inactiviteit moet je zeggen: oké, vanaf nu is deze sessie echt niet geldig meer. Daarbij spelen in principe 2 factoren van belang. 1. Je wil een gebruiker voldoende tijd geven om iets te kunnen doen. 2. Je wil een actieve sessie niet te lang 'in leven houden' om sessie-hijacking te voorkomen. Wat gebruik jij zelf meestal als session timeout?
>> ... maar als niemand weet waar hij moet zijn om je backend te benaderen loopt het risico ook enorm terug.
Dat is zeker waar. Goed punt inderdaad.
PS Weet jij trouwens of een verlopen sessiebestand nog benaderd kan worden? Stel een sessie krijgt na een half uur een timeout, maar wordt pas een paar uur later door de gc verwijderd. Kan in de tussentijd dan iemand die sessie nog benaderen door de session id te 'raden', of zegt het sessiebestand dan 'ik ben o niet meer geldig' en gebeurt er verder niks?
Gewijzigd op 28/05/2016 15:09:03 door Ozzie PHP
Mijn antwoord zou zijn: zou afhangen van de applicatie.
Maar ook: er zijn meerdere manieren om een probleem op te lossen, bijvoorbeeld door het wegnemen van het probleem zelf. In een oplossing waarbij het niet uitmaakt dat een sessie verloopt is het verlopen van een sessie geen probleem...
Het is maar net hoe ver je je catering voor (de domheid?) van een gebruiker wilt laten gaan. Ik ken weinig mensen die in een shopping-spree voor de aankoop nog even een wandeling gaan maken eigenlijk.
It is impossible to make anything idiot proof, because idiots tend to be ingenious.
Quote:
Net als dat je niet wilt dat URLs van het backend bekend worden.
Security through obscurity is zelden een goed ontwerpprincipe.
Quote:
Het zou niet de eerste keer zijn dat ik zie dat een aanval getriggerd wordt door een ongelukkige link naar een externe partij, die bij het ontdekken van de URLs naar een backoffice vol aan de slag ging.
Als ik het bovenstaande zo lees dan was de veiligheid van die applicatie(s) lang niet robuust genoeg. En wederom is dan een menselijke f*ckup de bron van alle ellende (maar je zou dus ook vraagtekens kunnen plaatsen bij de sterkte van security als je dmv een link een backend in kan duiken). Een systeem beveiligen met state-of-the-art shizzle heeft weinig zin als iemand het moeilijk te onthouden wachtwoord als post-it aan zijn/haar monitor plakt eh.
Om ten langen leste antwoord te geven op je generieke vraag, een generiek antwoord:
De default sessie-timeout is een goede sessie-timeout. Te meer omdat deze al naar gelang de situatie on-the-fly aangepast kan worden.
Dat is zeker waar. De vraag is alleen óf, en zo ja hoe je dit volledig kan dichttimmeren.
>> Te meer omdat deze al naar gelang de situatie on-the-fly aangepast kan worden.
Dit is natuurlijk ietsje te makkelijk ... veel instellingen kunnen on the fly worden aangepast. Betekent echter niet dat je daarom niet hoeft na te denken over een goede basisinstelling.
>> De default sessie-timeout is een goede sessie-timeout.
Oké ... maar leg mij dan eens uit waarom die default setting van 1440 seconden (ofwel 24 minuten) een goede setting is volgens jou? Waar baseer jij dat op? Ik kan je alvast verklappen dat die 1440 seconden per toeval de default zijn geworden, omdat de default van oudsher eigenlijk een dag was (1440 minuten). In de loop der jaren zijn die minuten ooit per ongeluk seconden geworden. Er zit dus niet een of andere gedachte achter die 24 minuten. Maar dan ben ik dus benieuwd waarom dit volgens jou exact de juiste setting is.
Gewijzigd op 28/05/2016 16:56:36 door Ozzie PHP
Toegegeven, het is naïef om er vanuit te gaan dat iets per definitie zijn default waarde heeft en het is altijd verstandig om dit te toetsen, maar ik vind het al helemaal takke-irritant als webhosters zelf denken slim te zijn en een heleboel waarden een eigen, en afwijkende, default te geven.
Assumption is the mother of all f*ckups, en ik kon mijzelf wel voor mijn kop slaan toen ik een poos geleden er achterkwam dat een host register_globals aan had staan, maar ik vroeg mij tegelijkertijd af wat de mentale gesteldheid van iemand is om dit zelf zo te configureren als de standaard al jaren "Off" is...
Defaults worden inderdaad vaker zomaar aangepast ... maar bij mij staat de default voor de session timeout wel gewoon op 1440. Dus die is niet aangepast. Ik kan 'm wel zelf wijzigen ... maar de vraag is in hoeverre dat dus een risico met zich meebrengt. Stel dat ik de timeout instel op bijv. 3600 seconden (ofwel een uur) worden mijn websites dan gevoeliger voor session hijacking? Of is het verschil tussen 24 minuten versus een uur verwaarloosbaar in dat opzicht?
In dat opzicht is het verwaarloosbaar. De risico's op hijacking worden ook zwaar overdreven. Het is uiteraard afhankelijk van de responsetijd van je applicatie, maar 63^27 is bijna een 4 met 48 nullen aan combinaties. In theorie kun je een keer geluk hebben en op een key als aaaaaaaaaaaaaaaaaaaaaaaaaaa tegenkomen, maar de kans daarop is 1 op de 63^27. Je beveiliging staat of valt niet met de sessieduur, maar de overige maatregelen. Op een forum als dit zou ik geen IP controle gebruiken, er is geen echt gevoelige informatie. Bij andere applicaties wel, of deels (bijvoorbeeld de eerste 3 octets). Vermoedelijk bestaat de session timeout ook alleen om sessies na verloop van tijd op te kunnen ruimen en heeft het geen ander doel. Hier heb ik geen harde data over, maar het voelt logischer dan iets anders.
Oké, thanks. Gebruik jij zelf ook een langere timeout-duur, of gebruik je de default?
Gewijzigd op 28/05/2016 23:20:24 door Ben van Velzen
Wat bedoel je daarmee? Dat je geen "fysieke" sessiebestanden hebt, maar dat je alle sessiedata in de database opslaat? Of begrijp ik je nu verkeerd?
Dat bedoel ik inderdaad.
Ah oké ... geinig :-)
session_set_save_handler is hetzelfde. Je maakt een functie voor het lezen van je sessie, het openen, sluiten etc, en niet onbelangrijk: de gc handler. Je kunt hierdoor veel invloed uitoefenen vanuit je handlers met je implementatie. Het heeft als bijkomend voordeel dat je de sessies centraal kunt weergeven/stoppen etc. Je kunt gebruikers hiermee dus ook controle geven over hun lopende sessies.
Voorbeelden genoeg, er is een topic van eerder vandaag waarin zo'n handler staat. Nu zou ik hem anders opbouwen, maar de strekking van het gebruik van