session cookies verwijderen
https://secure.servage.net/wiki/Session
Anyway, nu valt me het volgende op. Als ik een sessie verwijder met session_destroy(); dan wordt de session cookie helemaal leeg gemaakt, maar het bestandje zelf blijft wel staan. Hoort dat zo? Ik ging er altijd van uit dat bij session_destroy() gewoon alles verwijderd zou worden...
De permissies van de map waarin de session cookies opgeslagen worden staan op 777 en de eigenaar ben ik.
Marlies Maalderink op 15/02/2017 17:01:02:
Als ik een sessie verwijder met session_destroy(); dan wordt de session cookie helemaal leeg gemaakt, maar het bestandje zelf blijft wel staan. Hoort dat zo?
Ja, dat hoort zo. Het bespaart namelijk heel wat uitstapjes naar het bestandssysteem. Er wordt niet aan de lopende band steeds maar één sessiebestand gewist, maar in één keer een heleboel sessiebestanden.
De kans dat deze garbage collector wordt geactiveerd, kun je regelen met session.gc_probability en session.gc_divisor in php.ini. De kans is daarbij gelijk aan session.gc_probability / session.gc_divisor.
Is dat niet teveel van het goede?
Als www-data er in kan schrijven en lezen is dat voldoende.
Ook vraag ik me af of session_destroy() ook niet te veel van het goede is?
Kan je niet beter het onderdeel van de session wat niet meer nodig is unsetten?
Bart, ja, misschien is dat idd wel wat veel van het goede. Had het nu klakkeloos overgenomen omdat mijn hostingprovider aangeeft dat je het zo moet doen. Vraag me wel af waarom ze dat dan zeggen.
Wat betreft session_destroy(), is dat niet een normaal onderdeel van uitloggen? In de praktijk zal dat trouwens niet eens zo heel veel voorkomen, maar het lijkt mij logischer om een log uit af te sluiten met een session_destroy(). Of zijn er goede redenen om dat niet te doen?
Chmodden naar 777 werkt inderdaad altijd, maar technisch gezien laat je nu een iedereen en dan bedoel ik de goede, maar ook de slechte lezen, schrijven, en uitvoeren.
Op zich is lezen en schrijven (heel voorzichtig gezegd) niet zo heel erg. Maar uitvoeren is een potentieel gevaar. Daarmee kan je hele stoute dingetjes doen. En dat zou ik als zowel gebruiker, als provider toch minder vinden als ik zomaar van alles mag doen op een server.
Dus wat ik zou doen is chown www-data:en_jou_gebruiker /var/www/html/weet_ik_niet_welkemap/sessions/
Wat betreft session_destroy(), dat het een hele normale actie is, en vrijwel overal op het net gebeiteld staat klopt. Maar als je wat verder er over nadenkt is het net zoiets als een mug met een kanon proberen af te schieten. Ik weet natuurlijk niet wat voor applicatie dat je aan het schrijven bent, maar ik zou me zomaar kunnen voorstellen bij een webshop bijvoorbeeld dat je een $_SESSION['ingelogd'] aanmaakt om bestellingen in te zien, maar in die zelfde session_start() kan bijvoorbeeld ook een $_SESSION['bewaar_winkelwagen'] of $_SESSION['favoriet'] in zitten. Met session_destroy() schiet je dus ook met dat zelfde kanon de rest van de bewaarde waardes in je $_SESSION af.
Dus waarom zou je de als je alleen het inloggen wilt opheffen alles weggooien?
Toegeven, ik gebruik voor enkel inloggen en uitloggen het ook session_destroy(), maar zou ik wat meer opties hebben dan doe ik dat niet.
Gewijzigd op 15/02/2017 18:57:44 door Bart V B
De oplossing is niet alleen session_destroy() aanroepen, maar éérst niets opslaan in het sessiebestand door $_SESSION op een lege array in te stellen. Bijvoorbeeld uitloggen bestaat dan uit drie stappen:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
$_SESSION = array();
if (ini_get('session.use_cookies')) {
$cookie_params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $cookie_params['path'], $cookie_params['domain'], $cookie_params['secure'], $cookie_params['httponly']);
}
session_destroy();
?>
$_SESSION = array();
if (ini_get('session.use_cookies')) {
$cookie_params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $cookie_params['path'], $cookie_params['domain'], $cookie_params['secure'], $cookie_params['httponly']);
}
session_destroy();
?>
In dit geval gaat het alleen om in en uitloggen.
Ward, dan telt het inderdaad snel op. Maar als je een session_destroy() doet, wordt hij dan ook niet leeg gemaakt? (als ik een session cookie bekijk van een session die ik heb ge-destroyed, dan staat er ook niets meer in namelijk...) Of is er dan nog verborgen data of maakt hij hem niet altijd leeg?
Indien het gaat om uitloggen, wat een "state change" is, loont het misschien ook de moeite om:
- het sessie-id te verversen met session_regenerate_id()
- direct na dit alles de pagina te verversen met header('Location: xyz') gevolgd door een exit-statement zodat de nieuwe toestand ook meteen van kracht is
Thomas van den Heuvel op 16/02/2017 10:20:15:
Indien het gaat om uitloggen, wat een "state change" is, loont het misschien ook de moeite om:
- het sessie-id te verversen met session_regenerate_id()
- direct na dit alles de pagina te verversen met header('Location: xyz') gevolgd door een exit-statement zodat de nieuwe toestand ook meteen van kracht is
- het sessie-id te verversen met session_regenerate_id()
- direct na dit alles de pagina te verversen met header('Location: xyz') gevolgd door een exit-statement zodat de nieuwe toestand ook meteen van kracht is
Dat laatste doe ik al. Wat betreft het eerste, op welke plek de je dat? Na het leegmaken van de session maar voor session_destroy? Klopt het dat je dan dit krijgt?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
public function uitloggen() {
$this->lifetime = -4200;
$_SESSION = array();
$cookie_params = session_get_cookie_params();
session_set_cookie_params( $this->lifetime, $cookie_params[ 'path' ], $cookie_params[ 'domain' ], $cookie_params[ 'secure' ], $cookie_params[ 'httponly' ] );
session_regenerate_id(true);
session_destroy();
}
?>
public function uitloggen() {
$this->lifetime = -4200;
$_SESSION = array();
$cookie_params = session_get_cookie_params();
session_set_cookie_params( $this->lifetime, $cookie_params[ 'path' ], $cookie_params[ 'domain' ], $cookie_params[ 'secure' ], $cookie_params[ 'httponly' ] );
session_regenerate_id(true);
session_destroy();
}
?>
Gewijzigd op 16/02/2017 11:44:49 door Marlies Maalderink
Maar als je dit (aanroep van session_regenerate_id()) op zijn minst bij het inloggen doet (ook een state change) is dat misschien al wel genoeg.
Dus in principe wordt het session_id regelmatig geregenereerd. Het lijkt overigens prima te werken zoals het hierboven staat, alleen betwijfel ik of session_regenerate_id hier uberhaupt iets toevoegd of er een beetje voor niets tussen staat.
Hm, laat voorlopig maar weg dan. Er stond mij iets bij over state changes, maar als de state change tevens inhoudt dat de sessie beëindigd wordt dan is dat nogal loos wellicht ja.
Ga ik het weghalen. Thanks voor het meedenken!
Thomas van den Heuvel op 16/02/2017 14:42:14:
Er stond mij iets bij over state changes, maar als de state change tevens inhoudt dat de sessie beëindigd wordt dan is dat nogal loos wellicht ja.
Dat is gewoon correct. Overschakelen van HTTP naar HTTP/S is zo'n state change. En overschakelen van anonieme bezoeker naar ingelogde gebruiker is er ook een.
Maar de hamvraag is daarom: heeft de uitgelogde gebruiker nog een sessie? Gebruik je ergens anders nog een session_start(), dan is het antwoord waarschijnlijk: ja. Wordt de sessie na het uitloggen niet beëindigd maar voortgezet met minder rechten, dan is ook dat een state change.
Hoewel hij na het uitloggen geredirect wordt naar de login pagina waar ik wel weer session_start gebruik. (maar dat staat los van de uitloggende gebruiker)
Dat staat er niet los van: eigenlijk hadden ze session_start() voor de duidelijkheid session_start_or_restart() moeten noemen.
Is die sessie dan nog steeds niet echt weg? En zou ik dus toch het session id moeten regeneren?
Potverdorie wat moet je doen om van een sessie af te komen ;)
Waarom zou je het NIET doen? Het kan toch geen enkel kwaad?
Het regenereren van een ID doe je om een mogelijke session-hijacking te voorkomen.
Als Piets eerste session ID 'abc' heeft en na het regenereren 'xyz' dan is hij nog steeds gewoon gekoppeld aan hetzelfde sessiebestand. Het enige wat je doet is het een hacker lastig maken die het gemunt heeft op de sessie (het sessiebestand) met ID 'abc'.
Dus ... heel simpel. Maak gewoon de sessie leeg als iemand uitlogt.
$_SESSION = [];
Nu staat er niks zinvols meer in. En als je wilt kun je dan ook nog regenereren.
Ozzie PHP op 16/02/2017 18:06:51:
Waarom zou je het NIET doen? Het kan toch geen enkel kwaad?
Waarom zou je het NIET doen? Het kan toch geen enkel kwaad?
Dat is waar. Ik zet hem er wel weer in...
ondertussen ga ik wel een beetje off-topic, sorry daarvoor.
In totaal zijn de sessies nu beveiligd op de volgende manier:
- de session-cookies worden ingesteld op httponly en op secure als die mogelijkheid er is
- de user agent en het ip adres worden opgeslagen als er iemand inlogt (gehashed samen met het wachtwoord)
- het session id word geregenereerd direct na inloggen, en daarna bij 20% van de session_starts
- bij het uitloggen wordt de sessie leeggemaakt, de lifetime in het verleden gezet, nogmaals geregenarate en dan gedestroyed
- de formulieren zijn voorzien van tokens die ik ook in een sessie opsla en direct na het controleren weer leegmaak.
Kan ik nog meer doen om de sessies te beveiligen of zit ik zo wel goed?
Gewijzigd op 16/02/2017 20:06:50 door Marlies Maalderink
Dit kun je beter niet doen. Een IP-adres kan gedurende de sessie wijzigen.
>> de lifetime in het verleden gezet
Dit lijkt me niet nodig.
>> de formulieren zijn voorzien van tokens die ik ook in een sessie opsla en direct na het controleren weer leegmaak
Het leegmaken lijkt me ook niet per se nodig. Gewoon zorgen dat er iedere keer als je het formulier aanroept een nieuwe token wordt gegenereerd.
Ik denk dat het pas weer uitmaakt dat het sessie id verandert (na leeggooien, destroy en het unsetten van het cookie) als je er weer spannende dingen mee gaat doen zoals inloggen. Maar je zei al dat je op dat moment regenerate. Daarnaast ben je je "link" met je sessie id kwijt doordat je het sessie-cookie weggooit.
In het ergste geval kaapt iemand een lege sessie ;-). Niet zo bijzonder boeiend lijkt mij. Maar het is een state change, da's waar :].
Gewijzigd op 16/02/2017 22:57:36 door Thomas van den Heuvel