Zodra een gebruiker is ingelogd, staat het sessie-ID tijdelijk gelijk aan de sterkste authenticatiemethode die de applicatie heeft gebruikt, of dat nu een wachtwoord, een eenmalige code, een clientcertificaat, een smartcard of een vingerafdruk was. Kan een aanvaller dat ID raden, onderscheppen of opdringen, dan is hij de gebruiker en komt het inlogformulier er niet meer aan te pas. Sessies testen betekent daarom: het ID testen, de cookie die het draagt, en wat de server ermee doet bij het inloggen, na inactiviteit en bij het uitloggen.
Deze checklist volgt de OWASP Session Management Cheat Sheet en RFC 6265, de cookiespecificatie.
Het sessie-ID zelf
Begin bij de manier waarop het ID wordt gemaakt. De cheat sheet eist minimaal 64 bits entropie uit een cryptografisch veilige random number generator. Bij die lengte schat het document dat het ongeveer 585 jaar kost om een geldig ID te raden, uitgaande van 10.000 pogingen per seconde en 100.000 gelijktijdig geldige sessies. Genereert u zelf ID's in plaats van die van het framework te gebruiken, dan adviseert het document minimaal 128 bits en een unieke waarde per sessie.
Let op vaste of voorspelbare delen. Een hexadecimaal ID van 16 tekens waarvan de helft vast is, heeft slechts 32 bits entropie, en dat is te weinig. De waarde mag voor de client ook niets betekenen: geen gebruikers-ID, rol of e-mailadres erin. Bewaar die gegevens op de server.
Controleer ook de naam. Standaardnamen als PHPSESSID, JSESSIONID, CFID/CFTOKEN en ASP.NET_SessionId verraden aan een aanvaller welke stack u draait. De cheat sheet stelt een generieke naam voor, zoals id.
Accepteer het ID nooit in een URL. ID's in URL's lekken via links, logs, browsergeschiedenis, bladwijzers, de Referer-header en zoekmachines, en ze maken session fixation eenvoudiger.
Valt leestoegang tot uw sessieopslag binnen uw dreigingsmodel, dan vormen onbewerkte tokens een risico. De cheat sheet beschrijft een gesplitst ontwerp: de cookie bevat een identifier en een geheime verifier, en de server bewaart de identifier plus de SHA-256-hash van de verifier, die in constante tijd wordt vergeleken. De identifier alleen wordt nooit geaccepteerd.
Cookie-attributen
RFC 6265 definieert voor een Set-Cookie-header de volgende attributen: Expires, Max-Age, Domain, Path, Secure en HttpOnly.
Securemarkeert de cookie voor beveiligde verbindingen. De RFC waarschuwt dat het geen integriteit biedt tegen een actieve netwerkaanvaller, behandel het dus niet als bescherming daartegen.HttpOnlyhoort op elke sessiecookie. Controleer de vlag in de developer tools van de browser.DomainenPathbepalen het bereik. Houd beide niet breder dan de applicatie nodig heeft.ExpiresenMax-Agevertellen de browser hoe lang de cookie bewaard moet blijven. Gebruik ze niet als uw timeout.
Controleer de overige response headers met onze security headers-tool.
Inloggen, timeouts en uitloggen
Een sessie-ID dat de browser vóór het inloggen al had en daarna behoudt, is precies waar fixation-aanvallen op leunen. Geef een nieuw ID uit zodra de gebruiker zich authenticeert, zodat het eerdere ID niet meer geldig is.
Timeouts vragen om twee limieten. Een idle timeout beëindigt sessies die niemand gebruikt. Een absolute timeout beëindigt sessies die eindeloos actief blijven, waardoor een gestolen ID beperkt bruikbaar blijft. Leg de waarden vast, kies ze korter voor beheer en betalingen, en dwing ze af op de server door het opgeslagen sessierecord te controleren, niet de verloopdatum van de cookie.
Uitloggen moet de sessie op de server vernietigen. De cookie in de browser wissen is niet genoeg, want de identifier is het credential: wie hem eerder heeft gekopieerd, kan hem nog steeds meesturen. Na het uitloggen moet het oude ID naar niets meer verwijzen. De cheat sheet bevat ook een sectie over caching van webcontent en Clear-Site-Data, die het lezen waard is voor wat de browser na het uitloggen nog bewaart.
Gebruik waar mogelijk de ingebouwde sessieafhandeling van het framework. De cheat sheet merkt op dat deze implementaties kwetsbaarheden hebben gehad, dus draai de nieuwste versie en controleer de standaardinstellingen.
Wat u test
- Leg de cookie vast vóór en na het inloggen. Het eerste request moet daadwerkelijk een sessiecookie zetten, controleer dus dat
before.txtniet leeg is. Bewaar de inloggegevens in een bestand (creds.txtmetuser=test&pass=...), zodat ze niet in de shellgeschiedenis belanden. De twee ID's moeten verschillen.
curl -i -c before.txt https://app.example/login curl -i -b before.txt -c after.txt -d @creds.txt https://app.example/login
- Log uit met de geauthenticeerde cookie en speel daarna de oude waarde opnieuw af, afkomstig uit de laatste kolom van
after.txt. Die moet worden geweigerd. Is uitloggen een POST, voeg dan-d ''toe aan het eerste commando.
curl -i -b after.txt https://app.example/logout curl -i -b 'id=VALUE_FROM_AFTER_TXT' https://app.example/account
- Log in, blijf inactief tot voorbij de idle timeout en stuur dan een request. Opnieuw authenticeren moet vereist zijn.
- Houd een sessie actief tot voorbij de absolute timeout. Ze moet toch eindigen.
- Controleer
Set-Cookiein de loginresponse opSecure,HttpOnlyen eenDomainenPathdie niet breder zijn dan nodig. - Verzamel een paar honderd ID's en vergelijk ze. Vaste segmenten en opeenvolgende waarden zijn bevindingen. Vergelijk de cookienaam met de hierboven genoemde standaardnamen van frameworks.
- Doorzoek de applicatie, logs en links op sessie-ID's in URL's.
Rapporteer bevindingen tegen OWASP ASVS met vermelding van de versie: v5.0.0-<chapter>.<section>.<requirement>. ASVS 5.0.0 is gepubliceerd op 30 mei 2025 en de eisen zijn beschikbaar als CSV. Voeg aan uw testsheet een kolom toe met de identifier van elke test, zodat een mislukte test leest als een bevinding met verwijzing naar de bijbehorende eis.
Waar te beginnen
- Voer test 1 en 2 eerst uit op staging: de vergelijking van de ID's vóór en na het inloggen, daarna de replay na uitloggen.
- Leg de
Set-Cookie-header van uw sessiecookie vast en herstel de attributen die ontbreken of te breed zijn. - Controleer hoe ID's worden gegenereerd. Hebt u zelf een generator gebouwd, stap dan over op die van het framework, of bevestig dat deze een veilige random-bron gebruikt met minimaal 128 bits.
- Leg de idle en absolute timeouts vast, dwing ze af op de server en voeg tests toe die falen als iemand ze verwijdert.
- Laat uitloggen het sessierecord op de server verwijderen en voeg de replaytests toe aan uw regressiesuite.
