Archief - De topics van lang geleden

[Web] Session Hijacking achter NAT

04-10-2007, 22:46 door Eghie, 4 reacties
Ik ben bezig met beveiliging van een authenticatie systeem,
wat via PHP werkt. Nu is dit een SSO systeem. Omdat dit een
authenticatie systeem is, wil ik dit zo veilig mogelijk
hebben. Nu is er 1 probleem waar ik wat moeite mee heb en
dat is het voorkomen van session hijacking.

De meeste van jullie weten waarschijnlijk wel, dat een
standaard PHP sessie makkelijk te hijacken is. Je grijpt een
session cookie van iemand (eigenlijk alleen de session id)
en je bent binnen. De bekende if ($_SESSION["loggedin"])
werkt zelf niet daartegen.

Nu heb je in PHP de functie, session_regenerate_id(true).
Deze functie hergenereerd je sessie id. Dit verkleind enorm
de tijd op waarop iemand je sessie kan hijacken. Dit komt
omdat hij bij elke keer bij het laden een nieuwe sessie id
krijgt, waardoor de oude ongeldig wordt. Nu is dat een
redelijk goede beveiliging. Maar stel nu dat bij de laatste
handeling die de gebruiker doet op de site, de cookie wordt
gejat, dan krijgt de aanvaller alsnog een geldige id.

Nu kun je de sessie ook nog aan een IP koppelen. Ik neem
meteen ook maar even mee dat je de sessie ook aan useragent,
accept language, accept charset, etc zou koppelen. Dus dan
heb je een identiteit te pakken die bijna zeker aan
jouw browser is gekoppeld. Maar nu komt het probleem:

Stel je zit in een groot bedrijf. Dit bedrijf zit achter een
NAT router. Bedrijf heeft allemaal gestandariseerde
software. Dit betekend dat bij dit bedrijf, bij elke PC de
volgende gegevens gelijk zijn: extern ip, useragent, accept
language, accept charset, nog wat browser specifieke dingen.
Stel ze gebruiken geen proxy die X-forwarded-for meegeeft,
dus aan intern IP kun je ze ook niet aan herkennen. Als
conclusie uit dit laatste stukje kun je trekken, dat elke
PC, binnen het bedrijfs netwerk, gelijk is voor de
webserver. Ze hebben allemaal dezelfde identiteit. Dus de IP
koppeling en andere browser checks die gekoppeld zijn aan de
sessie komen ze door.

Als ze nu in dit geval, de laatste cookie van de gebruiker
jatten, vanuit het bedrijfsnetwerk, dan kunnen ze gewoon
verder met de sessie. Dit omdat ze alle checks gewoon doorkomen.

Nu zeg ik er even bij dat dit SSO systeem WEB only is, dus
niet iets als kerberos ofzo, wat ook systemen in het netwerk
identificeerd. Ga er ook maar even van uit dat we niet
altijd controlle hebben over het netwerk.

Hoe kun je toch voorkomen, dat mensen binnen het netwerk
(achter NAT), toch niet de sessie kunnen overnemen van de
collega?

Het probleem wat er namelijk is, je hebt namelijk geen
100% zekere identiteit van de specifieke PC. Dit is
ook wel logisch, vanwege privacy redenen. Anders kon Google
wel heel makkelijk een profiel van je schetsen, wat ze nu
overigens ook heel goed kunnen.

Hoe gaan jullie met dit probleem om?

Houd er wel even rekening mee dat het SSO is, dus ook niet
bedoeld is om voor elke pagina opnieuw te authenticeren.
Uiteraard gaan erg belangrijke pagina's, zoals wachtwoord
wijziging, wel met de vraag om nog een keer je wachtwoord in
te voeren.
Reacties (4)
05-10-2007, 08:12 door pikah
Dit is een hele goede vraag, waarvan het antwoord niet al te eenvoudig
is. Je kan namelijk op meerdere manieren het risico verminderen.

1. Sessie time-out, probeer deze zo laag mogelijk te houden, maar
zorg wel dat het acceptabel blijft voor de gebruikers, elke minuut je
password opnieuw intypen is dus niet acceptabel :)

2. Encryption, je zou je SID kunnen encrypten voordat hij in de cookie
terecht komt. (Is wel een stuk moeilijker om het goed te implementeren)

3. Er zijn twee verschillende soorten cookies, persistent cookies en per-
session cookies, de per-session cookies bestaan alleen tijdens de
sessie zelf en zullen dus niet op de harde schijf worden opgeslagen,
maar in het geheugen (Dit kan ook uitgelezen worden, maar is een
heel stuk ingewikelder).

4. Client-side authenticatie via certificaten en SSL, hierdoor moet de hacker niet alleen de cookie hebben maar ook de private key van de client en de sleutel van de SSL sessie.

Een combinatie van deze oplossingen is dus een reele beveiliging. Let
wel op dat je nooit 100% zeker bent dat je cookie niet gevonden wordt,
gedecrypt wordt en dit ook nog eens binnen de sessie tijd, maar je
verminderd het risico aanzienlijk.

EDIT: Iets wat nog in me op kwam, op het moment dat de gebruiker de browser sluit zorgen dat automatisch de sessie word be-eindigd en de cookie verwijderen. (Dit is niet altijd te realiseren, maar in sommige gevallen wel)

EDIT2: Google geeft ook een aantal websites met verschillende oplossingen http://www.google.nl/search?hl=nl&q=prevent+cookie+theft&btnG=Google+zoeken&meta=
05-10-2007, 09:21 door Eghie
Door pikah
Dit is een hele goede vraag, waarvan het antwoord niet al te
eenvoudig
is. Je kan namelijk op meerdere manieren het risico verminderen.

1. Sessie time-out, probeer deze zo laag mogelijk te houden,
maar
zorg wel dat het acceptabel blijft voor de gebruikers, elke
minuut je
password opnieuw intypen is dus niet acceptabel
:)
Bedoel je hiermee de sessie expire time, of iets
van een idle timeout? Lijkt me dan gewenster een idle
timeout. Maar zeker een goed idee om te implementeren.
Bedankt. :)


2. Encryption, je zou je SID kunnen encrypten voordat hij in
de cookie
terecht komt. (Is wel een stuk moeilijker om het goed te
implementeren)
Hoe had je in gedachte om dit zo te encrypten dat de cookie
niet gejat kan worden. De encryptie key moet dan per
browser/client anders zijn, wil dit werken tegen cookie
hijacken. Als de key overal hetzelfde blijft om te
encrypten, heb je eigenlijk gewoon een andere representatie
van het sessie id te pakken. Hier schiet je dan niet zoveel
mee op, want als de hijacker gewoon de cookie precies
hetzelfde houd, dus niks met die encryptie doet, dan herkend
de server de cookie nog steeds als geldig.

3. Er zijn twee verschillende soorten cookies,
persistent cookies en per-
session cookies, de per-session cookies bestaan alleen
tijdens de
sessie zelf en zullen dus niet op de harde schijf worden
opgeslagen,
maar in het geheugen (Dit kan ook uitgelezen worden, maar is
een
heel stuk ingewikkelder).
Bij beveiliging is het eigenlijk ook de bedoeling om de boel
zoveel mogelijk te beveiligen, terwijl het toch acceptabel
blijft voor de gebruiker. Aangezien het een ticket
gebasseerde SSO implementatie wordt, moet minimaal het login
ticket, of in Kerberos bekende Ticket Granting Ticket (of
TGT), als persistant cookie worden opgeslagen, aangezien die
gewoon moet onthouden blijven worden. De verschillende
service tickets kunnen wel als per-session cookie worden
opgeslagen, aangezien dat toch gewoon software sessies zijn.

4. Client-side authenticatie via certificaten en SSL,
hierdoor moet de hacker niet alleen de cookie hebben maar
ook de private key van de client en de sleutel van de SSL
sessie.
Hier zat ik ook al te denken. Het probleem is hier echter
wel, dat we geen controle hebben over alle systemen waarop
de gebruiker inlogd binnen het systeem. Daarom zal dit een
optionele systeem moeten worden.

Een combinatie van deze oplossingen is dus een reele
beveiliging. Let
wel op dat je nooit 100% zeker bent dat je cookie niet
gevonden wordt,
gedecrypt wordt en dit ook nog eens binnen de sessie tijd,
maar je
verminderd het risico aanzienlijk.

EDIT: Iets wat nog in me op kwam, op het moment dat de
gebruiker de browser sluit zorgen dat automatisch de sessie
word be-eindigd en de cookie verwijderen. (Dit is niet
altijd te realiseren, maar in sommige gevallen wel)
Hiervoor zou ik eerder die idle timeout gebruiken lijkt me.
Dit vergt wel heel veel werk, wat ook vrij fout gevoelig is.
Daarom wil ik dit liever niet implementeren.

EDIT2: Google geeft ook een aantal websites met
verschillende oplossingen
http://www.google.nl/search?hl=nl&q=prevent+cookie+theft&btnG=Google+zoeken&meta=
Hier ga ik nog even naar kijken.

Uiteraard is een zowat verplichte beveiliging, anti- Session
Fixation
(http://en.wikipedia.org/wiki/Session_fixation).
Dit had ik geloof ik nog niet genoemd. Hier heb ik al wel
aan gedacht.

XSS (Cross Site Scripting) moet natuurlijk ook gewoon
beveiligd worden, maar dit valt onder input validation. Die
wil ik zowieso erg streng maken.
05-10-2007, 09:36 door pikah

Bedoel je hiermee de sessie expire time, of iets
van een idle timeout
Ik bedoelde hier inderdaad de idle timeout. Op het moment
dat een gebruiker 'niets' doet, hoe lang duurt het dan
voordat de sessie wordt beeindigd.


Hier schiet je dan niet zoveel
mee op, want als de hijacker gewoon de cookie precies
hetzelfde houd, dus niks met die encryptie doet, dan herkend
de server de cookie nog steeds als geldig.
Dit is inderdaad hetzelfde waar ik ook aan zat te denken,
vandaar dat de oplossing moeilijker wordt om te implementeren.

Op de andere 'mogelijke' oplossingen geeft je zelf al een
reactie met onderbouwing waarom je het wel of niet wil
implementeren.

Ik denk dat SSL toch een goede oplossing is waardoor het
toch een stuk moeilijker wordt om een aanval uit te voeren.
Je moet nu alleen gaan bijhouden welke certificaten bij wie
horen en aangeven welke personen (en dus certificaten) wel
en geen verbinding mogen maken.

Zoals je zelf aangeeft heb je de mogelijkheid al verkleind
naar een specifiek subnet achter een NAT firewall. Het
risico dat een aanval uitgevoerd wordt is al erg klein gemaakt.

Met SSL zal dit kleine risico nog kleiner gemaakt worden, de
vraag is alleen, hoe ver wil je gaan?

Zijn er andere mensen die misschien nog meer ideeen over dit
probleem hebben?

Mvg,
Ronald van der Westen
08-10-2007, 10:40 door Eghie
Door pikah
Ik denk dat SSL toch een goede oplossing is waardoor het
toch een stuk moeilijker wordt om een aanval uit te voeren.
Je moet nu alleen gaan bijhouden welke certificaten bij wie
horen en aangeven welke personen (en dus certificaten) wel
en geen verbinding mogen maken.

Zoals je zelf aangeeft heb je de mogelijkheid al verkleind
naar een specifiek subnet achter een NAT firewall. Het
risico dat een aanval uitgevoerd wordt is al erg klein gemaakt.

Met SSL zal dit kleine risico nog kleiner gemaakt worden, de
vraag is alleen, hoe ver wil je gaan?
Het risico wordt inderdaad een stuk kleiner met SSL client
certificaten. Wat ik wel zou kunnen doen is, het systeem
optioneel maken. Dus als een gebruiker een SSL certificaat
gebruikt, dan moet hij voor de hele sessie dezelfde SSL
certificaat gebruiken. Uiteraard wordt de SSL certificaat
wel aan de server kant opgeslagen, zodat het geen
willekeurige certificaat kan zijn. Als de gebruiker echter
geen SSL certificaat gebruikt bij het inloggen, dan is het
voor de rest ook niet nodig.

Wat ik bij het aanmaken van het gebruikers profiel wel wil
gaan doen is een SSL client certificaat en een PGP
handtekening genereren voor die gebruiker en die in de
database opslaan. De gebruiker kan dan kiezen of hij/zij het
wil gebruiken.
Reageren

Deze posting is gelocked. Reageren is niet meer mogelijk.